diff --git a/src/assembly/config.xml b/src/assembly/config.xml
new file mode 100644
index 0000000..b0592ae
--- /dev/null
+++ b/src/assembly/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly>
+  <id>config</id>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <formats>
+    <format>jar</format>
+  </formats>
+  <fileSets>
+
+    <fileSet>
+      <directory>src/main/config</directory>
+      <outputDirectory></outputDirectory>
+      <includes>
+        <include>**</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+
+</assembly>
+
diff --git a/src/assembly/site-component.xml b/src/assembly/site-component.xml
new file mode 100644
index 0000000..7c48a5b
--- /dev/null
+++ b/src/assembly/site-component.xml
@@ -0,0 +1,15 @@
+<assembly>
+  <id>site-component</id>
+  <formats>
+    <format>jar</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>${basedir}</directory>
+      <outputDirectory>jetty-xml</outputDirectory>
+      <includes>
+        <include>src/main/resources/org/eclipse/**</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+</assembly>
diff --git a/src/config/etc/README.spnego b/src/config/etc/README.spnego
new file mode 100644
index 0000000..0b4cc5b
--- /dev/null
+++ b/src/config/etc/README.spnego
@@ -0,0 +1,62 @@
+This setup will enable you to authenticate a user via spnego into your 
+webapp.
+
+To run with spengo enabled the following command line options are required:
+
+-Djava.security.krb5.conf=/path/to/jetty/etc/krb5.ini
+-Djava.security.auth.login.config=/path/to/jetty/etc/spnego.conf 
+-Djavax.security.auth.useSubjectCredsOnly=false
+
+The easiest place to put these lines are in the start.ini file.
+
+For debugging the spengo authentication the following options are helpful:
+
+-Dorg.eclipse.jetty.LEVEL=debug
+-Dsun.security.spnego.debug=true
+
+
+Spengo Authentication is enabled in the webapp with the following setup.
+
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Secure Area</web-resource-name>
+      <url-pattern>/secure/me/*</url-pattern>
+    </web-resource-collection>
+    <auth-constraint>
+      <role-name>MORTBAY.ORG</role-name>  <-- this is the domain that the user is a member of
+    </auth-constraint>
+  </security-constraint>
+
+  <login-config>
+    <auth-method>SPNEGO</auth-method>
+    <realm-name>Test Realm</realm-name>
+    (optionally to add custom error page)
+    <spnego-login-config>
+      <spengo-error-page>/loginError.html?param=foo</spnego-error-page>
+    </spnego-login-config>
+  </login-config>
+   
+A corresponding UserRealm needs to be created either programmatically if 
+embedded, via the jetty.xml or in a context file for the webapp.
+
+(in the jetty.xml)
+
+   <Call name="addBean">
+      <Arg>
+        <New class="org.eclipse.jetty.security.SpnegoLoginService">
+          <Set name="name">Test Realm</Set>
+          <Set name="config"><Property name="jetty.home" default="."/>/etc/spnego.properties</Set>
+        </New>
+      </Arg>
+    </Call>
+
+(context file)
+  <Get name="securityHandler">
+    <Set name="loginService">
+      <New class="org.eclipse.jetty.security.SpnegoLoginService">
+	    <Set name="name">Test Realm</Set>
+	    <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/spnego.properties</Set>
+      </New>
+    </Set>
+    <Set name="checkWelcomeFiles">true</Set>
+  </Get>
\ No newline at end of file
diff --git a/src/config/etc/jdbcRealm.properties b/src/config/etc/jdbcRealm.properties
new file mode 100644
index 0000000..48104d8
--- /dev/null
+++ b/src/config/etc/jdbcRealm.properties
@@ -0,0 +1,72 @@
+# 
+# This is a sample properties file for the org.eclipse.jetty.security.JDBCLoginService
+# implemtation of the UserRealm interface.  This allows Jetty users authentication 
+# to work from a database.
+#
+#   +-------+      +------------+      +-------+
+#   | users |      | user_roles |      | roles |
+#   +-------+      +------------+      +-------+
+#   | id    |     /| user_id    |\     | id    |
+#   | user  -------| role_id    |------- role  |
+#   | pwd   |     \|            |/     |       |
+#   +-------+      +------------+      +-------+
+#   
+# 
+# 'cachetime' is a time in seconds to cache positive database
+# lookups in internal hash table. Set to 0 to disable caching.
+# 
+#
+# For MySQL:
+# create a MYSQL user called "jetty" with password "jetty"
+#
+# Create the tables:
+# create table users 
+# (
+#     id integer primary key,
+#     username varchar(100) not null unique key,
+#     pwd varchar(20) not null
+# );
+# 
+# create table roles
+# (
+#     id integer primary key,
+#     role varchar(100) not null unique key
+# );    
+#
+# create table user_roles
+# (
+#     user_id integer not null,
+#     role_id integer not null,
+#     unique key (user_id, role_id),
+#     index(user_id)
+# );
+#
+# I'm not sure unique key with a first component of user_id will be
+# user by MySQL in query, so additional index wouldn't hurt.
+#
+# To test JDBC implementation:
+#
+# mysql> insert into users values (1, 'admin', 'password');
+# mysql> insert into roles values (1, 'server-administrator');
+# mysql> insert into roles values (2, 'content-administrator');
+# mysql> insert into user_roles values (1, 1);
+# mysql> insert into user_roles values (1, 2);
+#
+# Replace HashUserRealm in etc/admin.xml with JDBCUserRealm and
+# set path to properties file.
+#
+jdbcdriver = org.gjt.mm.mysql.Driver
+url = jdbc:mysql://localhost/jetty
+username = jetty
+password = jetty
+usertable = users
+usertablekey = id
+usertableuserfield = username
+usertablepasswordfield = pwd
+roletable = roles
+roletablekey = id
+roletablerolefield = role
+userroletable = user_roles
+userroletableuserkey = user_id
+userroletablerolekey = role_id
+cachetime = 300
diff --git a/src/config/etc/jetty-bio-ssl.xml b/src/config/etc/jetty-bio-ssl.xml
new file mode 100644
index 0000000..3386b7b
--- /dev/null
+++ b/src/config/etc/jetty-bio-ssl.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure SSL for the Jetty Server                              -->
+<!-- this configuration file should be used in combination with      -->
+<!-- other configuration files.  e.g.                                -->
+<!--    java -jar start.jar etc/jetty-ssl.xml                        -->
+<!-- =============================================================== -->
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+  <Call name="addConnector">
+    <Arg>
+      <New class="org.eclipse.jetty.server.ssl.SslSocketConnector">
+	<Set name="Port">9443</Set>
+	<Set name="maxIdleTime">30000</Set>
+	<Set name="Keystore"><Property name="jetty.home" default="." />/etc/keystore</Set>
+	<Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
+	<Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
+        <Set name="truststore"><Property name="jetty.home" default="." />/etc/keystore</Set>
+        <Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
+      </New>
+    </Arg>
+  </Call>
+</Configure>
diff --git a/src/config/etc/jetty-bio.xml b/src/config/etc/jetty-bio.xml
new file mode 100644
index 0000000..66950ee
--- /dev/null
+++ b/src/config/etc/jetty-bio.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Mixin configuration for Block socket connector                  -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <!-- Use this connector if NIO is not available.  -->
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.eclipse.jetty.server.bio.SocketConnector">
+            <Set name="port"><Property name="jetty.bio.port" default="8081"/></Set>
+            <Set name="maxIdleTime">50000</Set>
+            <Set name="lowResourceMaxIdleTime">1500</Set>
+          </New>
+      </Arg>
+    </Call>
+
+</Configure>
diff --git a/src/config/etc/jetty-debug.xml b/src/config/etc/jetty-debug.xml
new file mode 100644
index 0000000..6d66953
--- /dev/null
+++ b/src/config/etc/jetty-debug.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Mixin the DebugHandler                                          -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+    <Get id="oldhandler" name="handler"/>
+    <Set name="handler">
+      <New id="DebugHandler" class="org.eclipse.jetty.server.handler.DebugHandler">
+        <Set name="handler"><Ref id="oldhandler"/></Set>
+	<Set name="outputStream">
+	  <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
+	    <Arg type="String"><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.debug.log</Arg>
+	    <Arg type="boolean">true</Arg> <!-- append -->
+	    <Arg type="int">90</Arg> <!-- retain days -->
+	  </New>
+	</Set>
+      </New>
+    </Set>
+</Configure>
diff --git a/src/config/etc/jetty-fileserver.xml b/src/config/etc/jetty-fileserver.xml
new file mode 100644
index 0000000..de15b38
--- /dev/null
+++ b/src/config/etc/jetty-fileserver.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+
+<Configure id="FileServer" class="org.eclipse.jetty.server.Server">
+
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+            <Set name="port">8080</Set>
+          </New>
+      </Arg>
+    </Call>
+
+    <Set name="handler">
+      <New class="org.eclipse.jetty.server.handler.HandlerList">
+        <Set name="handlers">
+	  <Array type="org.eclipse.jetty.server.Handler">
+	    <Item>
+	      <New class="org.eclipse.jetty.server.handler.ResourceHandler">
+	        <Set name="directoriesListed">true</Set>
+		<Set name="welcomeFiles">
+		  <Array type="String"><Item>index.html</Item></Array>
+		</Set>
+	        <Set name="resourceBase">.</Set>
+	      </New>
+	    </Item>
+	    <Item>
+	      <New class="org.eclipse.jetty.server.handler.DefaultHandler">
+	      </New>
+	    </Item>
+	  </Array>
+        </Set>
+      </New>
+    </Set>
+    
+</Configure>
diff --git a/src/config/etc/jetty-ipaccess.xml b/src/config/etc/jetty-ipaccess.xml
new file mode 100644
index 0000000..d5fb5f8
--- /dev/null
+++ b/src/config/etc/jetty-ipaccess.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Mixin the Statistics Handler                                    -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <Get id="oldhandler" name="handler"/>
+
+    <Set name="handler">
+     <New id="IPAccessHandler" class="org.eclipse.jetty.server.handler.IPAccessHandler">
+      <Set name="handler"><Ref id="oldhandler"/></Set>
+      <Set name="white">
+        <Array type="String">
+	  <Item>127.0.0.1</Item>
+	  <Item>127.0.0.2/*.html</Item>
+	</Array>
+      </Set>
+      <Set name="black">
+        <Array type="String">
+	  <Item>127.0.0.1/blacklisted</Item>
+	  <Item>127.0.0.2/black.html</Item>
+	</Array>
+      </Set>
+     </New>
+    </Set>
+    
+</Configure>
diff --git a/src/config/etc/jetty-jmx.xml b/src/config/etc/jetty-jmx.xml
new file mode 100644
index 0000000..4db0dbb
--- /dev/null
+++ b/src/config/etc/jetty-jmx.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- ============================================================================ -->
+<!-- To correctly start Jetty with JMX module enabled, this configuration         -->
+<!-- file must appear first in the list of the configuration files.               -->
+<!-- The simplest way to achieve this is to add etc/jetty-jmx.xml as the          -->
+<!-- first file in configuration file list at the end of start.ini file.          -->
+<!-- ============================================================================ -->
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+  <!-- =========================================================== -->
+  <!-- Set the java.rmi.server.hostname property in case you've    -->
+  <!-- got a misconfigured /etc/hosts entry or the like.           -->
+  <!-- =========================================================== -->
+  <!-- 
+  <Call class="java.lang.System" name="setProperty">
+    <Arg>java.rmi.server.hostname</Arg>
+    <Arg>127.0.0.1</Arg>
+  </Call>
+  -->
+  
+  <!-- =========================================================== -->
+  <!-- Initialize an mbean server                                  -->
+  <!-- =========================================================== -->
+  <Call id="MBeanServer" class="java.lang.management.ManagementFactory"
+    name="getPlatformMBeanServer" />
+
+  <!-- =========================================================== -->
+  <!-- Initialize the Jetty MBean container                        -->
+  <!-- =========================================================== -->
+  <New id="MBeanContainer" class="org.eclipse.jetty.jmx.MBeanContainer">
+    <Arg><Ref id="MBeanServer" /></Arg>
+    <Call name="start"/>
+  </New>
+
+  <!-- Add to the Server to listen for object events -->
+  <Get id="Container" name="container">
+    <Call name="addEventListener">
+      <Arg><Ref id="MBeanContainer" /></Arg>
+    </Call>
+  </Get>
+
+  <!-- Add to the Server as a managed lifecycle -->
+  <Call name="addBean">
+    <Arg><Ref id="MBeanContainer"/></Arg>
+    <Arg type="boolean">true</Arg>
+  </Call>
+
+  <!-- Add the static log -->
+  <Ref id="MBeanContainer">
+    <Call name="addBean">
+      <Arg>
+        <New class="org.eclipse.jetty.util.log.Log"/>
+      </Arg>
+    </Call>
+  </Ref>
+  
+  <!-- In order to connect to the JMX server remotely from a different
+       process, possibly running on a different host, Jetty JMX module
+       can create a remote JMX connector. It requires RMI registry to
+       be started prior to creating the connector server because the
+       JMX specification uses RMI to facilitate connections.        
+   -->
+
+  <!-- Optionally start the RMI registry. Normally RMI registry runs on
+       port 1099. The argument below can be changed in order to comply
+       with the firewall requirements.
+  -->
+  <!--
+  <Call name="createRegistry" class="java.rmi.registry.LocateRegistry">
+    <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
+    <Call name="sleep" class="java.lang.Thread">
+       <Arg type="java.lang.Integer">1000</Arg>
+    </Call>
+  </Call>
+  -->
+ 
+  <!-- Optionally add a remote JMX connector. The parameters of the constructor
+       below specify the JMX service URL, and the object name string for the
+       connector server bean. The parameters of the JMXServiceURL constructor 
+       specify the protocol that clients will use to connect to the remote JMX
+       connector (RMI), the hostname of the server (local hostname), port number
+       (automatically assigned), and the URL path. Note that URL path contains
+       the RMI registry hostname and port number, that may need to be modified
+       in order to comply with the firewall requirements. 
+  -->
+  <!--
+  <New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer">
+    <Arg>
+      <New class="javax.management.remote.JMXServiceURL">
+        <Arg type="java.lang.String">rmi</Arg>
+        <Arg type="java.lang.String" />
+        <Arg type="java.lang.Integer"><SystemProperty name="jetty.jmxrmiport" default="1099"/></Arg>
+        <Arg type="java.lang.String">/jndi/rmi://<SystemProperty name="jetty.jmxrmihost" default="localhost"/>:<SystemProperty name="jetty.jmxrmiport" default="1099"/>/jmxrmi</Arg>
+      </New>
+    </Arg>
+    <Arg>org.eclipse.jetty.jmx:name=rmiconnectorserver</Arg>
+    <Call name="start" />
+  </New>
+  -->
+</Configure>
+
diff --git a/src/config/etc/jetty-logging.xml b/src/config/etc/jetty-logging.xml
new file mode 100644
index 0000000..2060a22
--- /dev/null
+++ b/src/config/etc/jetty-logging.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+
+<!-- =============================================================== -->
+<!-- Configure stderr and stdout to a Jetty rollover log file        -->
+<!-- this configuration file should be used in combination with      -->
+<!-- other configuration files.  e.g.                                -->
+<!--    java -jar start.jar etc/jetty-logging.xml                    -->
+<!-- =============================================================== -->
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <New id="ServerLog" class="java.io.PrintStream">
+      <Arg>
+        <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
+          <Arg><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.stderrout.log</Arg>
+          <Arg type="boolean">false</Arg>
+          <Arg type="int">90</Arg>
+          <Arg><Call class="java.util.TimeZone" name="getTimeZone"><Arg>GMT</Arg></Call></Arg>
+          <Get id="ServerLogName" name="datedFilename"/>
+        </New>
+      </Arg>
+    </New>
+
+    <Call class="org.eclipse.jetty.util.log.Log" name="info"><Arg>Redirecting stderr/stdout to <Ref id="ServerLogName"/></Arg></Call>
+    <Call class="java.lang.System" name="setErr"><Arg><Ref id="ServerLog"/></Arg></Call>
+    <Call class="java.lang.System" name="setOut"><Arg><Ref id="ServerLog"/></Arg></Call>
+
+</Configure>
+
+
+
diff --git a/src/config/etc/jetty-proxy.xml b/src/config/etc/jetty-proxy.xml
new file mode 100644
index 0000000..5bc46c3
--- /dev/null
+++ b/src/config/etc/jetty-proxy.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!--                                                                 -->
+<!-- Documentation of this file format can be found at:              -->
+<!-- http://docs.codehaus.org/display/JETTY/jetty.xml                -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+
+
+<Configure id="Proxy" class="org.eclipse.jetty.server.Server">
+
+    <!-- =========================================================== -->
+    <!-- Server Thread Pool                                          -->
+    <!-- =========================================================== -->
+    <Set name="ThreadPool">
+      <!-- Default queued blocking threadpool 
+      -->
+      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+        <Set name="minThreads">10</Set>
+        <Set name="maxThreads">50</Set>
+      </New>
+    </Set>
+
+
+    <!-- =========================================================== -->
+    <!-- Set connectors                                              -->
+    <!-- =========================================================== -->
+
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+            <Set name="host"><Property name="jetty.host" /></Set>
+            <Set name="port"><Property name="jetty.port" default="8888"/></Set>
+            <Set name="maxIdleTime">300000</Set>
+            <Set name="Acceptors">2</Set>
+            <Set name="statsOn">false</Set>
+	    <Set name="lowResourcesConnections">20000</Set>
+	    <Set name="lowResourcesMaxIdleTime">5000</Set>
+          </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <Set name="handler">
+      <New id="Servlets" class="org.eclipse.jetty.servlet.ServletHandler">
+        <Call name="addServletWithMapping">
+	  <Arg>org.eclipse.jetty.servlets.ProxyServlet</Arg>
+	  <Arg>/</Arg>
+	</Call>
+      </New>
+    </Set>
+    
+    <!-- =========================================================== -->
+    <!-- extra options                                               -->
+    <!-- =========================================================== -->
+    <Set name="stopAtShutdown">true</Set>
+    <Set name="sendServerVersion">true</Set>
+    <Set name="sendDateHeader">true</Set>
+    <Set name="gracefulShutdown">1000</Set>
+
+</Configure>
diff --git a/src/config/etc/jetty-requestlog.xml b/src/config/etc/jetty-requestlog.xml
new file mode 100644
index 0000000..45d3aab
--- /dev/null
+++ b/src/config/etc/jetty-requestlog.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Request Log                                 -->
+<!-- =============================================================== -->
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <!-- =========================================================== -->
+    <!-- Configure Request Log                                       -->
+    <!-- =========================================================== -->
+    <Ref id="Handlers">
+      <Call name="addHandler">
+        <Arg>
+          <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
+	    <Set name="requestLog">
+	      <!-- Use AsyncNCSARequestLog for improved request latency -->
+	      <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
+		<Set name="filename"><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
+		<Set name="filenameDateFormat">yyyy_MM_dd</Set>
+		<Set name="retainDays">90</Set>
+		<Set name="append">true</Set>
+		<Set name="extended">false</Set>
+		<Set name="logCookies">false</Set>
+		<Set name="LogTimeZone">GMT</Set>
+	      </New>
+	    </Set>
+	  </New>
+        </Arg>
+      </Call>
+    </Ref>
+
+</Configure>
diff --git a/src/config/etc/jetty-ssl.xml b/src/config/etc/jetty-ssl.xml
new file mode 100644
index 0000000..4c0c9ff
--- /dev/null
+++ b/src/config/etc/jetty-ssl.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure SSL for the Jetty Server                              -->
+<!-- this configuration file should be used in combination with      -->
+<!-- other configuration files.  e.g.                                -->
+<!--    java -jar start.jar etc/jetty-ssl.xml                        -->
+<!--                                                                 -->
+<!--  alternately, add to the start.ini for easier usage             -->
+<!-- =============================================================== -->
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+  <!-- if NIO is not available, use org.eclipse.jetty.server.ssl.SslSocketConnector -->
+  
+  <New id="sslContextFactory" class="org.eclipse.jetty.http.ssl.SslContextFactory">
+    <Set name="KeyStore"><Property name="jetty.home" default="." />/etc/keystore</Set>
+    <Set name="KeyStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
+    <Set name="KeyManagerPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
+    <Set name="TrustStore"><Property name="jetty.home" default="." />/etc/keystore</Set>
+    <Set name="TrustStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
+  </New>
+
+  <Call name="addConnector">
+    <Arg>
+      <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
+        <Arg><Ref id="sslContextFactory" /></Arg>
+        <Set name="Port">8443</Set>
+        <Set name="maxIdleTime">30000</Set>
+        <Set name="Acceptors">2</Set>
+        <Set name="AcceptQueueSize">100</Set>
+      </New>
+    </Arg>
+  </Call>
+</Configure>
diff --git a/src/config/etc/jetty-stats.xml b/src/config/etc/jetty-stats.xml
new file mode 100644
index 0000000..e0a0c7f
--- /dev/null
+++ b/src/config/etc/jetty-stats.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Mixin the Statistics Handler                                    -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <Get id="oldhandler" name="handler"/>
+
+    <Set name="handler">
+     <New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler">
+      <Set name="handler"><Ref id="oldhandler"/></Set>
+     </New>
+    </Set>
+    
+</Configure>
diff --git a/src/config/etc/jetty-xinetd.xml b/src/config/etc/jetty-xinetd.xml
new file mode 100644
index 0000000..c2fbaa2
--- /dev/null
+++ b/src/config/etc/jetty-xinetd.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configuration for starting up Jetty using inetd/xinetd          -->
+<!-- This feature requires at least Java 5                           -->
+<!--                                                                 -->
+<!-- Making it a mixin for convenience, but note that if used        -->
+<!-- with jetty.xml, Jetty will use multiple connectors              -->
+<!-- =============================================================== -->
+
+<!-- Sample xinetd configuration (restart xinetd after adding the configuration file)
+
+service jetty
+{
+    disable     = no
+
+    id          = jetty
+    type        = UNLISTED     
+    wait        = yes          
+    socket_type = stream
+
+    # change this
+    user        = username
+    group       = groupname
+    port        = 2001
+
+    # sample script for running jetty as a service
+    # replace $JETTY_HOME with /path/to/jetty_home/
+    server      = $JETTY_HOME/bin/jetty-xinetd.sh
+}
+
+-->
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+    <Call name="addConnector">
+      <Arg>
+          <!-- Inherited channel (from inetd/xinetd) -->
+          <New class="org.eclipse.jetty.server.nio.InheritedChannelConnector">
+
+
+            <!-- Optional. Fallback in case System.inheritedChannel() does not give a ServerSocketChannel 
+            <Set name="port"><Property name="jetty.service.port" default="8082"/></Set>
+            -->
+
+            <!-- sane defaults -->
+            <Set name="maxIdleTime">300000</Set>
+            <Set name="Acceptors">2</Set>
+            <Set name="statsOn">false</Set>
+      	    <Set name="lowResourcesConnections">20000</Set>
+	        <Set name="lowResourcesMaxIdleTime">5000</Set>
+          </New>
+      </Arg>
+    </Call>
+</Configure>
+
diff --git a/src/config/etc/jetty.xml b/src/config/etc/jetty.xml
new file mode 100644
index 0000000..153514d
--- /dev/null
+++ b/src/config/etc/jetty.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!--                                                                 -->
+<!-- Documentation of this file format can be found at:              -->
+<!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax        -->
+<!--                                                                 -->
+<!-- Additional configuration files are available in $JETTY_HOME/etc -->
+<!-- and can be mixed in.  For example:                              -->
+<!--   java -jar start.jar etc/jetty-ssl.xml                         -->
+<!--                                                                 -->
+<!-- See start.ini file for the default configuraton files           -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+    <!-- =========================================================== -->
+    <!-- Server Thread Pool                                          -->
+    <!-- =========================================================== -->
+    <Set name="ThreadPool">
+      <!-- Default queued blocking threadpool -->
+      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+        <Set name="minThreads">10</Set>
+        <Set name="maxThreads">200</Set>
+        <Set name="detailedDump">false</Set>
+      </New>
+    </Set>
+
+    <!-- =========================================================== -->
+    <!-- Set connectors                                              -->
+    <!-- =========================================================== -->
+
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+            <Set name="host"><Property name="jetty.host" /></Set>
+            <Set name="port"><Property name="jetty.port" default="8080"/></Set>
+            <Set name="maxIdleTime">300000</Set>
+            <Set name="Acceptors">2</Set>
+            <Set name="statsOn">false</Set>
+            <Set name="confidentialPort">8443</Set>
+	    <Set name="lowResourcesConnections">20000</Set>
+	    <Set name="lowResourcesMaxIdleTime">5000</Set>
+          </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- Set handler Collection Structure                            --> 
+    <!-- =========================================================== -->
+    <Set name="handler">
+      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+        <Set name="handlers">
+         <Array type="org.eclipse.jetty.server.Handler">
+           <Item>
+             <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
+           </Item>
+           <Item>
+             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
+           </Item>
+         </Array>
+        </Set>
+      </New>
+    </Set>
+
+    <!-- =========================================================== -->
+    <!-- extra options                                               -->
+    <!-- =========================================================== -->
+    <Set name="stopAtShutdown">true</Set>
+    <Set name="sendServerVersion">true</Set>
+    <Set name="sendDateHeader">true</Set>
+    <Set name="gracefulShutdown">1000</Set>
+    <Set name="dumpAfterStart">false</Set>
+    <Set name="dumpBeforeStop">false</Set>
+
+</Configure>
diff --git a/src/config/etc/keystore b/src/config/etc/keystore
new file mode 100644
index 0000000..08f6cda
--- /dev/null
+++ b/src/config/etc/keystore
Binary files differ
diff --git a/src/config/etc/krb5.ini b/src/config/etc/krb5.ini
new file mode 100644
index 0000000..9cea63c
--- /dev/null
+++ b/src/config/etc/krb5.ini
@@ -0,0 +1,23 @@
+[libdefaults]
+default_realm = MORTBAY.ORG
+default_keytab_name = FILE:/path/to/jetty/etc/krb5.keytab
+permitted_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 
+default_tgs_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 
+default_tkt_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 
+
+
+
+[realms]
+MORTBAY.ORG = {
+ 		kdc = 192.168.2.30
+ 		admin_server = 192.168.2.30
+ 		default_domain = MORTBAY.ORG
+}
+
+[domain_realm]
+mortbay.org= MORTBAY.ORG
+.mortbay.org = MORTBAY.ORG
+
+[appdefaults]
+autologin = true
+forwardable = true
diff --git a/src/config/etc/spnego.conf b/src/config/etc/spnego.conf
new file mode 100644
index 0000000..3d5caf8
--- /dev/null
+++ b/src/config/etc/spnego.conf
@@ -0,0 +1,19 @@
+com.sun.security.jgss.initiate {
+     com.sun.security.auth.module.Krb5LoginModule required
+     principal="HTTP/vm.mortbay.org@MORTBAY.ORG" 
+     keyTab="/path/to/jetty/etc/krb5.keytab" 
+     useKeyTab=true
+     storeKey=true 
+     debug=true 
+     isInitiator=false;
+};
+ 
+com.sun.security.jgss.accept {
+     com.sun.security.auth.module.Krb5LoginModule required
+     principal="HTTP/vm.mortbay.org@MORTBAY.ORG" 
+     useKeyTab=true
+     keyTab="/path/to/jetty/etc/krb5.keytab" 
+     storeKey=true 
+     debug=true 
+     isInitiator=false;
+};
diff --git a/src/config/etc/spnego.properties b/src/config/etc/spnego.properties
new file mode 100644
index 0000000..86862ea
--- /dev/null
+++ b/src/config/etc/spnego.properties
@@ -0,0 +1 @@
+targetName = HTTP/vm.mortbay.org
\ No newline at end of file
diff --git a/src/config/etc/webdefault.xml b/src/config/etc/webdefault.xml
new file mode 100644
index 0000000..213138b
--- /dev/null
+++ b/src/config/etc/webdefault.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+  <!-- ===================================================================== -->
+  <!-- This file contains the default descriptor for web applications.       -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <!-- The intent of this descriptor is to include jetty specific or common  -->
+  <!-- configuration for all webapps.   If a context has a webdefault.xml    -->
+  <!-- descriptor, it is applied before the contexts own web.xml file        -->
+  <!--                                                                       -->
+  <!-- A context may be assigned a default descriptor by:                    -->
+  <!--  + Calling WebApplicationContext.setDefaultsDescriptor                -->
+  <!--  + Passed an arg to addWebApplications                                -->
+  <!--                                                                       -->
+  <!-- This file is used both as the resource within the jetty.jar (which is -->
+  <!-- used as the default if no explicit defaults descriptor is set) and it -->
+  <!-- is copied to the etc directory of the Jetty distro and explicitly     -->
+  <!-- by the jetty.xml file.                                                -->
+  <!--                                                                       -->
+  <!-- ===================================================================== -->
+<web-app
+  xmlns="http://java.sun.com/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+  metadata-complete="true"
+  version="2.5"
+>
+
+  <description>
+    Default web.xml file.  
+    This file is applied to a Web application before it's own WEB_INF/web.xml file
+  </description>
+
+  <!-- ==================================================================== -->
+  <!-- Removes static references to beans from javax.el.BeanELResolver to   -->
+  <!-- ensure webapp classloader can be released on undeploy                -->
+  <!-- ==================================================================== -->
+  <listener>
+   <listener-class>org.eclipse.jetty.servlet.listener.ELContextCleaner</listener-class>
+  </listener>
+  
+  <!-- ==================================================================== -->
+  <!-- Removes static cache of Methods from java.beans.Introspector to      -->
+  <!-- ensure webapp classloader can be released on undeploy                -->
+  <!-- ==================================================================== -->  
+  <listener>
+   <listener-class>org.eclipse.jetty.servlet.listener.IntrospectorCleaner</listener-class>
+  </listener>
+  
+
+  <!-- ==================================================================== -->
+  <!-- Context params to control Session Cookies                            -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!--
+    UNCOMMENT TO ACTIVATE <context-param> <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name> <param-value>127.0.0.1</param-value> </context-param> <context-param>
+    <param-name>org.eclipse.jetty.servlet.SessionPath</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
+    <param-value>-1</param-value> </context-param>
+  -->
+
+  <!-- ==================================================================== -->
+  <!-- The default servlet.                                                 -->
+  <!-- This servlet, normally mapped to /, provides the handling for static -->
+  <!-- content, OPTIONS and TRACE methods for the context.                  -->
+  <!-- The following initParameters are supported:                          -->
+  <!--  
+ *  acceptRanges      If true, range requests and responses are
+ *                    supported
+ *
+ *  dirAllowed        If true, directory listings are returned if no
+ *                    welcome file is found. Else 403 Forbidden.
+ *
+ *  welcomeServlets   If true, attempt to dispatch to welcome files
+ *                    that are servlets, but only after no matching static
+ *                    resources could be found. If false, then a welcome
+ *                    file must exist on disk. If "exact", then exact
+ *                    servlet matches are supported without an existing file.
+ *                    Default is true.
+ *
+ *                    This must be false if you want directory listings,
+ *                    but have index.jsp in your welcome file list.
+ *
+ *  redirectWelcome   If true, welcome files are redirected rather than
+ *                    forwarded to.
+ *
+ *  gzip              If set to true, then static content will be served as
+ *                    gzip content encoded if a matching resource is
+ *                    found ending with ".gz"
+ *
+ *  resourceBase      Set to replace the context resource base
+ *
+ *  resourceCache     If set, this is a context attribute name, which the servlet 
+ *                    will use to look for a shared ResourceCache instance. 
+ *                        
+ *  relativeResourceBase
+ *                    Set with a pathname relative to the base of the
+ *                    servlet context root. Useful for only serving static content out
+ *                    of only specific subdirectories.
+ *
+ *  aliases           If True, aliases of resources are allowed (eg. symbolic
+ *                    links and caps variations). May bypass security constraints.
+ *
+ *  maxCacheSize      The maximum total size of the cache or 0 for no cache.
+ *  maxCachedFileSize The maximum size of a file to cache
+ *  maxCachedFiles    The maximum number of files to cache
+ *
+ *  useFileMappedBuffer
+ *                    If set to true, it will use mapped file buffer to serve static content
+ *                    when using NIO connector. Setting this value to false means that
+ *                    a direct buffer will be used instead of a mapped file buffer.
+ *                    By default, this is set to true.
+ *
+ *  cacheControl      If set, all static content will have this value set as the cache-control
+ *                    header.
+ -->
+ 
+ 
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <servlet>
+    <servlet-name>default</servlet-name>
+    <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+    <init-param>
+      <param-name>aliases</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>acceptRanges</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>dirAllowed</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>welcomeServlets</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>redirectWelcome</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>maxCacheSize</param-name>
+      <param-value>256000000</param-value>
+    </init-param>
+    <init-param>
+      <param-name>maxCachedFileSize</param-name>
+      <param-value>200000000</param-value>
+    </init-param>
+    <init-param>
+      <param-name>maxCachedFiles</param-name>
+      <param-value>2048</param-value>
+    </init-param>
+    <init-param>
+      <param-name>gzip</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>useFileMappedBuffer</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <!--
+    <init-param>
+      <param-name>resourceCache</param-name>
+      <param-value>resourceCache</param-value>
+    </init-param>
+    -->
+    <!--
+    <init-param>
+      <param-name>cacheControl</param-name>
+      <param-value>max-age=3600,public</param-value>
+    </init-param>
+    -->
+    <load-on-startup>0</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>default</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+
+
+  <!-- ==================================================================== -->
+  <!-- JSP Servlet                                                          -->
+  <!-- This is the jasper JSP servlet from the jakarta project              -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!-- The JSP page compiler and execution servlet, which is the mechanism  -->
+  <!-- used by Glassfish to support JSP pages.  Traditionally, this servlet -->
+  <!-- is mapped to URL patterh "*.jsp".  This servlet supports the         -->
+  <!-- following initialization parameters (default values are in square    -->
+  <!-- brackets):                                                           -->
+  <!--                                                                      -->
+  <!--   checkInterval       If development is false and reloading is true, -->
+  <!--                       background compiles are enabled. checkInterval -->
+  <!--                       is the time in seconds between checks to see   -->
+  <!--                       if a JSP page needs to be recompiled. [300]    -->
+  <!--                                                                      -->
+  <!--   compiler            Which compiler Ant should use to compile JSP   -->
+  <!--                       pages.  See the Ant documenation for more      -->
+  <!--                       information. [javac]                           -->
+  <!--                                                                      -->
+  <!--   classdebuginfo      Should the class file be compiled with         -->
+  <!--                       debugging information?  [true]                 -->
+  <!--                                                                      -->
+  <!--   classpath           What class path should I use while compiling   -->
+  <!--                       generated servlets?  [Created dynamically      -->
+  <!--                       based on the current web application]          -->
+  <!--                       Set to ? to make the container explicitly set  -->
+  <!--                       this parameter.                                -->
+  <!--                                                                      -->
+  <!--   development         Is Jasper used in development mode (will check -->
+  <!--                       for JSP modification on every access)?  [true] -->
+  <!--                                                                      -->
+  <!--   enablePooling       Determines whether tag handler pooling is      -->
+  <!--                       enabled  [true]                                -->
+  <!--                                                                      -->
+  <!--   fork                Tell Ant to fork compiles of JSP pages so that -->
+  <!--                       a separate JVM is used for JSP page compiles   -->
+  <!--                       from the one Tomcat is running in. [true]      -->
+  <!--                                                                      -->
+  <!--   ieClassId           The class-id value to be sent to Internet      -->
+  <!--                       Explorer when using <jsp:plugin> tags.         -->
+  <!--                       [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93]   -->
+  <!--                                                                      -->
+  <!--   javaEncoding        Java file encoding to use for generating java  -->
+  <!--                       source files. [UTF-8]                          -->
+  <!--                                                                      -->
+  <!--   keepgenerated       Should we keep the generated Java source code  -->
+  <!--                       for each page instead of deleting it? [true]   -->
+  <!--                                                                      -->
+  <!--   logVerbosityLevel   The level of detailed messages to be produced  -->
+  <!--                       by this servlet.  Increasing levels cause the  -->
+  <!--                       generation of more messages.  Valid values are -->
+  <!--                       FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
+  <!--                       [WARNING]                                      -->
+  <!--                                                                      -->
+  <!--   mappedfile          Should we generate static content with one     -->
+  <!--                       print statement per input line, to ease        -->
+  <!--                       debugging?  [false]                            -->
+  <!--                                                                      -->
+  <!--                                                                      -->
+  <!--   reloading           Should Jasper check for modified JSPs?  [true] -->
+  <!--                                                                      -->
+  <!--   suppressSmap        Should the generation of SMAP info for JSR45   -->
+  <!--                       debugging be suppressed?  [false]              -->
+  <!--                                                                      -->
+  <!--   dumpSmap            Should the SMAP info for JSR45 debugging be    -->
+  <!--                       dumped to a file? [false]                      -->
+  <!--                       False if suppressSmap is true                  -->
+  <!--                                                                      -->
+  <!--   scratchdir          What scratch directory should we use when      -->
+  <!--                       compiling JSP pages?  [default work directory  -->
+  <!--                       for the current web application]               -->
+  <!--                                                                      -->
+  <!--   tagpoolMaxSize      The maximum tag handler pool size  [5]         -->
+  <!--                                                                      -->
+  <!--   xpoweredBy          Determines whether X-Powered-By response       -->
+  <!--                       header is added by generated servlet  [false]  -->
+  <!--                                                                      -->
+  <!-- If you wish to use Jikes to compile JSP pages:                       -->
+  <!--   Set the init parameter "compiler" to "jikes".  Define              -->
+  <!--   the property "-Dbuild.compiler.emacs=true" when starting Jetty     -->
+  <!--   to cause Jikes to emit error messages in a format compatible with  -->
+  <!--   Jasper.                                                            -->
+  <!--   If you get an error reporting that jikes can't use UTF-8 encoding, -->
+  <!--   try setting the init parameter "javaEncoding" to "ISO-8859-1".     -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <servlet
+    id="jsp"
+  >
+    <servlet-name>jsp</servlet-name>
+    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+    <init-param>
+      <param-name>logVerbosityLevel</param-name>
+      <param-value>DEBUG</param-value>
+    </init-param>
+    <init-param>
+      <param-name>fork</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>xpoweredBy</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <!--  
+    <init-param>
+        <param-name>classpath</param-name>
+        <param-value>?</param-value>
+    </init-param>
+    -->
+    <load-on-startup>0</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>jsp</servlet-name>
+    <url-pattern>*.jsp</url-pattern>
+    <url-pattern>*.jspf</url-pattern>
+    <url-pattern>*.jspx</url-pattern>
+    <url-pattern>*.xsp</url-pattern>
+    <url-pattern>*.JSP</url-pattern>
+    <url-pattern>*.JSPF</url-pattern>
+    <url-pattern>*.JSPX</url-pattern>
+    <url-pattern>*.XSP</url-pattern>
+  </servlet-mapping>
+
+  <!-- ==================================================================== -->
+  <!-- Dynamic Servlet Invoker.                                             -->
+  <!-- This servlet invokes anonymous servlets that have not been defined   -->
+  <!-- in the web.xml or by other means. The first element of the pathInfo  -->
+  <!-- of a request passed to the envoker is treated as a servlet name for  -->
+  <!-- an existing servlet, or as a class name of a new servlet.            -->
+  <!-- This servlet is normally mapped to /servlet/*                        -->
+  <!-- This servlet support the following initParams:                       -->
+  <!--                                                                      -->
+  <!--  nonContextServlets       If false, the invoker can only load        -->
+  <!--                           servlets from the contexts classloader.    -->
+  <!--                           This is false by default and setting this  -->
+  <!--                           to true may have security implications.    -->
+  <!--                                                                      -->
+  <!--  verbose                  If true, log dynamic loads                 -->
+  <!--                                                                      -->
+  <!--  *                        All other parameters are copied to the     -->
+  <!--                           each dynamic servlet as init parameters    -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!--
+    Uncomment for dynamic invocation <servlet> <servlet-name>invoker</servlet-name> <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class> <init-param> <param-name>verbose</param-name>
+    <param-value>false</param-value> </init-param> <init-param> <param-name>nonContextServlets</param-name> <param-value>false</param-value> </init-param> <init-param>
+    <param-name>dynamicParam</param-name> <param-value>anyValue</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>invoker</servlet-name>
+    <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
+  -->
+
+
+
+  <!-- ==================================================================== -->
+  <session-config>
+    <session-timeout>30</session-timeout>
+  </session-config>
+
+  <!-- ==================================================================== -->
+  <!-- Default MIME mappings                                                -->
+  <!-- The default MIME mappings are provided by the mime.properties        -->
+  <!-- resource in the org.eclipse.jetty.server.jar file.  Additional or modified  -->
+  <!-- mappings may be specified here                                       -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!-- UNCOMMENT TO ACTIVATE
+  <mime-mapping>
+    <extension>mysuffix</extension>
+    <mime-type>mymime/type</mime-type>
+  </mime-mapping>
+  -->
+
+  <!-- ==================================================================== -->
+  <welcome-file-list>
+    <welcome-file>index.html</welcome-file>
+    <welcome-file>index.htm</welcome-file>
+    <welcome-file>index.jsp</welcome-file>
+  </welcome-file-list>
+
+  <!-- ==================================================================== -->
+  <locale-encoding-mapping-list>
+    <locale-encoding-mapping>
+      <locale>ar</locale>
+      <encoding>ISO-8859-6</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>be</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>bg</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>ca</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>cs</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>da</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>de</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>el</locale>
+      <encoding>ISO-8859-7</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>en</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>es</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>et</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>fi</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>fr</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>hr</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>hu</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>is</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>it</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>iw</locale>
+      <encoding>ISO-8859-8</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>ja</locale>
+      <encoding>Shift_JIS</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>ko</locale>
+      <encoding>EUC-KR</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>lt</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>lv</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>mk</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>nl</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>no</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>pl</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>pt</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>ro</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>ru</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sh</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sk</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sl</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sq</locale>
+      <encoding>ISO-8859-2</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sr</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>sv</locale>
+      <encoding>ISO-8859-1</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>tr</locale>
+      <encoding>ISO-8859-9</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>uk</locale>
+      <encoding>ISO-8859-5</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>zh</locale>
+      <encoding>GB2312</encoding>
+    </locale-encoding-mapping>
+    <locale-encoding-mapping>
+      <locale>zh_TW</locale>
+      <encoding>Big5</encoding>
+    </locale-encoding-mapping>
+  </locale-encoding-mapping-list>
+
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>Disable TRACE</web-resource-name>
+      <url-pattern>/</url-pattern>
+      <http-method>TRACE</http-method>
+    </web-resource-collection>
+    <auth-constraint/>
+  </security-constraint>
+
+</web-app>
+
diff --git a/src/java/org/eclipse/jetty/client/AbstractHttpConnection.java b/src/java/org/eclipse/jetty/client/AbstractHttpConnection.java
new file mode 100644
index 0000000..0e0042c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/AbstractHttpConnection.java
@@ -0,0 +1,571 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.jetty.client.security.Authentication;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpGenerator;
+import org.eclipse.jetty.http.HttpHeaderValues;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpVersions;
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.View;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout;
+
+/**
+ *
+ * @version $Revision: 879 $ $Date: 2009-09-11 16:13:28 +0200 (Fri, 11 Sep 2009) $
+ */
+public abstract class AbstractHttpConnection extends AbstractConnection implements Dumpable
+{
+    private static final Logger LOG = Log.getLogger(AbstractHttpConnection.class);
+
+    protected HttpDestination _destination;
+    protected HttpGenerator _generator;
+    protected HttpParser _parser;
+    protected boolean _http11 = true;
+    protected int _status;
+    protected Buffer _connectionHeader;
+    protected boolean _reserved;
+
+    // The current exchange waiting for a response
+    protected volatile HttpExchange _exchange;
+    protected HttpExchange _pipeline;
+    private final Timeout.Task _idleTimeout = new ConnectionIdleTask();
+    private AtomicBoolean _idle = new AtomicBoolean(false);
+
+
+    AbstractHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endp)
+    {
+        super(endp);
+
+        _generator = new HttpGenerator(requestBuffers,endp);
+        _parser = new HttpParser(responseBuffers,endp,new Handler());
+    }
+
+    public void setReserved (boolean reserved)
+    {
+        _reserved = reserved;
+    }
+
+    public boolean isReserved()
+    {
+        return _reserved;
+    }
+
+    public HttpDestination getDestination()
+    {
+        return _destination;
+    }
+
+    public void setDestination(HttpDestination destination)
+    {
+        _destination = destination;
+    }
+
+    public boolean send(HttpExchange ex) throws IOException
+    {
+        LOG.debug("Send {} on {}",ex,this);
+        synchronized (this)
+        {
+            if (_exchange != null)
+            {
+                if (_pipeline != null)
+                    throw new IllegalStateException(this + " PIPELINED!!!  _exchange=" + _exchange);
+                _pipeline = ex;
+                return true;
+            }
+
+            _exchange = ex;
+            _exchange.associate(this);
+
+            // The call to associate() may have closed the connection, check if it's the case
+            if (!_endp.isOpen())
+            {
+                _exchange.disassociate();
+                _exchange = null;
+                return false;
+            }
+
+            _exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_COMMIT);
+
+            adjustIdleTimeout();
+
+            return true;
+        }
+    }
+
+    private void adjustIdleTimeout() throws IOException
+    {
+        // Adjusts the idle timeout in case the default or exchange timeout
+        // are greater. This is needed for long polls, where one wants an
+        // aggressive releasing of idle connections (so idle timeout is small)
+        // but still allow long polls to complete normally
+
+        long timeout = _exchange.getTimeout();
+        if (timeout <= 0)
+            timeout = _destination.getHttpClient().getTimeout();
+
+        long endPointTimeout = _endp.getMaxIdleTime();
+
+        if (timeout > 0 && timeout > endPointTimeout)
+        {
+            // Make it larger than the exchange timeout so that there are
+            // no races between the idle timeout and the exchange timeout
+            // when trying to close the endpoint
+            _endp.setMaxIdleTime(2 * (int)timeout);
+        }
+    }
+
+    public abstract Connection handle() throws IOException;
+
+
+    public boolean isIdle()
+    {
+        synchronized (this)
+        {
+            return _exchange == null;
+        }
+    }
+
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    public void onClose()
+    {
+    }
+
+    /**
+     * @throws IOException
+     */
+    protected void commitRequest() throws IOException
+    {
+        synchronized (this)
+        {
+            _status=0;
+            if (_exchange.getStatus() != HttpExchange.STATUS_WAITING_FOR_COMMIT)
+                throw new IllegalStateException();
+
+            _exchange.setStatus(HttpExchange.STATUS_SENDING_REQUEST);
+            _generator.setVersion(_exchange.getVersion());
+
+            String method=_exchange.getMethod();
+            String uri = _exchange.getRequestURI();
+            if (_destination.isProxied())
+            {
+                if (!HttpMethods.CONNECT.equals(method) && uri.startsWith("/"))
+                {
+                    boolean secure = _destination.isSecure();
+                    String host = _destination.getAddress().getHost();
+                    int port = _destination.getAddress().getPort();
+                    StringBuilder absoluteURI = new StringBuilder();
+                    absoluteURI.append(secure ? HttpSchemes.HTTPS : HttpSchemes.HTTP);
+                    absoluteURI.append("://");
+                    absoluteURI.append(host);
+                    // Avoid adding default ports
+                    if (!(secure && port == 443 || !secure && port == 80))
+                        absoluteURI.append(":").append(port);
+                    absoluteURI.append(uri);
+                    uri = absoluteURI.toString();
+                }
+                Authentication auth = _destination.getProxyAuthentication();
+                if (auth != null)
+                    auth.setCredentials(_exchange);
+            }
+
+            _generator.setRequest(method, uri);
+            _parser.setHeadResponse(HttpMethods.HEAD.equalsIgnoreCase(method));
+
+            HttpFields requestHeaders = _exchange.getRequestFields();
+            if (_exchange.getVersion() >= HttpVersions.HTTP_1_1_ORDINAL)
+            {
+                if (!requestHeaders.containsKey(HttpHeaders.HOST_BUFFER))
+                    requestHeaders.add(HttpHeaders.HOST_BUFFER,_destination.getHostHeader());
+            }
+
+            Buffer requestContent = _exchange.getRequestContent();
+            if (requestContent != null)
+            {
+                requestHeaders.putLongField(HttpHeaders.CONTENT_LENGTH, requestContent.length());
+                _generator.completeHeader(requestHeaders,false);
+                _generator.addContent(new View(requestContent),true);
+                _exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+            }
+            else
+            {
+                InputStream requestContentStream = _exchange.getRequestContentSource();
+                if (requestContentStream != null)
+                {
+                    _generator.completeHeader(requestHeaders, false);
+                }
+                else
+                {
+                    requestHeaders.remove(HttpHeaders.CONTENT_LENGTH);
+                    _generator.completeHeader(requestHeaders, true);
+                    _exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+                }
+            }
+        }
+    }
+
+    protected void reset() throws IOException
+    {
+        _connectionHeader = null;
+        _parser.reset();
+        _generator.reset();
+        _http11 = true;
+    }
+
+
+    private class Handler extends HttpParser.EventHandler
+    {
+        @Override
+        public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException
+        {
+            // System.out.println( method.toString() + "///" + url.toString() +
+            // "///" + version.toString() );
+            // TODO validate this is acceptable, the <!DOCTYPE goop was coming
+            // out here
+            // throw new IllegalStateException();
+        }
+
+        @Override
+        public void startResponse(Buffer version, int status, Buffer reason) throws IOException
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange==null)
+            {
+                LOG.warn("No exchange for response");
+                _endp.close();
+                return;
+            }
+
+            switch(status)
+            {
+                case HttpStatus.CONTINUE_100:
+                case HttpStatus.PROCESSING_102:
+                    // TODO check if appropriate expect was sent in the request.
+                    exchange.setEventListener(new NonFinalResponseListener(exchange));
+                    break;
+
+                case HttpStatus.OK_200:
+                    // handle special case for CONNECT 200 responses
+                    if (HttpMethods.CONNECT.equalsIgnoreCase(exchange.getMethod()))
+                        _parser.setHeadResponse(true);
+                    break;
+            }
+
+            _http11 = HttpVersions.HTTP_1_1_BUFFER.equals(version);
+            _status=status;
+            exchange.getEventListener().onResponseStatus(version,status,reason);
+            exchange.setStatus(HttpExchange.STATUS_PARSING_HEADERS);
+
+        }
+
+        @Override
+        public void parsedHeader(Buffer name, Buffer value) throws IOException
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange!=null)
+            {
+                if (HttpHeaders.CACHE.getOrdinal(name) == HttpHeaders.CONNECTION_ORDINAL)
+                {
+                    _connectionHeader = HttpHeaderValues.CACHE.lookup(value);
+                }
+                exchange.getEventListener().onResponseHeader(name,value);
+            }
+        }
+
+        @Override
+        public void headerComplete() throws IOException
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange!=null)
+            {
+                exchange.setStatus(HttpExchange.STATUS_PARSING_CONTENT);
+                if (HttpMethods.CONNECT.equalsIgnoreCase(exchange.getMethod()))
+                    _parser.setPersistent(true);
+            }
+        }
+
+        @Override
+        public void content(Buffer ref) throws IOException
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange!=null)
+                exchange.getEventListener().onResponseContent(ref);
+        }
+
+        @Override
+        public void messageComplete(long contextLength) throws IOException
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange!=null)
+                exchange.setStatus(HttpExchange.STATUS_COMPLETED);
+        }
+
+        @Override
+        public void earlyEOF()
+        {
+            HttpExchange exchange = _exchange;
+            if (exchange!=null)
+            {
+                if (!exchange.isDone())
+                {
+                    if (exchange.setStatus(HttpExchange.STATUS_EXCEPTED))
+                        exchange.getEventListener().onException(new EofException("early EOF"));
+                }
+            }
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("%s %s g=%s p=%s",
+                super.toString(),
+                _destination == null ? "?.?.?.?:??" : _destination.getAddress(),
+                _generator,
+                _parser);
+    }
+
+    public String toDetailString()
+    {
+        return toString() + " ex=" + _exchange + " idle for " + _idleTimeout.getAge();
+    }
+
+    public void close() throws IOException
+    {
+        //if there is a live, unfinished exchange, set its status to be
+        //excepted and wake up anyone waiting on waitForDone()
+
+        HttpExchange exchange = _exchange;
+        if (exchange != null && !exchange.isDone())
+        {
+            switch (exchange.getStatus())
+            {
+                case HttpExchange.STATUS_CANCELLED:
+                case HttpExchange.STATUS_CANCELLING:
+                case HttpExchange.STATUS_COMPLETED:
+                case HttpExchange.STATUS_EXCEPTED:
+                case HttpExchange.STATUS_EXPIRED:
+                    break;
+                case HttpExchange.STATUS_PARSING_CONTENT:
+                    if (_endp.isInputShutdown() && _parser.isState(HttpParser.STATE_EOF_CONTENT))
+                        break;
+                default:
+                    String exch= exchange.toString();
+                    String reason = _endp.isOpen()?(_endp.isInputShutdown()?"half closed: ":"local close: "):"closed: ";
+                    if (exchange.setStatus(HttpExchange.STATUS_EXCEPTED))
+                        exchange.getEventListener().onException(new EofException(reason+exch));
+            }
+        }
+
+        if (_endp.isOpen())
+        {
+            _endp.close();
+            _destination.returnConnection(this, true);
+        }
+    }
+
+    public void setIdleTimeout()
+    {
+        synchronized (this)
+        {
+            if (_idle.compareAndSet(false, true))
+                _destination.getHttpClient().scheduleIdle(_idleTimeout);
+            else
+                throw new IllegalStateException();
+        }
+    }
+
+    public boolean cancelIdleTimeout()
+    {
+        synchronized (this)
+        {
+            if (_idle.compareAndSet(true, false))
+            {
+                _destination.getHttpClient().cancel(_idleTimeout);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    protected void exchangeExpired(HttpExchange exchange)
+    {
+        synchronized (this)
+        {
+            // We are expiring an exchange, but the exchange is pending
+            // Cannot reuse the connection because the reply may arrive, so close it
+            if (_exchange == exchange)
+            {
+                try
+                {
+                    _destination.returnConnection(this, true);
+                }
+                catch (IOException x)
+                {
+                    LOG.ignore(x);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.Dumpable#dump()
+     */
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String)
+     */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        synchronized (this)
+        {
+            out.append(String.valueOf(this)).append("\n");
+            AggregateLifeCycle.dump(out,indent,Collections.singletonList(_endp));
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private class ConnectionIdleTask extends Timeout.Task
+    {
+        /* ------------------------------------------------------------ */
+        @Override
+        public void expired()
+        {
+            // Connection idle, close it
+            if (_idle.compareAndSet(true, false))
+            {
+                _destination.returnIdleConnection(AbstractHttpConnection.this);
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private class NonFinalResponseListener implements HttpEventListener
+    {
+        final HttpExchange _exchange;
+        final HttpEventListener _next;
+
+        /* ------------------------------------------------------------ */
+        public NonFinalResponseListener(HttpExchange exchange)
+        {
+            _exchange=exchange;
+            _next=exchange.getEventListener();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onRequestCommitted() throws IOException
+        {
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onRequestComplete() throws IOException
+        {
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+        {
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onResponseHeader(Buffer name, Buffer value) throws IOException
+        {
+            _next.onResponseHeader(name,value);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onResponseHeaderComplete() throws IOException
+        {
+            _next.onResponseHeaderComplete();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onResponseContent(Buffer content) throws IOException
+        {
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onResponseComplete() throws IOException
+        {
+            _exchange.setEventListener(_next);
+            _exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+            _parser.reset();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onConnectionFailed(Throwable ex)
+        {
+            _exchange.setEventListener(_next);
+            _next.onConnectionFailed(ex);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onException(Throwable ex)
+        {
+            _exchange.setEventListener(_next);
+            _next.onException(ex);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onExpire()
+        {
+            _exchange.setEventListener(_next);
+            _next.onExpire();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void onRetry()
+        {
+            _exchange.setEventListener(_next);
+            _next.onRetry();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/Address.java b/src/java/org/eclipse/jetty/client/Address.java
new file mode 100644
index 0000000..5ea7f04
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/Address.java
@@ -0,0 +1,96 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.net.InetSocketAddress;
+
+/**
+ * @version $Revision: 4135 $ $Date: 2008-12-02 11:57:07 +0100 (Tue, 02 Dec 2008) $
+ */
+public class Address
+{
+    private final String host;
+    private final int port;
+
+    public static Address from(String hostAndPort)
+    {
+        String host;
+        int port;
+        int colon = hostAndPort.indexOf(':');
+        if (colon >= 0)
+        {
+            host = hostAndPort.substring(0, colon);
+            port = Integer.parseInt(hostAndPort.substring(colon + 1));
+        }
+        else
+        {
+            host = hostAndPort;
+            port = 0;
+        }
+        return new Address(host, port);
+    }
+
+    public Address(String host, int port)
+    {
+        if (host == null)
+            throw new IllegalArgumentException("Host is null");
+        
+        this.host = host.trim();
+        this.port = port;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+        Address that = (Address)obj;
+        if (!host.equals(that.host)) return false;
+        return port == that.port;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = host.hashCode();
+        result = 31 * result + port;
+        return result;
+    }
+
+    public String getHost()
+    {
+        return host;
+    }
+
+    public int getPort()
+    {
+        return port;
+    }
+
+    public InetSocketAddress toSocketAddress()
+    {
+        return new InetSocketAddress(getHost(), getPort());
+    }
+
+    @Override
+    public String toString()
+    {
+        return host + ":" + port;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/AsyncHttpConnection.java b/src/java/org/eclipse/jetty/client/AsyncHttpConnection.java
new file mode 100644
index 0000000..8af1fea
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/AsyncHttpConnection.java
@@ -0,0 +1,269 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.http.AbstractGenerator;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+/* ------------------------------------------------------------ */
+/** Asynchronous Client HTTP Connection
+ */
+public class AsyncHttpConnection extends AbstractHttpConnection implements AsyncConnection
+{
+    private static final Logger LOG = Log.getLogger(AsyncHttpConnection.class);
+
+    private boolean _requestComplete;
+    private Buffer _requestContentChunk;
+    private final AsyncEndPoint _asyncEndp;
+
+    AsyncHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endp)
+    {
+        super(requestBuffers,responseBuffers,endp);
+        _asyncEndp=(AsyncEndPoint)endp;
+    }
+
+    protected void reset() throws IOException
+    {
+        _requestComplete = false;
+        super.reset();
+    }
+
+    public Connection handle() throws IOException
+    {
+        Connection connection = this;
+        boolean progress=true;
+
+        try
+        {
+            boolean failed = false;
+
+            // While we are making progress and have not changed connection
+            while (progress && connection==this)
+            {
+                LOG.debug("while open={} more={} progress={}",_endp.isOpen(),_parser.isMoreInBuffer(),progress);
+
+                progress=false;
+                HttpExchange exchange=_exchange;
+
+                LOG.debug("exchange {} on {}",exchange,this);
+
+                try
+                {
+                    // Should we commit the request?
+                    if (!_generator.isCommitted() && exchange!=null && exchange.getStatus() == HttpExchange.STATUS_WAITING_FOR_COMMIT)
+                    {
+                        LOG.debug("commit {}",exchange);
+                        progress=true;
+                        commitRequest();
+                    }
+
+                    // Generate output
+                    if (_generator.isCommitted() && !_generator.isComplete())
+                    {
+                        if (_generator.flushBuffer()>0)
+                        {
+                            LOG.debug("flushed");
+                            progress=true;
+                        }
+
+                        // Is there more content to send or should we complete the generator
+                        if (_generator.isState(AbstractGenerator.STATE_CONTENT))
+                        {
+                            // Look for more content to send.
+                            if (_requestContentChunk==null)
+                                _requestContentChunk = exchange.getRequestContentChunk(null);
+
+                            if (_requestContentChunk==null)
+                            {
+                                LOG.debug("complete {}",exchange);
+                                progress=true;
+                                _generator.complete();
+                                if (exchange.getStatus() < HttpExchange.STATUS_WAITING_FOR_RESPONSE)
+                                    exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+                            }
+                            else if (_generator.isEmpty())
+                            {
+                                LOG.debug("addChunk");
+                                progress=true;
+                                Buffer chunk=_requestContentChunk;
+                                _requestContentChunk=exchange.getRequestContentChunk(null);
+                                _generator.addContent(chunk,_requestContentChunk==null);
+                                if (_requestContentChunk==null)
+                                    exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+                            }
+                        }
+                    }
+
+                    // Signal request completion
+                    if (_generator.isComplete() && !_requestComplete)
+                    {
+                        LOG.debug("requestComplete {}",exchange);
+                        progress=true;
+                        _requestComplete = true;
+                        exchange.getEventListener().onRequestComplete();
+                    }
+
+                    // Read any input that is available
+                    if (!_parser.isComplete() && _parser.parseAvailable())
+                    {
+                        LOG.debug("parsed {}",exchange);
+                        progress=true;
+                    }
+
+                    // Flush output
+                    _endp.flush();
+
+                    // Has any IO been done by the endpoint itself since last loop
+                    if (_asyncEndp.hasProgressed())
+                    {
+                        LOG.debug("hasProgressed {}",exchange);
+                        progress=true;
+                    }
+                }
+                catch (Throwable e)
+                {
+                    LOG.debug("Failure on " + _exchange, e);
+
+                    failed = true;
+
+                    synchronized (this)
+                    {
+                        if (exchange != null)
+                        {
+                            // Cancelling the exchange causes an exception as we close the connection,
+                            // but we don't report it as it is normal cancelling operation
+                            if (exchange.getStatus() != HttpExchange.STATUS_CANCELLING &&
+                                    exchange.getStatus() != HttpExchange.STATUS_CANCELLED &&
+                                    !exchange.isDone())
+                            {
+                                if (exchange.setStatus(HttpExchange.STATUS_EXCEPTED))
+                                    exchange.getEventListener().onException(e);
+                            }
+                        }
+                        else
+                        {
+                            if (e instanceof IOException)
+                                throw (IOException)e;
+                            if (e instanceof Error)
+                                throw (Error)e;
+                            if (e instanceof RuntimeException)
+                                throw (RuntimeException)e;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+                finally
+                {
+                    LOG.debug("finally {} on {} progress={} {}",exchange,this,progress,_endp);
+
+                    boolean complete = failed || _generator.isComplete() && _parser.isComplete();
+
+                    if (complete)
+                    {
+                        boolean persistent = !failed && _parser.isPersistent() && _generator.isPersistent();
+                        _generator.setPersistent(persistent);
+                        reset();
+                        if (persistent)
+                            _endp.setMaxIdleTime((int)_destination.getHttpClient().getIdleTimeout());
+
+                        synchronized (this)
+                        {
+                            exchange=_exchange;
+                            _exchange = null;
+
+                            // Cancel the exchange
+                            if (exchange!=null)
+                            {
+                                exchange.cancelTimeout(_destination.getHttpClient());
+
+                                // TODO should we check the exchange is done?
+                            }
+
+                            // handle switched protocols
+                            if (_status==HttpStatus.SWITCHING_PROTOCOLS_101)
+                            {
+                                Connection switched=exchange.onSwitchProtocol(_endp);
+                                if (switched!=null)
+                                {
+                                    // switched protocol!
+                                    if (_pipeline!=null)
+                                    {
+                                        _destination.send(_pipeline);
+                                    }
+                                    _pipeline = null;
+
+                                    connection=switched;
+                                }
+                            }
+
+                            // handle pipelined requests
+                            if (_pipeline!=null)
+                            {
+                                if (!persistent || connection!=this)
+                                    _destination.send(_pipeline);
+                                else
+                                    _exchange=_pipeline;
+                                _pipeline=null;
+                            }
+
+                            if (_exchange==null && !isReserved())  // TODO how do we return switched connections?
+                                _destination.returnConnection(this, !persistent);
+                        }
+
+                    }
+                }
+            }
+        }
+        finally
+        {
+            _parser.returnBuffers();
+            _generator.returnBuffers();
+            LOG.debug("unhandle {} on {}",_exchange,_endp);
+        }
+
+        return connection;
+    }
+
+    public void onInputShutdown() throws IOException
+    {
+        if (_generator.isIdle())
+            _endp.shutdownOutput();
+    }
+
+    @Override
+    public boolean send(HttpExchange ex) throws IOException
+    {
+        boolean sent=super.send(ex);
+        if (sent)
+            _asyncEndp.asyncDispatch();
+        return sent;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/BlockingHttpConnection.java b/src/java/org/eclipse/jetty/client/BlockingHttpConnection.java
new file mode 100644
index 0000000..94d163b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/BlockingHttpConnection.java
@@ -0,0 +1,314 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import org.eclipse.jetty.http.AbstractGenerator;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** Blocking HTTP Connection
+ */
+public class BlockingHttpConnection extends AbstractHttpConnection
+{
+    private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
+
+    private boolean _requestComplete;
+    private Buffer _requestContentChunk;
+    private boolean _expired=false;
+
+    BlockingHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endPoint)
+    {
+        super(requestBuffers, responseBuffers, endPoint);
+    }
+
+    protected void reset() throws IOException
+    {
+        _requestComplete = false;
+        _expired = false;
+        super.reset();
+    }
+    
+    
+    @Override
+    protected void exchangeExpired(HttpExchange exchange)
+    {
+        synchronized (this)
+        {
+           super.exchangeExpired(exchange);
+           _expired = true;
+           this.notifyAll();
+        }
+    }
+    
+    
+
+    @Override
+    public void onIdleExpired(long idleForMs)
+    {
+        try
+        {
+            LOG.debug("onIdleExpired {}ms {} {}",idleForMs,this,_endp);
+            _expired = true;
+            _endp.close();
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+
+            try
+            {
+                _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+        }
+
+        synchronized(this)
+        {
+            this.notifyAll();
+        }
+    }
+
+    @Override
+    public Connection handle() throws IOException
+    {
+        Connection connection = this;
+
+        try
+        {
+            boolean failed = false;
+
+
+            // While we are making progress and have not changed connection
+            while (_endp.isOpen() && connection==this)
+            {
+                LOG.debug("open={} more={}",_endp.isOpen(),_parser.isMoreInBuffer());
+
+                HttpExchange exchange;
+                synchronized (this)
+                {
+                    exchange=_exchange;
+                    while (exchange == null)
+                    {
+                        try
+                        {
+                            this.wait();
+                            exchange=_exchange;
+                            if (_expired)
+                            {
+                                failed = true;
+                                throw new InterruptedException();
+                            }
+
+                        }
+                        catch (InterruptedException e)
+                        {
+                            throw new InterruptedIOException();
+                        }
+                    }
+                }
+                LOG.debug("exchange {}",exchange);
+
+                try
+                {
+                    // Should we commit the request?
+                    if (!_generator.isCommitted() && exchange!=null && exchange.getStatus() == HttpExchange.STATUS_WAITING_FOR_COMMIT)
+                    {
+                        LOG.debug("commit");
+                        commitRequest();
+                    }
+
+                    // Generate output
+                    while (_generator.isCommitted() && !_generator.isComplete())
+                    {
+                        if (_generator.flushBuffer()>0)
+                        {
+                            LOG.debug("flushed");
+                        }
+
+                        // Is there more content to send or should we complete the generator
+                        if (_generator.isState(AbstractGenerator.STATE_CONTENT))
+                        {
+                            // Look for more content to send.
+                            if (_requestContentChunk==null)
+                                _requestContentChunk = exchange.getRequestContentChunk(null);
+
+                            if (_requestContentChunk==null)
+                            {
+                                LOG.debug("complete");
+                                _generator.complete();
+                            }
+                            else if (_generator.isEmpty())
+                            {
+                                LOG.debug("addChunk");
+                                Buffer chunk=_requestContentChunk;
+                                _requestContentChunk=exchange.getRequestContentChunk(null);
+                                _generator.addContent(chunk,_requestContentChunk==null);
+                                if (_requestContentChunk==null)
+                                    exchange.setStatus(HttpExchange.STATUS_WAITING_FOR_RESPONSE);
+                            }
+                        }
+                    }
+
+                    // Signal request completion
+                    if (_generator.isComplete() && !_requestComplete)
+                    {
+                        LOG.debug("requestComplete");
+                        _requestComplete = true;
+                        exchange.getEventListener().onRequestComplete();
+                    }
+
+                    // Read any input that is available
+                    if (!_parser.isComplete() && _parser.parseAvailable())
+                    {
+                        LOG.debug("parsed");
+                    }
+
+                    // Flush output
+                    _endp.flush();
+                }
+                catch (Throwable e)
+                {
+                    LOG.debug("Failure on " + _exchange, e);
+
+                    failed = true;
+
+                    synchronized (this)
+                    {
+                        if (exchange != null)
+                        {
+                            // Cancelling the exchange causes an exception as we close the connection,
+                            // but we don't report it as it is normal cancelling operation
+                            if (exchange.getStatus() != HttpExchange.STATUS_CANCELLING &&
+                                    exchange.getStatus() != HttpExchange.STATUS_CANCELLED &&
+                                    !exchange.isDone())
+                            {
+                                if(exchange.setStatus(HttpExchange.STATUS_EXCEPTED))
+                                    exchange.getEventListener().onException(e);
+                            }
+                        }
+                        else
+                        {
+                            if (e instanceof IOException)
+                                throw (IOException)e;
+                            if (e instanceof Error)
+                                throw (Error)e;
+                            if (e instanceof RuntimeException)
+                                throw (RuntimeException)e;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+                finally
+                {
+                    LOG.debug("{} {}",_generator, _parser);
+                    LOG.debug("{}",_endp);
+
+                    boolean complete = failed || _generator.isComplete() && _parser.isComplete();
+
+                    if (complete)
+                    {
+                        boolean persistent = !failed && _parser.isPersistent() && _generator.isPersistent();
+                        _generator.setPersistent(persistent);
+                        reset();
+                        if (persistent)
+                            _endp.setMaxIdleTime((int)_destination.getHttpClient().getIdleTimeout());
+
+                        synchronized (this)
+                        {
+                            exchange=_exchange;
+                            _exchange = null;
+
+                            // Cancel the exchange
+                            if (exchange!=null)
+                            {
+                                exchange.cancelTimeout(_destination.getHttpClient());
+
+                                // TODO should we check the exchange is done?
+                            }
+
+                            // handle switched protocols
+                            if (_status==HttpStatus.SWITCHING_PROTOCOLS_101)
+                            {
+                                Connection switched=exchange.onSwitchProtocol(_endp);
+                                if (switched!=null)
+                                    connection=switched;
+                                {
+                                    // switched protocol!
+                                    _pipeline = null;
+                                    if (_pipeline!=null)
+                                        _destination.send(_pipeline);
+                                    _pipeline = null;
+
+                                    connection=switched;
+                                }
+                            }
+
+                            // handle pipelined requests
+                            if (_pipeline!=null)
+                            {
+                                if (!persistent || connection!=this)
+                                    _destination.send(_pipeline);
+                                else
+                                    _exchange=_pipeline;
+                                _pipeline=null;
+                            }
+
+                            if (_exchange==null && !isReserved())  // TODO how do we return switched connections?
+                                _destination.returnConnection(this, !persistent);
+                        }
+                    }
+                }
+            }
+        }
+        finally
+        {
+            _parser.returnBuffers();
+            _generator.returnBuffers();
+        }
+
+        return connection;
+    }
+
+    @Override
+    public boolean send(HttpExchange ex) throws IOException
+    {
+        boolean sent=super.send(ex);
+        if (sent)
+        {
+            synchronized (this)
+            {
+                notifyAll();
+            }
+        }
+        return sent;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/CachedExchange.java b/src/java/org/eclipse/jetty/client/CachedExchange.java
new file mode 100644
index 0000000..2643399
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/CachedExchange.java
@@ -0,0 +1,75 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.io.Buffer;
+
+/**
+ * An exchange that retains response status and response headers for later use.
+ */
+public class CachedExchange extends HttpExchange
+{
+    private final HttpFields _responseFields;
+    private volatile int _responseStatus;
+
+    /**
+     * Creates a new CachedExchange.
+     *
+     * @param cacheHeaders true to cache response headers, false to not cache them
+     */
+    public CachedExchange(boolean cacheHeaders)
+    {
+        _responseFields = cacheHeaders ? new HttpFields() : null;
+    }
+
+    public synchronized int getResponseStatus()
+    {
+        if (getStatus() < HttpExchange.STATUS_PARSING_HEADERS)
+            throw new IllegalStateException("Response not received yet");
+        return _responseStatus;
+    }
+
+    public synchronized HttpFields getResponseFields()
+    {
+        if (getStatus() < HttpExchange.STATUS_PARSING_CONTENT)
+            throw new IllegalStateException("Headers not completely received yet");
+        return _responseFields;
+    }
+
+    @Override
+    protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        _responseStatus = status;
+        super.onResponseStatus(version, status, reason);
+    }
+
+    @Override
+    protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
+    {
+        if (_responseFields != null)
+        {
+            _responseFields.add(name, value.asImmutableBuffer());
+        }
+        
+        super.onResponseHeader(name, value);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/ContentExchange.java b/src/java/org/eclipse/jetty/client/ContentExchange.java
new file mode 100644
index 0000000..4cbbe9c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/ContentExchange.java
@@ -0,0 +1,135 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.util.StringUtil;
+
+/**
+ * A exchange that retains response content for later use.
+ */
+public class ContentExchange extends CachedExchange
+{
+    private int _bufferSize = 4096;
+    private String _encoding = "utf-8";
+    private ByteArrayOutputStream _responseContent;
+    private File _fileForUpload;
+
+    public ContentExchange()
+    {
+        super(false);
+    }
+
+    public ContentExchange(boolean cacheFields)
+    {
+        super(cacheFields);
+    }
+
+    public synchronized String getResponseContent() throws UnsupportedEncodingException
+    {
+        if (_responseContent != null)
+            return _responseContent.toString(_encoding);
+        return null;
+    }
+
+    public synchronized byte[] getResponseContentBytes()
+    {
+        if (_responseContent != null)
+            return _responseContent.toByteArray();
+        return null;
+    }
+
+    @Override
+    protected synchronized void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        if (_responseContent!=null)
+            _responseContent.reset();
+        super.onResponseStatus(version,status,reason);
+    }
+
+    @Override
+    protected synchronized void onResponseHeader(Buffer name, Buffer value) throws IOException
+    {
+        super.onResponseHeader(name, value);
+        int header = HttpHeaders.CACHE.getOrdinal(name);
+        switch (header)
+        {
+            case HttpHeaders.CONTENT_LENGTH_ORDINAL:
+                _bufferSize = BufferUtil.toInt(value);
+                break;
+            case HttpHeaders.CONTENT_TYPE_ORDINAL:
+                String mime = StringUtil.asciiToLowerCase(value.toString());
+                int i = mime.indexOf("charset=");
+                if (i > 0)
+                {
+                    _encoding = mime.substring(i + 8);
+                    i = _encoding.indexOf(';');
+                    if (i > 0)
+                        _encoding = _encoding.substring(0, i);
+                }
+                break;
+        }
+    }
+
+    @Override
+    protected synchronized void onResponseContent(Buffer content) throws IOException
+    {
+        super.onResponseContent(content);
+        if (_responseContent == null)
+            _responseContent = new ByteArrayOutputStream(_bufferSize);
+        content.writeTo(_responseContent);
+    }
+
+    @Override
+    protected synchronized void onRetry() throws IOException
+    {
+        if (_fileForUpload != null)
+        {
+            setRequestContent(null);
+            setRequestContentSource(getInputStream());
+        }
+        else
+            super.onRetry();
+    }
+
+    private synchronized InputStream getInputStream() throws IOException
+    {
+        return new FileInputStream(_fileForUpload);
+    }
+
+    public synchronized File getFileForUpload()
+    {
+        return _fileForUpload;
+    }
+
+    public synchronized void setFileForUpload(File fileForUpload) throws IOException
+    {
+        this._fileForUpload = fileForUpload;
+        setRequestContentSource(getInputStream());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/HttpClient.java b/src/java/org/eclipse/jetty/client/HttpClient.java
new file mode 100644
index 0000000..80f5536
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/HttpClient.java
@@ -0,0 +1,911 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.net.ssl.SSLContext;
+
+import org.eclipse.jetty.client.security.Authentication;
+import org.eclipse.jetty.client.security.RealmResolver;
+import org.eclipse.jetty.client.security.SecurityListener;
+import org.eclipse.jetty.http.HttpBuffers;
+import org.eclipse.jetty.http.HttpBuffersImpl;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Buffers.Type;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.ThreadPool;
+import org.eclipse.jetty.util.thread.Timeout;
+
+/**
+ * Http Client.
+ * <p/>
+ * HttpClient is the main active component of the client API implementation.
+ * It is the opposite of the Connectors in standard Jetty, in that it listens
+ * for responses rather than requests.   Just like the connectors, there is a
+ * blocking socket version and a non-blocking NIO version (implemented as nested classes
+ * selected by {@link #setConnectorType(int)}).
+ * <p/>
+ * The an instance of {@link HttpExchange} is passed to the {@link #send(HttpExchange)} method
+ * to send a request.  The exchange contains both the headers and content (source) of the request
+ * plus the callbacks to handle responses.   A HttpClient can have many exchanges outstanding
+ * and they may be queued on the {@link HttpDestination} waiting for a {@link AbstractHttpConnection},
+ * queued in the {@link AbstractHttpConnection} waiting to be transmitted or pipelined on the actual
+ * TCP/IP connection waiting for a response.
+ * <p/>
+ * The {@link HttpDestination} class is an aggregation of {@link AbstractHttpConnection}s for the
+ * same host, port and protocol.   A destination may limit the number of connections
+ * open and they provide a pool of open connections that may be reused.   Connections may also
+ * be allocated from a destination, so that multiple request sources are not multiplexed
+ * over the same connection.
+ *
+ * @see HttpExchange
+ * @see HttpDestination
+ */
+public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attributes, Dumpable
+{
+    public static final int CONNECTOR_SOCKET = 0;
+    public static final int CONNECTOR_SELECT_CHANNEL = 2;
+
+    private int _connectorType = CONNECTOR_SELECT_CHANNEL;
+    private boolean _useDirectBuffers = true;
+    private boolean _connectBlocking = true;
+    private int _maxConnectionsPerAddress = Integer.MAX_VALUE;
+    private int _maxQueueSizePerAddress = Integer.MAX_VALUE;
+    private ConcurrentMap<Address, HttpDestination> _destinations = new ConcurrentHashMap<Address, HttpDestination>();
+    ThreadPool _threadPool;
+    Connector _connector;
+    private long _idleTimeout = 20000;
+    private long _timeout = 320000;
+    private int _connectTimeout = 75000;
+    private Timeout _timeoutQ = new Timeout();
+    private Timeout _idleTimeoutQ = new Timeout();
+    private Address _proxy;
+    private Authentication _proxyAuthentication;
+    private Set<String> _noProxy;
+    private int _maxRetries = 3;
+    private int _maxRedirects = 20;
+    private LinkedList<String> _registeredListeners;
+
+    private final SslContextFactory _sslContextFactory;
+
+    private RealmResolver _realmResolver;
+
+    private AttributesMap _attributes=new AttributesMap();
+
+    private final HttpBuffersImpl _buffers= new HttpBuffersImpl();
+
+    /* ------------------------------------------------------------------------------- */
+    private void setBufferTypes()
+    {
+        if (_connectorType==CONNECTOR_SOCKET)
+        {
+            _buffers.setRequestBufferType(Type.BYTE_ARRAY);
+            _buffers.setRequestHeaderType(Type.BYTE_ARRAY);
+            _buffers.setResponseBufferType(Type.BYTE_ARRAY);
+            _buffers.setResponseHeaderType(Type.BYTE_ARRAY);
+        }
+        else
+        {
+            _buffers.setRequestBufferType(Type.DIRECT);
+            _buffers.setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
+            _buffers.setResponseBufferType(Type.DIRECT);
+            _buffers.setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT);
+        }
+
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public HttpClient()
+    {
+        this(new SslContextFactory());
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public HttpClient(SslContextFactory sslContextFactory)
+    {
+        _sslContextFactory = sslContextFactory;
+        addBean(_sslContextFactory);
+        addBean(_buffers);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @return True if connects will be in blocking mode.
+     */
+    public boolean isConnectBlocking()
+    {
+        return _connectBlocking;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @param connectBlocking True if connects will be in blocking mode.
+     */
+    public void setConnectBlocking(boolean connectBlocking)
+    {
+        _connectBlocking = connectBlocking;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void send(HttpExchange exchange) throws IOException
+    {
+        boolean ssl = HttpSchemes.HTTPS_BUFFER.equalsIgnoreCase(exchange.getScheme());
+        HttpDestination destination = getDestination(exchange.getAddress(), ssl);
+        destination.send(exchange);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the threadpool
+     */
+    public ThreadPool getThreadPool()
+    {
+        return _threadPool;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the ThreadPool.
+     * The threadpool passed is added via {@link #addBean(Object)} so that
+     * it's lifecycle may be managed as a {@link AggregateLifeCycle}.
+     * @param threadPool the threadPool to set
+     */
+    public void setThreadPool(ThreadPool threadPool)
+    {
+        removeBean(_threadPool);
+        _threadPool = threadPool;
+        addBean(_threadPool);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     * @return Attribute associated with client
+     */
+    public Object getAttribute(String name)
+    {
+        return _attributes.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return names of attributes associated with client
+     */
+    public Enumeration getAttributeNames()
+    {
+        return _attributes.getAttributeNames();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     */
+    public void removeAttribute(String name)
+    {
+        _attributes.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set an attribute on the HttpClient.
+     * Attributes are not used by the client, but are provided for
+     * so that users of a shared HttpClient may share other structures.
+     * @param name
+     * @param attribute
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _attributes.setAttribute(name,attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void clearAttributes()
+    {
+        _attributes.clearAttributes();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public HttpDestination getDestination(Address remote, boolean ssl) throws IOException
+    {
+        return getDestination(remote, ssl, getSslContextFactory());
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public HttpDestination getDestination(Address remote, boolean ssl, SslContextFactory sslContextFactory) throws IOException
+    {
+        if (remote == null)
+            throw new UnknownHostException("Remote socket address cannot be null.");
+
+        HttpDestination destination = _destinations.get(remote);
+        if (destination == null)
+        {
+            destination = new HttpDestination(this, remote, ssl, sslContextFactory);
+            if (_proxy != null && (_noProxy == null || !_noProxy.contains(remote.getHost())))
+            {
+                destination.setProxy(_proxy);
+                if (_proxyAuthentication != null)
+                    destination.setProxyAuthentication(_proxyAuthentication);
+            }
+            HttpDestination other =_destinations.putIfAbsent(remote, destination);
+            if (other!=null)
+                destination=other;
+        }
+        return destination;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void schedule(Timeout.Task task)
+    {
+        _timeoutQ.schedule(task);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void schedule(Timeout.Task task, long timeout)
+    {
+        _timeoutQ.schedule(task, timeout - _timeoutQ.getDuration());
+    }
+
+    /* ------------------------------------------------------------ */
+    public void scheduleIdle(Timeout.Task task)
+    {
+        _idleTimeoutQ.schedule(task);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void cancel(Timeout.Task task)
+    {
+        task.cancel();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get whether the connector can use direct NIO buffers.
+     */
+    public boolean getUseDirectBuffers()
+    {
+        return _useDirectBuffers;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set a RealmResolver for client Authentication.
+     * If a realmResolver is set, then the HttpDestinations created by
+     * this client will instantiate a {@link SecurityListener} so that
+     * BASIC and DIGEST authentication can be performed.
+     * @param resolver
+     */
+    public void setRealmResolver(RealmResolver resolver)
+    {
+        _realmResolver = resolver;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * returns the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
+     *
+     * @return the SecurityRealmResolver reg_realmResolveristered with the HttpClient or null
+     */
+    public RealmResolver getRealmResolver()
+    {
+        return _realmResolver;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean hasRealms()
+    {
+        return _realmResolver == null ? false : true;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Registers a listener that can listen to the stream of execution between the client and the
+     * server and influence events.  Sequential calls to the method wrapper sequentially wrap the preceding
+     * listener in a delegation model.
+     * <p/>
+     * NOTE: the SecurityListener is a special listener which doesn't need to be added via this
+     * mechanic, if you register security realms then it will automatically be added as the top listener of the
+     * delegation stack.
+     *
+     * @param listenerClass
+     */
+    public void registerListener(String listenerClass)
+    {
+        if (_registeredListeners == null)
+        {
+            _registeredListeners = new LinkedList<String>();
+        }
+        _registeredListeners.add(listenerClass);
+    }
+
+    /* ------------------------------------------------------------ */
+    public LinkedList<String> getRegisteredListeners()
+    {
+        return _registeredListeners;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set to use NIO direct buffers.
+     *
+     * @param direct If True (the default), the connector can use NIO direct
+     *               buffers. Some JVMs have memory management issues (bugs) with
+     *               direct buffers.
+     */
+    public void setUseDirectBuffers(boolean direct)
+    {
+        _useDirectBuffers = direct;
+        setBufferTypes();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the type of connector (socket, blocking or select) in use.
+     */
+    public int getConnectorType()
+    {
+        return _connectorType;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setConnectorType(int connectorType)
+    {
+        this._connectorType = connectorType;
+        setBufferTypes();
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxConnectionsPerAddress()
+    {
+        return _maxConnectionsPerAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxConnectionsPerAddress(int maxConnectionsPerAddress)
+    {
+        _maxConnectionsPerAddress = maxConnectionsPerAddress;
+    }
+
+    public int getMaxQueueSizePerAddress()
+    {
+        return _maxQueueSizePerAddress;
+    }
+
+    public void setMaxQueueSizePerAddress(int maxQueueSizePerAddress)
+    {
+        this._maxQueueSizePerAddress = maxQueueSizePerAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        setBufferTypes();
+
+        _timeoutQ.setDuration(_timeout);
+        _timeoutQ.setNow();
+        _idleTimeoutQ.setDuration(_idleTimeout);
+        _idleTimeoutQ.setNow();
+
+        if (_threadPool==null)
+        {
+            QueuedThreadPool pool = new LocalQueuedThreadPool();
+            pool.setMaxThreads(16);
+            pool.setDaemon(true);
+            pool.setName("HttpClient");
+            _threadPool = pool;
+            addBean(_threadPool,true);
+        }
+
+        _connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this);
+        addBean(_connector,true);
+
+        super.doStart();
+
+        _threadPool.dispatch(new Runnable()
+        {
+            public void run()
+            {
+                while (isRunning())
+                {
+                    _timeoutQ.tick(System.currentTimeMillis());
+                    _idleTimeoutQ.tick(_timeoutQ.getNow());
+                    try
+                    {
+                        Thread.sleep(200);
+                    }
+                    catch (InterruptedException ignored)
+                    {
+                    }
+                }
+            }
+        });
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        for (HttpDestination destination : _destinations.values())
+            destination.close();
+
+        _timeoutQ.cancelAll();
+        _idleTimeoutQ.cancelAll();
+
+        super.doStop();
+
+        if (_threadPool instanceof LocalQueuedThreadPool)
+        {
+            removeBean(_threadPool);
+            _threadPool = null;
+        }
+
+        removeBean(_connector);
+    }
+
+    /* ------------------------------------------------------------ */
+    interface Connector extends LifeCycle
+    {
+        public void startConnection(HttpDestination destination) throws IOException;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * if a keystore location has been provided then client will attempt to use it as the keystore,
+     * otherwise we simply ignore certificates and run with a loose ssl context.
+     *
+     * @return the SSL context
+     */
+    protected SSLContext getSSLContext()
+    {
+        return _sslContextFactory.getSslContext();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the instance of SslContextFactory associated with the client
+     */
+    public SslContextFactory getSslContextFactory()
+    {
+        return _sslContextFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the period in milliseconds a {@link AbstractHttpConnection} can be idle for before it is closed.
+     */
+    public long getIdleTimeout()
+    {
+        return _idleTimeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param ms the period in milliseconds a {@link AbstractHttpConnection} can be idle for before it is closed.
+     */
+    public void setIdleTimeout(long ms)
+    {
+        _idleTimeout = ms;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the period in ms that an exchange will wait for a response from the server.
+     * @deprecated use {@link #getTimeout()} instead.
+     */
+    @Deprecated
+    public int getSoTimeout()
+    {
+        return Long.valueOf(getTimeout()).intValue();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @deprecated use {@link #setTimeout(long)} instead.
+     * @param timeout the period in ms that an exchange will wait for a response from the server.
+     */
+    @Deprecated
+    public void setSoTimeout(int timeout)
+    {
+        setTimeout(timeout);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the period in ms that an exchange will wait for a response from the server.
+     */
+    public long getTimeout()
+    {
+        return _timeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param timeout the period in ms that an exchange will wait for a response from the server.
+     */
+    public void setTimeout(long timeout)
+    {
+        _timeout = timeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the period in ms before timing out an attempt to connect
+     */
+    public int getConnectTimeout()
+    {
+        return _connectTimeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param connectTimeout the period in ms before timing out an attempt to connect
+     */
+    public void setConnectTimeout(int connectTimeout)
+    {
+        this._connectTimeout = connectTimeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Address getProxy()
+    {
+        return _proxy;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setProxy(Address proxy)
+    {
+        this._proxy = proxy;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Authentication getProxyAuthentication()
+    {
+        return _proxyAuthentication;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setProxyAuthentication(Authentication authentication)
+    {
+        _proxyAuthentication = authentication;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isProxied()
+    {
+        return this._proxy != null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Set<String> getNoProxy()
+    {
+        return _noProxy;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setNoProxy(Set<String> noProxyAddresses)
+    {
+        _noProxy = noProxyAddresses;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int maxRetries()
+    {
+        return _maxRetries;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxRetries(int retries)
+    {
+        _maxRetries = retries;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int maxRedirects()
+    {
+        return _maxRedirects;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxRedirects(int redirects)
+    {
+        _maxRedirects = redirects;
+    }
+
+    public int getRequestBufferSize()
+    {
+        return _buffers.getRequestBufferSize();
+    }
+
+    public void setRequestBufferSize(int requestBufferSize)
+    {
+        _buffers.setRequestBufferSize(requestBufferSize);
+    }
+
+    public int getRequestHeaderSize()
+    {
+        return _buffers.getRequestHeaderSize();
+    }
+
+    public void setRequestHeaderSize(int requestHeaderSize)
+    {
+        _buffers.setRequestHeaderSize(requestHeaderSize);
+    }
+
+    public int getResponseBufferSize()
+    {
+        return _buffers.getResponseBufferSize();
+    }
+
+    public void setResponseBufferSize(int responseBufferSize)
+    {
+        _buffers.setResponseBufferSize(responseBufferSize);
+    }
+
+    public int getResponseHeaderSize()
+    {
+        return _buffers.getResponseHeaderSize();
+    }
+
+    public void setResponseHeaderSize(int responseHeaderSize)
+    {
+        _buffers.setResponseHeaderSize(responseHeaderSize);
+    }
+
+    public Type getRequestBufferType()
+    {
+        return _buffers.getRequestBufferType();
+    }
+
+    public Type getRequestHeaderType()
+    {
+        return _buffers.getRequestHeaderType();
+    }
+
+    public Type getResponseBufferType()
+    {
+        return _buffers.getResponseBufferType();
+    }
+
+    public Type getResponseHeaderType()
+    {
+        return _buffers.getResponseHeaderType();
+    }
+
+    public void setRequestBuffers(Buffers requestBuffers)
+    {
+        _buffers.setRequestBuffers(requestBuffers);
+    }
+
+    public void setResponseBuffers(Buffers responseBuffers)
+    {
+        _buffers.setResponseBuffers(responseBuffers);
+    }
+
+    public Buffers getRequestBuffers()
+    {
+        return _buffers.getRequestBuffers();
+    }
+
+    public Buffers getResponseBuffers()
+    {
+        return _buffers.getResponseBuffers();
+    }
+
+    public void setMaxBuffers(int maxBuffers)
+    {
+        _buffers.setMaxBuffers(maxBuffers);
+    }
+
+    public int getMaxBuffers()
+    {
+        return _buffers.getMaxBuffers();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getTrustStoreLocation()
+    {
+        return _sslContextFactory.getTrustStore();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setTrustStoreLocation(String trustStoreLocation)
+    {
+        _sslContextFactory.setTrustStore(trustStoreLocation);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public InputStream getTrustStoreInputStream()
+    {
+        return _sslContextFactory.getTrustStoreInputStream();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setTrustStoreInputStream(InputStream trustStoreInputStream)
+    {
+        _sslContextFactory.setTrustStoreInputStream(trustStoreInputStream);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getKeyStoreLocation()
+    {
+        return _sslContextFactory.getKeyStorePath();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setKeyStoreLocation(String keyStoreLocation)
+    {
+        _sslContextFactory.setKeyStorePath(keyStoreLocation);
+    }
+
+    @Deprecated
+    public InputStream getKeyStoreInputStream()
+    {
+        return _sslContextFactory.getKeyStoreInputStream();
+    }
+
+    @Deprecated
+    public void setKeyStoreInputStream(InputStream keyStoreInputStream)
+    {
+        _sslContextFactory.setKeyStoreInputStream(keyStoreInputStream);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setKeyStorePassword(String keyStorePassword)
+    {
+        _sslContextFactory.setKeyStorePassword(keyStorePassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setKeyManagerPassword(String keyManagerPassword)
+    {
+        _sslContextFactory.setKeyManagerPassword(keyManagerPassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setTrustStorePassword(String trustStorePassword)
+    {
+        _sslContextFactory.setTrustStorePassword(trustStorePassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getKeyStoreType()
+    {
+        return _sslContextFactory.getKeyStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setKeyStoreType(String keyStoreType)
+    {
+        _sslContextFactory.setKeyStoreType(keyStoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getTrustStoreType()
+    {
+        return _sslContextFactory.getTrustStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setTrustStoreType(String trustStoreType)
+    {
+        _sslContextFactory.setTrustStoreType(trustStoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getKeyManagerAlgorithm()
+    {
+        return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setKeyManagerAlgorithm(String keyManagerAlgorithm)
+    {
+        _sslContextFactory.setSslKeyManagerFactoryAlgorithm(keyManagerAlgorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getTrustManagerAlgorithm()
+    {
+        return _sslContextFactory.getTrustManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setTrustManagerAlgorithm(String trustManagerAlgorithm)
+    {
+        _sslContextFactory.setTrustManagerFactoryAlgorithm(trustManagerAlgorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getProtocol()
+    {
+        return _sslContextFactory.getProtocol();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setProtocol(String protocol)
+    {
+        _sslContextFactory.setProtocol(protocol);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getProvider()
+    {
+        return _sslContextFactory.getProvider();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setProvider(String provider)
+    {
+        _sslContextFactory.setProvider(provider);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getSecureRandomAlgorithm()
+    {
+        return _sslContextFactory.getSecureRandomAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public void setSecureRandomAlgorithm(String secureRandomAlgorithm)
+    {
+        _sslContextFactory.setSecureRandomAlgorithm(secureRandomAlgorithm);
+    }
+
+    private static class LocalQueuedThreadPool extends QueuedThreadPool
+    {
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/HttpDestination.java b/src/java/org/eclipse/jetty/client/HttpDestination.java
new file mode 100644
index 0000000..4e551cd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/HttpDestination.java
@@ -0,0 +1,751 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.jetty.client.HttpClient.Connector;
+import org.eclipse.jetty.client.security.Authentication;
+import org.eclipse.jetty.client.security.SecurityListener;
+import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+/**
+ * @version $Revision: 879 $ $Date: 2009-09-11 16:13:28 +0200 (Fri, 11 Sep 2009) $
+ */
+public class HttpDestination implements Dumpable
+{
+    private static final Logger LOG = Log.getLogger(HttpDestination.class);
+
+    private final List<HttpExchange> _exchanges = new LinkedList<HttpExchange>();
+    private final List<AbstractHttpConnection> _connections = new LinkedList<AbstractHttpConnection>();
+    private final BlockingQueue<Object> _reservedConnections = new ArrayBlockingQueue<Object>(10, true);
+    private final List<AbstractHttpConnection> _idleConnections = new ArrayList<AbstractHttpConnection>();
+    private final HttpClient _client;
+    private final Address _address;
+    private final boolean _ssl;
+    private final SslContextFactory _sslContextFactory;
+    private final ByteArrayBuffer _hostHeader;
+    private volatile int _maxConnections;
+    private volatile int _maxQueueSize;
+    private int _pendingConnections = 0;
+    private int _pendingReservedConnections = 0;
+    private volatile Address _proxy;
+    private Authentication _proxyAuthentication;
+    private PathMap _authorizations;
+    private List<HttpCookie> _cookies;
+
+    HttpDestination(HttpClient client, Address address, boolean ssl, SslContextFactory sslContextFactory)
+    {
+        _client = client;
+        _address = address;
+        _ssl = ssl;
+        _sslContextFactory = sslContextFactory;
+        _maxConnections = _client.getMaxConnectionsPerAddress();
+        _maxQueueSize = _client.getMaxQueueSizePerAddress();
+        String addressString = address.getHost();
+        if (address.getPort() != (_ssl ? 443 : 80))
+            addressString += ":" + address.getPort();
+        _hostHeader = new ByteArrayBuffer(addressString);
+    }
+
+    public HttpClient getHttpClient()
+    {
+        return _client;
+    }
+
+    public Address getAddress()
+    {
+        return _address;
+    }
+
+    public boolean isSecure()
+    {
+        return _ssl;
+    }
+
+    public SslContextFactory getSslContextFactory()
+    {
+        return _sslContextFactory;
+    }
+
+    public Buffer getHostHeader()
+    {
+        return _hostHeader;
+    }
+
+    public int getMaxConnections()
+    {
+        return _maxConnections;
+    }
+
+    public void setMaxConnections(int maxConnections)
+    {
+        this._maxConnections = maxConnections;
+    }
+
+    public int getMaxQueueSize()
+    {
+        return _maxQueueSize;
+    }
+
+    public void setMaxQueueSize(int maxQueueSize)
+    {
+        this._maxQueueSize = maxQueueSize;
+    }
+
+    public int getConnections()
+    {
+        synchronized (this)
+        {
+            return _connections.size();
+        }
+    }
+
+    public int getIdleConnections()
+    {
+        synchronized (this)
+        {
+            return _idleConnections.size();
+        }
+    }
+
+    public void addAuthorization(String pathSpec, Authentication authorization)
+    {
+        synchronized (this)
+        {
+            if (_authorizations == null)
+                _authorizations = new PathMap();
+            _authorizations.put(pathSpec, authorization);
+        }
+
+        // TODO query and remove methods
+    }
+
+    public void addCookie(HttpCookie cookie)
+    {
+        synchronized (this)
+        {
+            if (_cookies == null)
+                _cookies = new ArrayList<HttpCookie>();
+            _cookies.add(cookie);
+        }
+
+        // TODO query, remove and age methods
+    }
+
+    /**
+     * Get a connection. We either get an idle connection if one is available, or
+     * we make a new connection, if we have not yet reached maxConnections. If we
+     * have reached maxConnections, we wait until the number reduces.
+     *
+     * @param timeout max time prepared to block waiting to be able to get a connection
+     * @return a HttpConnection for this destination
+     * @throws IOException if an I/O error occurs
+     */
+    private AbstractHttpConnection getConnection(long timeout) throws IOException
+    {
+        AbstractHttpConnection connection = null;
+
+        while ((connection == null) && (connection = getIdleConnection()) == null && timeout > 0)
+        {
+            boolean startConnection = false;
+            synchronized (this)
+            {
+                int totalConnections = _connections.size() + _pendingConnections;
+                if (totalConnections < _maxConnections)
+                {
+                    _pendingReservedConnections++;
+                    startConnection = true;
+                }
+            }
+
+            if (startConnection)
+            {
+                startNewConnection();
+                try
+                {
+                    Object o = _reservedConnections.take();
+                    if (o instanceof AbstractHttpConnection)
+                    {
+                        connection = (AbstractHttpConnection)o;
+                    }
+                    else
+                        throw (IOException)o;
+                }
+                catch (InterruptedException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+            else
+            {
+                try
+                {
+                    Thread.currentThread();
+                    Thread.sleep(200);
+                    timeout -= 200;
+                }
+                catch (InterruptedException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+        }
+        return connection;
+    }
+
+    public AbstractHttpConnection reserveConnection(long timeout) throws IOException
+    {
+        AbstractHttpConnection connection = getConnection(timeout);
+        if (connection != null)
+            connection.setReserved(true);
+        return connection;
+    }
+
+    public AbstractHttpConnection getIdleConnection() throws IOException
+    {
+        AbstractHttpConnection connection = null;
+        while (true)
+        {
+            synchronized (this)
+            {
+                if (connection != null)
+                {
+                    _connections.remove(connection);
+                    connection.close();
+                    connection = null;
+                }
+                if (_idleConnections.size() > 0)
+                    connection = _idleConnections.remove(_idleConnections.size() - 1);
+            }
+
+            if (connection == null)
+            {
+                return null;
+            }
+
+            // Check if the connection was idle,
+            // but it expired just a moment ago
+            if (connection.cancelIdleTimeout())
+            {
+                return connection;
+            }
+        }
+    }
+
+    protected void startNewConnection()
+    {
+        try
+        {
+            synchronized (this)
+            {
+                _pendingConnections++;
+            }
+            final Connector connector = _client._connector;
+            if (connector != null)
+                connector.startConnection(this);
+        }
+        catch (Exception e)
+        {
+            LOG.debug(e);
+            onConnectionFailed(e);
+        }
+    }
+
+    public void onConnectionFailed(Throwable throwable)
+    {
+        Throwable connect_failure = null;
+
+        boolean startConnection = false;
+        synchronized (this)
+        {
+            _pendingConnections--;
+            if (_pendingReservedConnections > 0)
+            {
+                connect_failure = throwable;
+                _pendingReservedConnections--;
+            }
+            else if (_exchanges.size() > 0)
+            {
+                HttpExchange ex = _exchanges.remove(0);
+                if (ex.setStatus(HttpExchange.STATUS_EXCEPTED))
+                    ex.getEventListener().onConnectionFailed(throwable);
+
+                // Since an existing connection had failed, we need to create a
+                // connection if the  queue is not empty and client is running.
+                if (!_exchanges.isEmpty() && _client.isStarted())
+                    startConnection = true;
+            }
+        }
+
+        if (startConnection)
+            startNewConnection();
+
+        if (connect_failure != null)
+        {
+            try
+            {
+                _reservedConnections.put(connect_failure);
+            }
+            catch (InterruptedException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+    }
+
+    public void onException(Throwable throwable)
+    {
+        synchronized (this)
+        {
+            _pendingConnections--;
+            if (_exchanges.size() > 0)
+            {
+                HttpExchange ex = _exchanges.remove(0);
+                if (ex.setStatus(HttpExchange.STATUS_EXCEPTED))
+                    ex.getEventListener().onException(throwable);
+            }
+        }
+    }
+
+    public void onNewConnection(final AbstractHttpConnection connection) throws IOException
+    {
+        Connection reservedConnection = null;
+
+        synchronized (this)
+        {
+            _pendingConnections--;
+            _connections.add(connection);
+
+            if (_pendingReservedConnections > 0)
+            {
+                reservedConnection = connection;
+                _pendingReservedConnections--;
+            }
+            else
+            {
+                // Establish the tunnel if needed
+                EndPoint endPoint = connection.getEndPoint();
+                if (isProxied() && endPoint instanceof SelectConnector.UpgradableEndPoint)
+                {
+                    SelectConnector.UpgradableEndPoint proxyEndPoint = (SelectConnector.UpgradableEndPoint)endPoint;
+                    ConnectExchange connect = new ConnectExchange(getAddress(), proxyEndPoint);
+                    connect.setAddress(getProxy());
+                    LOG.debug("Establishing tunnel to {} via {}", getAddress(), getProxy());
+                    send(connection, connect);
+                }
+                else
+                {
+                    // Another connection stole the exchange that caused the creation of this connection ?
+                    if (_exchanges.size() == 0)
+                    {
+                        LOG.debug("No exchanges for new connection {}", connection);
+                        connection.setIdleTimeout();
+                        _idleConnections.add(connection);
+                    }
+                    else
+                    {
+                        HttpExchange exchange = _exchanges.remove(0);
+                        send(connection, exchange);
+                    }
+                }
+            }
+        }
+
+        if (reservedConnection != null)
+        {
+            try
+            {
+                _reservedConnections.put(reservedConnection);
+            }
+            catch (InterruptedException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+    }
+
+    public void returnConnection(AbstractHttpConnection connection, boolean close) throws IOException
+    {
+        if (connection.isReserved())
+            connection.setReserved(false);
+
+        if (close)
+        {
+            try
+            {
+                connection.close();
+            }
+            catch (IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+
+        if (!_client.isStarted())
+            return;
+
+        if (!close && connection.getEndPoint().isOpen())
+        {
+            synchronized (this)
+            {
+                if (_exchanges.size() == 0)
+                {
+                    connection.setIdleTimeout();
+                    _idleConnections.add(connection);
+                }
+                else
+                {
+                    HttpExchange ex = _exchanges.remove(0);
+                    send(connection, ex);
+                }
+                this.notifyAll();
+            }
+        }
+        else
+        {
+            boolean startConnection = false;
+            synchronized (this)
+            {
+                _connections.remove(connection);
+                if (!_exchanges.isEmpty())
+                    startConnection = true;
+            }
+
+            if (startConnection)
+                startNewConnection();
+        }
+    }
+
+    public void returnIdleConnection(AbstractHttpConnection connection)
+    {
+        // TODO work out the real idle time;
+        long idleForMs = connection.getEndPoint() != null ? connection.getEndPoint().getMaxIdleTime() : -1;
+        connection.onIdleExpired(idleForMs);
+
+        boolean startConnection = false;
+        synchronized (this)
+        {
+            _idleConnections.remove(connection);
+            _connections.remove(connection);
+
+            if (!_exchanges.isEmpty() && _client.isStarted())
+                startConnection = true;
+        }
+
+        if (startConnection)
+            startNewConnection();
+    }
+
+    public void send(HttpExchange ex) throws IOException
+    {
+        ex.setStatus(HttpExchange.STATUS_WAITING_FOR_CONNECTION);
+
+        LinkedList<String> listeners = _client.getRegisteredListeners();
+        if (listeners != null)
+        {
+            // Add registered listeners, fail if we can't load them
+            for (int i = listeners.size(); i > 0; --i)
+            {
+                String listenerClass = listeners.get(i - 1);
+                try
+                {
+                    Class<?> listener = Class.forName(listenerClass);
+                    Constructor constructor = listener.getDeclaredConstructor(HttpDestination.class, HttpExchange.class);
+                    HttpEventListener elistener = (HttpEventListener)constructor.newInstance(this, ex);
+                    ex.setEventListener(elistener);
+                }
+                catch (final Exception e)
+                {
+                    throw new IOException("Unable to instantiate registered listener for destination: " + listenerClass)
+                    {
+                        {
+                            initCause(e);
+                        }
+                    };
+                }
+            }
+        }
+
+        // Security is supported by default and should be the first consulted
+        if (_client.hasRealms())
+        {
+            ex.setEventListener(new SecurityListener(this, ex));
+        }
+
+        doSend(ex);
+    }
+
+    public void resend(HttpExchange ex) throws IOException
+    {
+        ex.getEventListener().onRetry();
+        ex.reset();
+        doSend(ex);
+    }
+
+    protected void doSend(HttpExchange ex) throws IOException
+    {
+        // add cookies
+        // TODO handle max-age etc.
+        if (_cookies != null)
+        {
+            StringBuilder buf = null;
+            for (HttpCookie cookie : _cookies)
+            {
+                if (buf == null)
+                    buf = new StringBuilder();
+                else
+                    buf.append("; ");
+                buf.append(cookie.getName()); // TODO quotes
+                buf.append("=");
+                buf.append(cookie.getValue()); // TODO quotes
+            }
+            if (buf != null)
+                ex.addRequestHeader(HttpHeaders.COOKIE, buf.toString());
+        }
+
+        // Add any known authorizations
+        if (_authorizations != null)
+        {
+            Authentication auth = (Authentication)_authorizations.match(ex.getRequestURI());
+            if (auth != null)
+                (auth).setCredentials(ex);
+        }
+
+        // Schedule the timeout here, before we queue the exchange
+        // so that we count also the queue time in the timeout
+        ex.scheduleTimeout(this);
+
+        AbstractHttpConnection connection = getIdleConnection();
+        if (connection != null)
+        {
+            send(connection, ex);
+        }
+        else
+        {
+            boolean startConnection = false;
+            synchronized (this)
+            {
+                if (_exchanges.size() == _maxQueueSize)
+                    throw new RejectedExecutionException("Queue full for address " + _address);
+
+                _exchanges.add(ex);
+                if (_connections.size() + _pendingConnections < _maxConnections)
+                    startConnection = true;
+            }
+
+            if (startConnection)
+                startNewConnection();
+        }
+    }
+
+    protected void exchangeExpired(HttpExchange exchange)
+    {
+        // The exchange may expire while waiting in the
+        // destination queue, make sure it is removed
+        synchronized (this)
+        {
+            _exchanges.remove(exchange);
+        }
+    }
+
+    protected void send(AbstractHttpConnection connection, HttpExchange exchange) throws IOException
+    {
+        synchronized (this)
+        {
+            // If server closes the connection, put the exchange back
+            // to the exchange queue and recycle the connection
+            if (!connection.send(exchange))
+            {
+                if (exchange.getStatus() <= HttpExchange.STATUS_WAITING_FOR_CONNECTION)
+                    _exchanges.add(0, exchange);
+                returnIdleConnection(connection);
+            }
+        }
+    }
+
+    @Override
+    public synchronized String toString()
+    {
+        return String.format("HttpDestination@%x//%s:%d(%d/%d,%d,%d/%d)%n", hashCode(), _address.getHost(), _address.getPort(), _connections.size(), _maxConnections, _idleConnections.size(), _exchanges.size(), _maxQueueSize);
+    }
+
+    public synchronized String toDetailString()
+    {
+        StringBuilder b = new StringBuilder();
+        b.append(toString());
+        b.append('\n');
+        synchronized (this)
+        {
+            for (AbstractHttpConnection connection : _connections)
+            {
+                b.append(connection.toDetailString());
+                if (_idleConnections.contains(connection))
+                    b.append(" IDLE");
+                b.append('\n');
+            }
+        }
+        b.append("--");
+        b.append('\n');
+
+        return b.toString();
+    }
+
+    public void setProxy(Address proxy)
+    {
+        _proxy = proxy;
+    }
+
+    public Address getProxy()
+    {
+        return _proxy;
+    }
+
+    public Authentication getProxyAuthentication()
+    {
+        return _proxyAuthentication;
+    }
+
+    public void setProxyAuthentication(Authentication authentication)
+    {
+        _proxyAuthentication = authentication;
+    }
+
+    public boolean isProxied()
+    {
+        return _proxy != null;
+    }
+
+    public void close() throws IOException
+    {
+        synchronized (this)
+        {
+            for (AbstractHttpConnection connection : _connections)
+            {
+                connection.close();
+            }
+        }
+    }
+
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }
+
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        synchronized (this)
+        {
+            out.append(String.valueOf(this));
+            out.append("idle=");
+            out.append(String.valueOf(_idleConnections.size()));
+            out.append(" pending=");
+            out.append(String.valueOf(_pendingConnections));
+            out.append("\n");
+            AggregateLifeCycle.dump(out, indent, _connections);
+        }
+    }
+
+    private class ConnectExchange extends ContentExchange
+    {
+        private final SelectConnector.UpgradableEndPoint proxyEndPoint;
+
+        public ConnectExchange(Address serverAddress, SelectConnector.UpgradableEndPoint proxyEndPoint)
+        {
+            this.proxyEndPoint = proxyEndPoint;
+            setMethod(HttpMethods.CONNECT);
+            String serverHostAndPort = serverAddress.toString();
+            setRequestURI(serverHostAndPort);
+            addRequestHeader(HttpHeaders.HOST, serverHostAndPort);
+            addRequestHeader(HttpHeaders.PROXY_CONNECTION, "keep-alive");
+            addRequestHeader(HttpHeaders.USER_AGENT, "Jetty-Client");
+        }
+
+        @Override
+        protected void onResponseComplete() throws IOException
+        {
+            int responseStatus = getResponseStatus();
+            if (responseStatus == HttpStatus.OK_200)
+            {
+                proxyEndPoint.upgrade();
+            }
+            else if (responseStatus == HttpStatus.GATEWAY_TIMEOUT_504)
+            {
+                onExpire();
+            }
+            else
+            {
+                onException(new ProtocolException("Proxy: " + proxyEndPoint.getRemoteAddr() + ":" + proxyEndPoint.getRemotePort() + " didn't return http return code 200, but " + responseStatus));
+            }
+        }
+
+        @Override
+        protected void onConnectionFailed(Throwable x)
+        {
+            HttpDestination.this.onConnectionFailed(x);
+        }
+
+        @Override
+        protected void onException(Throwable x)
+        {
+            HttpExchange exchange = null;
+            synchronized (HttpDestination.this)
+            {
+                if (!_exchanges.isEmpty())
+                    exchange = _exchanges.remove(0);
+            }
+            if (exchange != null && exchange.setStatus(STATUS_EXCEPTED))
+                exchange.getEventListener().onException(x);
+        }
+
+        @Override
+        protected void onExpire()
+        {
+            HttpExchange exchange = null;
+            synchronized (HttpDestination.this)
+            {
+                if (!_exchanges.isEmpty())
+                    exchange = _exchanges.remove(0);
+            }
+            if (exchange != null && exchange.setStatus(STATUS_EXPIRED))
+                exchange.getEventListener().onExpire();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/HttpEventListener.java b/src/java/org/eclipse/jetty/client/HttpEventListener.java
new file mode 100644
index 0000000..c38b048
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/HttpEventListener.java
@@ -0,0 +1,68 @@
+//
+//  ========================================================================
+//  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.client;
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+
+/**
+ * 
+ * 
+ * 
+ */
+public interface HttpEventListener
+{
+
+    // TODO review the methods here, we can probably trim these down on what to expose
+    
+    public void onRequestCommitted() throws IOException;
+
+
+    public void onRequestComplete() throws IOException;
+
+
+    public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException;
+
+
+    public void onResponseHeader(Buffer name, Buffer value) throws IOException;
+
+    
+    public void onResponseHeaderComplete() throws IOException;
+
+    
+    public void onResponseContent(Buffer content) throws IOException;
+
+
+    public void onResponseComplete() throws IOException;
+
+
+    public void onConnectionFailed(Throwable ex);
+
+
+    public void onException(Throwable ex);
+
+
+    public void onExpire();
+    
+    public void onRetry();
+    
+
+}
diff --git a/src/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java b/src/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java
new file mode 100644
index 0000000..152444e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/HttpEventListenerWrapper.java
@@ -0,0 +1,167 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+
+public class HttpEventListenerWrapper implements HttpEventListener
+{
+    HttpEventListener _listener;
+    boolean _delegatingRequests;
+    boolean _delegatingResponses;
+    boolean _delegationResult = true;
+    private Buffer _version;
+    private int _status;
+    private Buffer _reason;
+
+    public HttpEventListenerWrapper()
+    {
+        _listener=null;
+        _delegatingRequests=false;
+        _delegatingResponses=false;
+    }
+    
+    public HttpEventListenerWrapper(HttpEventListener eventListener,boolean delegating)
+    {
+        _listener=eventListener;
+        _delegatingRequests=delegating;
+        _delegatingResponses=delegating;
+    }
+    
+    public HttpEventListener getEventListener()
+    {
+        return _listener;
+    }
+
+    public void setEventListener(HttpEventListener listener)
+    {
+        _listener = listener;
+    }
+
+    public boolean isDelegatingRequests()
+    {
+        return _delegatingRequests;
+    }
+    
+    public boolean isDelegatingResponses()
+    {
+        return _delegatingResponses;
+    }
+
+    public void setDelegatingRequests(boolean delegating)
+    {
+        _delegatingRequests = delegating;
+    }
+    
+    public void setDelegatingResponses(boolean delegating)
+    {
+        _delegatingResponses = delegating;
+    }
+    
+    public void setDelegationResult( boolean result )
+    {
+        _delegationResult = result;
+    }
+    
+    public void onConnectionFailed(Throwable ex)
+    {
+        if (_delegatingRequests)
+            _listener.onConnectionFailed(ex);
+    }
+
+    public void onException(Throwable ex)
+    {
+        if (_delegatingRequests||_delegatingResponses)
+            _listener.onException(ex);
+    }
+
+    public void onExpire()
+    {
+        if (_delegatingRequests||_delegatingResponses)
+            _listener.onExpire();
+    }
+
+    public void onRequestCommitted() throws IOException
+    {
+        if (_delegatingRequests)
+            _listener.onRequestCommitted();
+    }
+
+    public void onRequestComplete() throws IOException
+    {
+        if (_delegatingRequests)
+            _listener.onRequestComplete();
+    }
+
+    public void onResponseComplete() throws IOException
+    {
+        if (_delegatingResponses)
+        {
+            if (_delegationResult == false)
+            {
+                _listener.onResponseStatus(_version,_status,_reason);
+            }
+            _listener.onResponseComplete();
+        }
+    }
+
+    public void onResponseContent(Buffer content) throws IOException
+    {
+        if (_delegatingResponses)
+            _listener.onResponseContent(content);
+    }
+
+    public void onResponseHeader(Buffer name, Buffer value) throws IOException
+    {
+        if (_delegatingResponses)
+            _listener.onResponseHeader(name,value);
+    }
+
+    public void onResponseHeaderComplete() throws IOException
+    {
+        if (_delegatingResponses)
+            _listener.onResponseHeaderComplete();
+    }
+
+    public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        if (_delegatingResponses)
+        {
+            _listener.onResponseStatus(version,status,reason);
+        }
+        else
+        {
+            _version = version;
+            _status = status;
+            _reason = reason;
+        }
+    }
+
+    public void onRetry()
+    {
+        if (_delegatingRequests)
+            _listener.onRetry();
+    }
+    
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/client/HttpExchange.java b/src/java/org/eclipse/jetty/client/HttpExchange.java
new file mode 100644
index 0000000..b97b9ff
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/HttpExchange.java
@@ -0,0 +1,1228 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.jetty.client.security.SecurityListener;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.HttpVersions;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout;
+
+/**
+ * <p>
+ * An HTTP client API that encapsulates an exchange (a request and its response) with a HTTP server.
+ * </p>
+ *
+ * This object encapsulates:
+ * <ul>
+ * <li>The HTTP server address, see {@link #setAddress(Address)}, or {@link #setURI(URI)}, or {@link #setURL(String)})
+ * <li>The HTTP request method, URI and HTTP version (see {@link #setMethod(String)}, {@link #setRequestURI(String)}, and {@link #setVersion(int)})
+ * <li>The request headers (see {@link #addRequestHeader(String, String)} or {@link #setRequestHeader(String, String)})
+ * <li>The request content (see {@link #setRequestContent(Buffer)} or {@link #setRequestContentSource(InputStream)})
+ * <li>The status of the exchange (see {@link #getStatus()})
+ * <li>Callbacks to handle state changes (see the onXxx methods such as {@link #onRequestComplete()} or {@link #onResponseComplete()})
+ * <li>The ability to intercept callbacks (see {@link #setEventListener(HttpEventListener)}
+ * </ul>
+ *
+ * <p>
+ * The HttpExchange class is intended to be used by a developer wishing to have close asynchronous interaction with the the exchange.<br />
+ * Typically a developer will extend the HttpExchange class with a derived class that overrides some or all of the onXxx callbacks. <br />
+ * There are also some predefined HttpExchange subtypes that can be used as a basis, see {@link org.eclipse.jetty.client.ContentExchange} and
+ * {@link org.eclipse.jetty.client.CachedExchange}.
+ * </p>
+ *
+ * <p>
+ * Typically the HttpExchange is passed to the {@link HttpClient#send(HttpExchange)} method, which in turn selects a {@link HttpDestination} and calls its
+ * {@link HttpDestination#send(HttpExchange)}, which then creates or selects a {@link AbstractHttpConnection} and calls its {@link AbstractHttpConnection#send(HttpExchange)}. A
+ * developer may wish to directly call send on the destination or connection if they wish to bypass some handling provided (eg Cookie handling in the
+ * HttpDestination).
+ * </p>
+ *
+ * <p>
+ * In some circumstances, the HttpClient or HttpDestination may wish to retry a HttpExchange (eg. failed pipeline request, authentication retry or redirection).
+ * In such cases, the HttpClient and/or HttpDestination may insert their own HttpExchangeListener to intercept and filter the call backs intended for the
+ * HttpExchange.
+ * </p>
+ */
+public class HttpExchange
+{
+    static final Logger LOG = Log.getLogger(HttpExchange.class);
+
+    public static final int STATUS_START = 0;
+    public static final int STATUS_WAITING_FOR_CONNECTION = 1;
+    public static final int STATUS_WAITING_FOR_COMMIT = 2;
+    public static final int STATUS_SENDING_REQUEST = 3;
+    public static final int STATUS_WAITING_FOR_RESPONSE = 4;
+    public static final int STATUS_PARSING_HEADERS = 5;
+    public static final int STATUS_PARSING_CONTENT = 6;
+    public static final int STATUS_COMPLETED = 7;
+    public static final int STATUS_EXPIRED = 8;
+    public static final int STATUS_EXCEPTED = 9;
+    public static final int STATUS_CANCELLING = 10;
+    public static final int STATUS_CANCELLED = 11;
+
+    // HTTP protocol fields
+    private String _method = HttpMethods.GET;
+    private Buffer _scheme = HttpSchemes.HTTP_BUFFER;
+    private String _uri;
+    private int _version = HttpVersions.HTTP_1_1_ORDINAL;
+    private Address _address;
+    private final HttpFields _requestFields = new HttpFields();
+    private Buffer _requestContent;
+    private InputStream _requestContentSource;
+
+    private AtomicInteger _status = new AtomicInteger(STATUS_START);
+    private boolean _retryStatus = false;
+    // controls if the exchange will have listeners autoconfigured by the destination
+    private boolean _configureListeners = true;
+    private HttpEventListener _listener = new Listener();
+    private volatile AbstractHttpConnection _connection;
+
+    private Address _localAddress = null;
+
+    // a timeout for this exchange
+    private long _timeout = -1;
+    private volatile Timeout.Task _timeoutTask;
+    private long _lastStateChange=System.currentTimeMillis();
+    private long _sent=-1;
+    private int _lastState=-1;
+    private int _lastStatePeriod=-1;
+
+    boolean _onRequestCompleteDone;
+    boolean _onResponseCompleteDone;
+    boolean _onDone; // == onConnectionFail || onException || onExpired || onCancelled || onResponseCompleted && onRequestCompleted
+
+    protected void expire(HttpDestination destination)
+    {
+        AbstractHttpConnection connection = _connection;
+        if (getStatus() < HttpExchange.STATUS_COMPLETED)
+            setStatus(HttpExchange.STATUS_EXPIRED);
+        destination.exchangeExpired(this);
+        if (connection != null)
+            connection.exchangeExpired(this);
+    }
+
+    public int getStatus()
+    {
+        return _status.get();
+    }
+
+    /**
+     * @param status
+     *            the status to wait for
+     * @throws InterruptedException
+     *             if the waiting thread is interrupted
+     * @deprecated Use {@link #waitForDone()} instead
+     */
+    @Deprecated
+    public void waitForStatus(int status) throws InterruptedException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Wait until the exchange is "done". Done is defined as when a final state has been passed to the HttpExchange via the associated onXxx call. Note that an
+     * exchange can transit a final state when being used as part of a dialog (eg {@link SecurityListener}. Done status is thus defined as:
+     *
+     * <pre>
+     * done == onConnectionFailed || onException || onExpire || onRequestComplete &amp;&amp; onResponseComplete
+     * </pre>
+     *
+     * @return the done status
+     * @throws InterruptedException
+     */
+    public int waitForDone() throws InterruptedException
+    {
+        synchronized (this)
+        {
+            while (!isDone())
+                this.wait();
+            return _status.get();
+        }
+    }
+
+    public void reset()
+    {
+        // TODO - this should do a cancel and wakeup everybody that was waiting.
+        // might need a version number concept
+        synchronized (this)
+        {
+            _timeoutTask = null;
+            _onRequestCompleteDone = false;
+            _onResponseCompleteDone = false;
+            _onDone = false;
+            setStatus(STATUS_START);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param newStatus
+     * @return True if the status was actually set.
+     */
+    boolean setStatus(int newStatus)
+    {
+        boolean set = false;
+        try
+        {
+            int oldStatus = _status.get();
+            boolean ignored = false;
+            if (oldStatus != newStatus)
+            {
+                long now = System.currentTimeMillis();
+                _lastStatePeriod=(int)(now-_lastStateChange);
+                _lastState=oldStatus;
+                _lastStateChange=now;
+                if (newStatus==STATUS_SENDING_REQUEST)
+                    _sent=_lastStateChange;
+            }
+            
+            // State machine: from which old status you can go into which new status
+            switch (oldStatus)
+            {
+                case STATUS_START:
+                    switch (newStatus)
+                    {
+                        case STATUS_START:
+                        case STATUS_WAITING_FOR_CONNECTION:
+                        case STATUS_WAITING_FOR_COMMIT:
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_WAITING_FOR_CONNECTION:
+                    switch (newStatus)
+                    {
+                        case STATUS_WAITING_FOR_COMMIT:
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_WAITING_FOR_COMMIT:
+                    switch (newStatus)
+                    {
+                        case STATUS_SENDING_REQUEST:
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_SENDING_REQUEST:
+                    switch (newStatus)
+                    {
+                        case STATUS_WAITING_FOR_RESPONSE:
+                            if (set = _status.compareAndSet(oldStatus,newStatus))
+                                getEventListener().onRequestCommitted();
+                            break;
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_WAITING_FOR_RESPONSE:
+                    switch (newStatus)
+                    {
+                        case STATUS_PARSING_HEADERS:
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_PARSING_HEADERS:
+                    switch (newStatus)
+                    {
+                        case STATUS_PARSING_CONTENT:
+                            if (set = _status.compareAndSet(oldStatus,newStatus))
+                                getEventListener().onResponseHeaderComplete();
+                            break;
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_PARSING_CONTENT:
+                    switch (newStatus)
+                    {
+                        case STATUS_COMPLETED:
+                            if (set = _status.compareAndSet(oldStatus,newStatus))
+                                getEventListener().onResponseComplete();
+                            break;
+                        case STATUS_CANCELLING:
+                        case STATUS_EXCEPTED:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_EXPIRED:
+                            set = setStatusExpired(newStatus,oldStatus);
+                            break;
+                    }
+                    break;
+                case STATUS_COMPLETED:
+                    switch (newStatus)
+                    {
+                        case STATUS_START:
+                        case STATUS_EXCEPTED:
+                        case STATUS_WAITING_FOR_RESPONSE:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                        case STATUS_CANCELLING:
+                        case STATUS_EXPIRED:
+                            // Don't change the status, it's too late
+                            ignored = true;
+                            break;
+                    }
+                    break;
+                case STATUS_CANCELLING:
+                    switch (newStatus)
+                    {
+                        case STATUS_EXCEPTED:
+                        case STATUS_CANCELLED:
+                            if (set = _status.compareAndSet(oldStatus,newStatus))
+                                done();
+                            break;
+                        default:
+                            // Ignore other statuses, we're cancelling
+                            ignored = true;
+                            break;
+                    }
+                    break;
+                case STATUS_EXCEPTED:
+                case STATUS_EXPIRED:
+                case STATUS_CANCELLED:
+                    switch (newStatus)
+                    {
+                        case STATUS_START:
+                            set = _status.compareAndSet(oldStatus,newStatus);
+                            break;
+                            
+                        case STATUS_COMPLETED:
+                            ignored = true;
+                            done();
+                            break; 
+                            
+                        default:
+                            ignored = true;
+                            break;
+                    }
+                    break;
+                default:
+                    // Here means I allowed to set a state that I don't recognize
+                    throw new AssertionError(oldStatus + " => " + newStatus);
+            }
+
+            if (!set && !ignored)
+                throw new IllegalStateException(toState(oldStatus) + " => " + toState(newStatus));
+            LOG.debug("setStatus {} {}",newStatus,this);
+        }
+        catch (IOException x)
+        {
+            LOG.warn(x);
+        }
+        return set;
+    }
+
+    private boolean setStatusExpired(int newStatus, int oldStatus)
+    {
+        boolean set;
+        if (set = _status.compareAndSet(oldStatus,newStatus))
+            getEventListener().onExpire();
+        return set;
+    }
+
+    public boolean isDone()
+    {
+        synchronized (this)
+        {
+            return _onDone;
+        }
+    }
+
+    /**
+     * @deprecated
+     */
+    @Deprecated
+    public boolean isDone(int status)
+    {
+        return isDone();
+    }
+
+    public HttpEventListener getEventListener()
+    {
+        return _listener;
+    }
+
+    public void setEventListener(HttpEventListener listener)
+    {
+        _listener = listener;
+    }
+
+    public void setTimeout(long timeout)
+    {
+        _timeout = timeout;
+    }
+
+    public long getTimeout()
+    {
+        return _timeout;
+    }
+
+    /**
+     * @param url
+     *            an absolute URL (for example 'http://localhost/foo/bar?a=1')
+     */
+    public void setURL(String url)
+    {
+        setURI(URI.create(url));
+    }
+
+    /**
+     * @param address
+     *            the address of the server
+     */
+    public void setAddress(Address address)
+    {
+        _address = address;
+    }
+
+    /**
+     * @return the address of the server
+     */
+    public Address getAddress()
+    {
+        return _address;
+    }
+
+    /**
+     * the local address used by the connection
+     *
+     * Note: this method will not be populated unless the exchange has been executed by the HttpClient
+     *
+     * @return the local address used for the running of the exchange if available, null otherwise.
+     */
+    public Address getLocalAddress()
+    {
+        return _localAddress;
+    }
+
+    /**
+     * @param scheme
+     *            the scheme of the URL (for example 'http')
+     */
+    public void setScheme(Buffer scheme)
+    {
+        _scheme = scheme;
+    }
+
+    /**
+     * @param scheme
+     *            the scheme of the URL (for example 'http')
+     */
+    public void setScheme(String scheme)
+    {
+        if (scheme != null)
+        {
+            if (HttpSchemes.HTTP.equalsIgnoreCase(scheme))
+                setScheme(HttpSchemes.HTTP_BUFFER);
+            else if (HttpSchemes.HTTPS.equalsIgnoreCase(scheme))
+                setScheme(HttpSchemes.HTTPS_BUFFER);
+            else
+                setScheme(new ByteArrayBuffer(scheme));
+        }
+    }
+
+    /**
+     * @return the scheme of the URL
+     */
+    public Buffer getScheme()
+    {
+        return _scheme;
+    }
+
+    /**
+     * @param version
+     *            the HTTP protocol version as integer, 9, 10 or 11 for 0.9, 1.0 or 1.1
+     */
+    public void setVersion(int version)
+    {
+        _version = version;
+    }
+
+    /**
+     * @param version
+     *            the HTTP protocol version as string
+     */
+    public void setVersion(String version)
+    {
+        CachedBuffer v = HttpVersions.CACHE.get(version);
+        if (v == null)
+            _version = 10;
+        else
+            _version = v.getOrdinal();
+    }
+
+    /**
+     * @return the HTTP protocol version as integer
+     * @see #setVersion(int)
+     */
+    public int getVersion()
+    {
+        return _version;
+    }
+
+    /**
+     * @param method
+     *            the HTTP method (for example 'GET')
+     */
+    public void setMethod(String method)
+    {
+        _method = method;
+    }
+
+    /**
+     * @return the HTTP method
+     */
+    public String getMethod()
+    {
+        return _method;
+    }
+
+    /**
+     * @return request URI
+     * @see #getRequestURI()
+     * @deprecated
+     */
+    @Deprecated
+    public String getURI()
+    {
+        return getRequestURI();
+    }
+
+    /**
+     * @return request URI
+     */
+    public String getRequestURI()
+    {
+        return _uri;
+    }
+
+    /**
+     * Set the request URI
+     *
+     * @param uri
+     *            new request URI
+     * @see #setRequestURI(String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setURI(String uri)
+    {
+        setRequestURI(uri);
+    }
+
+    /**
+     * Set the request URI
+     *
+     * Per RFC 2616 sec5, Request-URI = "*" | absoluteURI | abs_path | authority<br/>
+     * where:<br/>
+     * <br/>
+     * "*" - request applies to server itself<br/>
+     * absoluteURI - required for proxy requests, e.g. http://localhost:8080/context<br/>
+     * (this form is generated automatically by HttpClient)<br/>
+     * abs_path - used for most methods, e.g. /context<br/>
+     * authority - used for CONNECT method only, e.g. localhost:8080<br/>
+     * <br/>
+     * For complete definition of URI components, see RFC 2396 sec3.<br/>
+     *
+     * @param uri
+     *            new request URI
+     */
+    public void setRequestURI(String uri)
+    {
+        _uri = uri;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param uri
+     *            an absolute URI (for example 'http://localhost/foo/bar?a=1')
+     */
+    public void setURI(URI uri)
+    {
+        if (!uri.isAbsolute())
+            throw new IllegalArgumentException("!Absolute URI: " + uri);
+
+        if (uri.isOpaque())
+            throw new IllegalArgumentException("Opaque URI: " + uri);
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("URI = {}",uri.toASCIIString());
+
+        String scheme = uri.getScheme();
+        int port = uri.getPort();
+        if (port <= 0)
+            port = "https".equalsIgnoreCase(scheme)?443:80;
+
+        setScheme(scheme);
+        setAddress(new Address(uri.getHost(),port));
+
+        HttpURI httpUri = new HttpURI(uri);
+        String completePath = httpUri.getCompletePath();
+        setRequestURI(completePath == null?"/":completePath);
+    }
+
+    /**
+     * Adds the specified request header
+     *
+     * @param name
+     *            the header name
+     * @param value
+     *            the header value
+     */
+    public void addRequestHeader(String name, String value)
+    {
+        getRequestFields().add(name,value);
+    }
+
+    /**
+     * Adds the specified request header
+     *
+     * @param name
+     *            the header name
+     * @param value
+     *            the header value
+     */
+    public void addRequestHeader(Buffer name, Buffer value)
+    {
+        getRequestFields().add(name,value);
+    }
+
+    /**
+     * Sets the specified request header
+     *
+     * @param name
+     *            the header name
+     * @param value
+     *            the header value
+     */
+    public void setRequestHeader(String name, String value)
+    {
+        getRequestFields().put(name,value);
+    }
+
+    /**
+     * Sets the specified request header
+     *
+     * @param name
+     *            the header name
+     * @param value
+     *            the header value
+     */
+    public void setRequestHeader(Buffer name, Buffer value)
+    {
+        getRequestFields().put(name,value);
+    }
+
+    /**
+     * @param value
+     *            the content type of the request
+     */
+    public void setRequestContentType(String value)
+    {
+        getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,value);
+    }
+
+    /**
+     * @return the request headers
+     */
+    public HttpFields getRequestFields()
+    {
+        return _requestFields;
+    }
+
+    /**
+     * @param requestContent
+     *            the request content
+     */
+    public void setRequestContent(Buffer requestContent)
+    {
+        _requestContent = requestContent;
+    }
+
+    /**
+     * @param stream
+     *            the request content as a stream
+     */
+    public void setRequestContentSource(InputStream stream)
+    {
+        _requestContentSource = stream;
+        if (_requestContentSource != null && _requestContentSource.markSupported())
+            _requestContentSource.mark(Integer.MAX_VALUE);
+    }
+
+    /**
+     * @return the request content as a stream
+     */
+    public InputStream getRequestContentSource()
+    {
+        return _requestContentSource;
+    }
+
+    public Buffer getRequestContentChunk(Buffer buffer) throws IOException
+    {
+        synchronized (this)
+        {
+            if (_requestContentSource!=null)
+            {
+                if (buffer == null)
+                    buffer = new ByteArrayBuffer(8192); // TODO configure
+
+                int space = buffer.space();
+                int length = _requestContentSource.read(buffer.array(),buffer.putIndex(),space);
+                if (length >= 0)
+                {
+                    buffer.setPutIndex(buffer.putIndex()+length);
+                    return buffer;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * @return the request content
+     */
+    public Buffer getRequestContent()
+    {
+        return _requestContent;
+    }
+
+    /**
+     * @return whether a retry will be attempted or not
+     */
+    public boolean getRetryStatus()
+    {
+        return _retryStatus;
+    }
+
+    /**
+     * @param retryStatus
+     *            whether a retry will be attempted or not
+     */
+    public void setRetryStatus(boolean retryStatus)
+    {
+        _retryStatus = retryStatus;
+    }
+
+    /**
+     * Initiates the cancelling of this exchange. The status of the exchange is set to {@link #STATUS_CANCELLING}. Cancelling the exchange is an asynchronous
+     * operation with respect to the request/response, and as such checking the request/response status of a cancelled exchange may return undefined results
+     * (for example it may have only some of the response headers being sent by the server). The cancelling of the exchange is completed when the exchange
+     * status (see {@link #getStatus()}) is {@link #STATUS_CANCELLED}, and this can be waited using {@link #waitForDone()}.
+     */
+    public void cancel()
+    {
+        setStatus(STATUS_CANCELLING);
+        abort();
+    }
+
+    private void done()
+    {
+        synchronized (this)
+        {
+            disassociate();
+            _onDone = true;
+            notifyAll();
+        }
+    }
+
+    private void abort()
+    {
+        AbstractHttpConnection httpConnection = _connection;
+        if (httpConnection != null)
+        {
+            try
+            {
+                // Closing the connection here will cause the connection
+                // to be returned in HttpConnection.handle()
+                httpConnection.close();
+            }
+            catch (IOException x)
+            {
+                LOG.debug(x);
+            }
+            finally
+            {
+                disassociate();
+            }
+        }
+    }
+
+    void associate(AbstractHttpConnection connection)
+    {
+        if (connection.getEndPoint().getLocalAddr() != null)
+            _localAddress = new Address(connection.getEndPoint().getLocalAddr(),connection.getEndPoint().getLocalPort());
+
+        _connection = connection;
+        if (getStatus() == STATUS_CANCELLING)
+            abort();
+    }
+
+    boolean isAssociated()
+    {
+        return this._connection != null;
+    }
+
+    AbstractHttpConnection disassociate()
+    {
+        AbstractHttpConnection result = _connection;
+        this._connection = null;
+        if (getStatus() == STATUS_CANCELLING)
+            setStatus(STATUS_CANCELLED);
+        return result;
+    }
+
+    public static String toState(int s)
+    {
+        String state;
+        switch (s)
+        {
+            case STATUS_START:
+                state = "START";
+                break;
+            case STATUS_WAITING_FOR_CONNECTION:
+                state = "CONNECTING";
+                break;
+            case STATUS_WAITING_FOR_COMMIT:
+                state = "CONNECTED";
+                break;
+            case STATUS_SENDING_REQUEST:
+                state = "SENDING";
+                break;
+            case STATUS_WAITING_FOR_RESPONSE:
+                state = "WAITING";
+                break;
+            case STATUS_PARSING_HEADERS:
+                state = "HEADERS";
+                break;
+            case STATUS_PARSING_CONTENT:
+                state = "CONTENT";
+                break;
+            case STATUS_COMPLETED:
+                state = "COMPLETED";
+                break;
+            case STATUS_EXPIRED:
+                state = "EXPIRED";
+                break;
+            case STATUS_EXCEPTED:
+                state = "EXCEPTED";
+                break;
+            case STATUS_CANCELLING:
+                state = "CANCELLING";
+                break;
+            case STATUS_CANCELLED:
+                state = "CANCELLED";
+                break;
+            default:
+                state = "UNKNOWN";
+        }
+        return state;
+    }
+
+    @Override
+    public String toString()
+    {
+        String state=toState(getStatus());
+        long now=System.currentTimeMillis();
+        long forMs = now -_lastStateChange;
+        String s= _lastState>=0
+            ?String.format("%s@%x=%s//%s%s#%s(%dms)->%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,toState(_lastState),_lastStatePeriod,state,forMs)
+            :String.format("%s@%x=%s//%s%s#%s(%dms)",getClass().getSimpleName(),hashCode(),_method,_address,_uri,state,forMs);
+        if (getStatus()>=STATUS_SENDING_REQUEST && _sent>0)
+            s+="sent="+(now-_sent)+"ms";
+        return s;
+    }
+
+    /**
+     */
+    protected Connection onSwitchProtocol(EndPoint endp) throws IOException
+    {
+        return null;
+    }
+
+    /**
+     * Callback called when the request headers have been sent to the server. This implementation does nothing.
+     *
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onRequestCommitted() throws IOException
+    {
+    }
+
+    /**
+     * Callback called when the request and its body have been sent to the server. This implementation does nothing.
+     *
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onRequestComplete() throws IOException
+    {
+    }
+
+    /**
+     * Callback called when a response status line has been received from the server. This implementation does nothing.
+     *
+     * @param version
+     *            the HTTP version
+     * @param status
+     *            the HTTP status code
+     * @param reason
+     *            the HTTP status reason string
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+    }
+
+    /**
+     * Callback called for each response header received from the server. This implementation does nothing.
+     *
+     * @param name
+     *            the header name
+     * @param value
+     *            the header value
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onResponseHeader(Buffer name, Buffer value) throws IOException
+    {
+    }
+
+    /**
+     * Callback called when the response headers have been completely received from the server. This implementation does nothing.
+     *
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onResponseHeaderComplete() throws IOException
+    {
+    }
+
+    /**
+     * Callback called for each chunk of the response content received from the server. This implementation does nothing.
+     *
+     * @param content
+     *            the buffer holding the content chunk
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onResponseContent(Buffer content) throws IOException
+    {
+    }
+
+    /**
+     * Callback called when the entire response has been received from the server This implementation does nothing.
+     *
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onResponseComplete() throws IOException
+    {
+    }
+
+    /**
+     * Callback called when an exception was thrown during an attempt to establish the connection with the server (for example the server is not listening).
+     * This implementation logs a warning.
+     *
+     * @param x
+     *            the exception thrown attempting to establish the connection with the server
+     */
+    protected void onConnectionFailed(Throwable x)
+    {
+        LOG.warn("CONNECTION FAILED " + this,x);
+    }
+
+    /**
+     * Callback called when any other exception occurs during the handling of this exchange. This implementation logs a warning.
+     *
+     * @param x
+     *            the exception thrown during the handling of this exchange
+     */
+    protected void onException(Throwable x)
+    {
+        LOG.warn("EXCEPTION " + this,x);
+    }
+
+    /**
+     * Callback called when no response has been received within the timeout. This implementation logs a warning.
+     */
+    protected void onExpire()
+    {
+        LOG.warn("EXPIRED " + this);
+    }
+
+    /**
+     * Callback called when the request is retried (due to failures or authentication). Implementations must reset any consumable content that needs to be sent.
+     *
+     * @throws IOException
+     *             allowed to be thrown by overriding code
+     */
+    protected void onRetry() throws IOException
+    {
+        if (_requestContentSource != null)
+        {
+            if (_requestContentSource.markSupported())
+            {
+                _requestContent = null;
+                _requestContentSource.reset();
+            }
+            else
+            {
+                throw new IOException("Unsupported retry attempt");
+            }
+        }
+    }
+
+    /**
+     * @return true if the exchange should have listeners configured for it by the destination, false if this is being managed elsewhere
+     * @see #setConfigureListeners(boolean)
+     */
+    public boolean configureListeners()
+    {
+        return _configureListeners;
+    }
+
+    /**
+     * @param autoConfigure
+     *            whether the listeners are configured by the destination or elsewhere
+     */
+    public void setConfigureListeners(boolean autoConfigure)
+    {
+        this._configureListeners = autoConfigure;
+    }
+
+    protected void scheduleTimeout(final HttpDestination destination)
+    {
+        assert _timeoutTask == null;
+
+        _timeoutTask = new Timeout.Task()
+        {
+            @Override
+            public void expired()
+            {
+                HttpExchange.this.expire(destination);
+            }
+        };
+
+        HttpClient httpClient = destination.getHttpClient();
+        long timeout = getTimeout();
+        if (timeout > 0)
+            httpClient.schedule(_timeoutTask,timeout);
+        else
+            httpClient.schedule(_timeoutTask);
+    }
+
+    protected void cancelTimeout(HttpClient httpClient)
+    {
+        Timeout.Task task = _timeoutTask;
+        if (task != null)
+            httpClient.cancel(task);
+        _timeoutTask = null;
+    }
+
+    private class Listener implements HttpEventListener
+    {
+        public void onConnectionFailed(Throwable ex)
+        {
+            try
+            {
+                HttpExchange.this.onConnectionFailed(ex);
+            }
+            finally
+            {
+                done();
+            }
+        }
+
+        public void onException(Throwable ex)
+        {
+            try
+            {
+                HttpExchange.this.onException(ex);
+            }
+            finally
+            {
+                done();
+            }
+        }
+
+        public void onExpire()
+        {
+            try
+            {
+                HttpExchange.this.onExpire();
+            }
+            finally
+            {
+                done();
+            }
+        }
+
+        public void onRequestCommitted() throws IOException
+        {
+            HttpExchange.this.onRequestCommitted();
+        }
+
+        public void onRequestComplete() throws IOException
+        {
+            try
+            {
+                HttpExchange.this.onRequestComplete();
+            }
+            finally
+            {
+                synchronized (HttpExchange.this)
+                {
+                    _onRequestCompleteDone = true;
+                    // Member _onDone may already be true, for example
+                    // because the exchange expired or has been canceled
+                    _onDone |= _onResponseCompleteDone;
+                    if (_onDone)
+                        disassociate();
+                    HttpExchange.this.notifyAll();
+                }
+            }
+        }
+
+        public void onResponseComplete() throws IOException
+        {
+            try
+            {
+                HttpExchange.this.onResponseComplete();
+            }
+            finally
+            {
+                synchronized (HttpExchange.this)
+                {
+                    _onResponseCompleteDone = true;
+                    // Member _onDone may already be true, for example
+                    // because the exchange expired or has been canceled
+                    _onDone |= _onRequestCompleteDone;
+                    if (_onDone)
+                        disassociate();
+                    HttpExchange.this.notifyAll();
+                }
+            }
+        }
+
+        public void onResponseContent(Buffer content) throws IOException
+        {
+            HttpExchange.this.onResponseContent(content);
+        }
+
+        public void onResponseHeader(Buffer name, Buffer value) throws IOException
+        {
+            HttpExchange.this.onResponseHeader(name,value);
+        }
+
+        public void onResponseHeaderComplete() throws IOException
+        {
+            HttpExchange.this.onResponseHeaderComplete();
+        }
+
+        public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+        {
+            HttpExchange.this.onResponseStatus(version,status,reason);
+        }
+
+        public void onRetry()
+        {
+            HttpExchange.this.setRetryStatus(true);
+            try
+            {
+                HttpExchange.this.onRetry();
+            }
+            catch (IOException e)
+            {
+                LOG.debug(e);
+            }
+        }
+    }
+
+    /**
+     * @deprecated use {@link org.eclipse.jetty.client.CachedExchange} instead
+     */
+    @Deprecated
+    public static class CachedExchange extends org.eclipse.jetty.client.CachedExchange
+    {
+        public CachedExchange(boolean cacheFields)
+        {
+            super(cacheFields);
+        }
+    }
+
+    /**
+     * @deprecated use {@link org.eclipse.jetty.client.ContentExchange} instead
+     */
+    @Deprecated
+    public static class ContentExchange extends org.eclipse.jetty.client.ContentExchange
+    {
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/RedirectListener.java b/src/java/org/eclipse/jetty/client/RedirectListener.java
new file mode 100644
index 0000000..3336dfb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/RedirectListener.java
@@ -0,0 +1,212 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+
+/**
+ * RedirectListener
+ *
+ * Detect and handle the redirect responses
+ */
+public class RedirectListener extends HttpEventListenerWrapper
+{
+    private final HttpExchange _exchange;
+    private HttpDestination _destination;
+    private String _location;
+    private int _attempts;
+    private boolean _requestComplete;
+    private boolean _responseComplete;
+    private boolean _redirected;
+
+    public RedirectListener(HttpDestination destination, HttpExchange ex)
+    {
+        // Start of sending events through to the wrapped listener
+        // Next decision point is the onResponseStatus
+        super(ex.getEventListener(),true);
+
+        _destination = destination;
+        _exchange = ex;
+    }
+
+    @Override
+    public void onResponseStatus( Buffer version, int status, Buffer reason )
+        throws IOException
+    {
+        _redirected = ((status == HttpStatus.MOVED_PERMANENTLY_301 ||
+                        status == HttpStatus.MOVED_TEMPORARILY_302) &&
+                       _attempts < _destination.getHttpClient().maxRedirects());
+
+        if (_redirected)
+        {
+            setDelegatingRequests(false);
+            setDelegatingResponses(false);
+        }
+
+        super.onResponseStatus(version,status,reason);
+    }
+
+
+    @Override
+    public void onResponseHeader( Buffer name, Buffer value )
+        throws IOException
+    {
+        if (_redirected)
+        {
+            int header = HttpHeaders.CACHE.getOrdinal(name);
+            switch (header)
+            {
+                case HttpHeaders.LOCATION_ORDINAL:
+                    _location = value.toString();
+                    break;
+            }
+        }
+        super.onResponseHeader(name,value);
+    }
+
+    @Override
+    public void onRequestComplete() throws IOException
+    {
+        _requestComplete = true;
+
+        if (checkExchangeComplete())
+        {
+            super.onRequestComplete();
+        }
+    }
+
+    @Override
+    public void onResponseComplete() throws IOException
+    {
+        _responseComplete = true;
+
+        if (checkExchangeComplete())
+        {
+            super.onResponseComplete();
+        }
+    }
+
+    public boolean checkExchangeComplete()
+        throws IOException
+    {
+        if (_redirected && _requestComplete && _responseComplete)
+        {
+            if (_location != null)
+            {
+                if (_location.indexOf("://")>0)
+                {
+                    _exchange.setURL(_location);
+                }
+                else
+                {
+                    _exchange.setRequestURI(_location);
+                }
+
+                // destination may have changed
+                boolean isHttps = HttpSchemes.HTTPS.equals(String.valueOf(_exchange.getScheme()));
+                HttpDestination destination=_destination.getHttpClient().getDestination(_exchange.getAddress(),isHttps);
+
+                if (_destination==destination)
+                {
+                    _destination.resend(_exchange);
+                }
+                else
+                {
+                    // unwrap to find ultimate listener.
+                    HttpEventListener listener=this;
+                    while(listener instanceof HttpEventListenerWrapper)
+                    {
+                        listener=((HttpEventListenerWrapper)listener).getEventListener();
+                    }
+                    
+                    //reset the listener
+                    _exchange.getEventListener().onRetry();
+                    _exchange.reset();
+                    _exchange.setEventListener(listener);
+
+                    // Set the new Host header
+                    Address address = _exchange.getAddress();
+                    int port = address.getPort();
+                    StringBuilder hostHeader = new StringBuilder( 64 );
+                    hostHeader.append( address.getHost() );
+                    if( !( ( port == 80 && !isHttps ) || ( port == 443 && isHttps ) ) ) 
+                    {
+                        hostHeader.append( ':' );
+                        hostHeader.append( port );
+                    }
+                    
+                    _exchange.setRequestHeader( HttpHeaders.HOST, hostHeader.toString() );
+
+                    destination.send(_exchange);
+                }
+
+                return false;
+            }
+            else
+            {
+                setDelegationResult(false);
+            }
+        }
+
+        return true;
+    }
+
+    public void onRetry()
+    {
+        _redirected=false;
+        _attempts++;
+
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+
+        _requestComplete=false;
+        _responseComplete=false;
+
+        super.onRetry();
+    }
+
+    /**
+     * Delegate failed connection
+     */
+    @Override
+    public void onConnectionFailed( Throwable ex )
+    {
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+
+        super.onConnectionFailed( ex );
+    }
+
+    /**
+     * Delegate onException
+     */
+    @Override
+    public void onException( Throwable ex )
+    {
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+
+        super.onException( ex );
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/SelectConnector.java b/src/java/org/eclipse/jetty/client/SelectConnector.java
new file mode 100644
index 0000000..4884221
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/SelectConnector.java
@@ -0,0 +1,449 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.UnresolvedAddressException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.net.ssl.SSLEngine;
+
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.io.nio.SslConnection;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.Timeout;
+import org.eclipse.jetty.util.thread.Timeout.Task;
+
+class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector, Dumpable
+{
+    private static final Logger LOG = Log.getLogger(SelectConnector.class);
+
+    private final HttpClient _httpClient;
+    private final Manager _selectorManager=new Manager();
+    private final Map<SocketChannel, Timeout.Task> _connectingChannels = new ConcurrentHashMap<SocketChannel, Timeout.Task>();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param httpClient the HttpClient this connector is associated to. It is 
+     * added via the {@link #addBean(Object, boolean)} as an unmanaged bean.
+     */
+    SelectConnector(HttpClient httpClient)
+    {
+        _httpClient = httpClient;
+        addBean(_httpClient,false);
+        addBean(_selectorManager,true);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void startConnection( HttpDestination destination )
+        throws IOException
+    {
+        SocketChannel channel = null;
+        try
+        {
+            channel = SocketChannel.open();
+            Address address = destination.isProxied() ? destination.getProxy() : destination.getAddress();
+            channel.socket().setTcpNoDelay(true);
+
+            if (_httpClient.isConnectBlocking())
+            {
+                channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
+                channel.configureBlocking(false);
+                _selectorManager.register( channel, destination );
+            }
+            else
+            {
+                channel.configureBlocking(false);
+                channel.connect(address.toSocketAddress());
+                _selectorManager.register(channel,destination);
+                ConnectTimeout connectTimeout = new ConnectTimeout(channel,destination);
+                _httpClient.schedule(connectTimeout,_httpClient.getConnectTimeout());
+                _connectingChannels.put(channel,connectTimeout);
+            }
+        }
+        catch (UnresolvedAddressException ex)
+        {
+            if (channel != null)
+                channel.close();
+            destination.onConnectionFailed(ex);
+        }
+        catch(IOException ex)
+        {
+            if (channel != null)
+                channel.close();
+            destination.onConnectionFailed(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    class Manager extends SelectorManager
+    {
+        Logger LOG = SelectConnector.LOG;
+
+        @Override
+        public boolean dispatch(Runnable task)
+        {
+            return _httpClient._threadPool.dispatch(task);
+        }
+
+        @Override
+        protected void endPointOpened(SelectChannelEndPoint endpoint)
+        {
+        }
+
+        @Override
+        protected void endPointClosed(SelectChannelEndPoint endpoint)
+        {
+        }
+
+        @Override
+        protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
+        {
+        }
+
+        @Override
+        public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment)
+        {
+            return new AsyncHttpConnection(_httpClient.getRequestBuffers(),_httpClient.getResponseBuffers(),endpoint);
+        }
+
+        @Override
+        protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+        {
+            // We're connected, cancel the connect timeout
+            Timeout.Task connectTimeout = _connectingChannels.remove(channel);
+            if (connectTimeout != null)
+                connectTimeout.cancel();
+            if (LOG.isDebugEnabled())
+                LOG.debug("Channels with connection pending: {}", _connectingChannels.size());
+
+            // key should have destination at this point (will be replaced by endpoint after this call)
+            HttpDestination dest=(HttpDestination)key.attachment();
+
+            SelectChannelEndPoint scep = new SelectChannelEndPoint(channel, selectSet, key, (int)_httpClient.getIdleTimeout());
+            AsyncEndPoint ep = scep;
+
+            if (dest.isSecure())
+            {
+                LOG.debug("secure to {}, proxied={}",channel,dest.isProxied());
+                ep = new UpgradableEndPoint(ep,newSslEngine(dest.getSslContextFactory(), channel));
+            }
+
+            AsyncConnection connection = selectSet.getManager().newConnection(channel,ep, key.attachment());
+            ep.setConnection(connection);
+
+            AbstractHttpConnection httpConnection=(AbstractHttpConnection)connection;
+            httpConnection.setDestination(dest);
+
+            if (dest.isSecure() && !dest.isProxied())
+                ((UpgradableEndPoint)ep).upgrade();
+
+            dest.onNewConnection(httpConnection);
+
+            return scep;
+        }
+
+        private synchronized SSLEngine newSslEngine(SslContextFactory sslContextFactory, SocketChannel channel) throws IOException
+        {
+            SSLEngine sslEngine;
+            if (channel != null)
+            {
+                String peerHost = channel.socket().getInetAddress().getHostAddress();
+                int peerPort = channel.socket().getPort();
+                sslEngine = sslContextFactory.newSslEngine(peerHost, peerPort);
+            }
+            else
+            {
+                sslEngine = sslContextFactory.newSslEngine();
+            }
+            sslEngine.setUseClientMode(true);
+            sslEngine.beginHandshake();
+
+            return sslEngine;
+        }
+
+        /* ------------------------------------------------------------ */
+        /* (non-Javadoc)
+         * @see org.eclipse.io.nio.SelectorManager#connectionFailed(java.nio.channels.SocketChannel, java.lang.Throwable, java.lang.Object)
+         */
+        @Override
+        protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
+        {
+            Timeout.Task connectTimeout = _connectingChannels.remove(channel);
+            if (connectTimeout != null)
+                connectTimeout.cancel();
+
+            if (attachment instanceof HttpDestination)
+                ((HttpDestination)attachment).onConnectionFailed(ex);
+            else
+                super.connectionFailed(channel,ex,attachment);
+        }
+    }
+
+    private class ConnectTimeout extends Timeout.Task
+    {
+        private final SocketChannel channel;
+        private final HttpDestination destination;
+
+        public ConnectTimeout(SocketChannel channel, HttpDestination destination)
+        {
+            this.channel = channel;
+            this.destination = destination;
+        }
+
+        @Override
+        public void expired()
+        {
+            if (channel.isConnectionPending())
+            {
+                LOG.debug("Channel {} timed out while connecting, closing it", channel);
+                close();
+                _connectingChannels.remove(channel);
+                destination.onConnectionFailed(new SocketTimeoutException());
+            }
+        }
+
+        private void close()
+        {
+            try
+            {
+                // This will unregister the channel from the selector
+                channel.close();
+            }
+            catch (IOException x)
+            {
+                LOG.ignore(x);
+            }
+        }
+    }
+
+    public static class UpgradableEndPoint implements AsyncEndPoint
+    {
+        AsyncEndPoint _endp;
+        SSLEngine _engine;
+
+        public UpgradableEndPoint(AsyncEndPoint endp, SSLEngine engine) throws IOException
+        {
+            _engine=engine;
+            _endp=endp;
+        }
+
+        public void upgrade()
+        {
+            AsyncHttpConnection connection = (AsyncHttpConnection)_endp.getConnection();
+
+            SslConnection sslConnection = new SslConnection(_engine,_endp);
+            _endp.setConnection(sslConnection);
+
+            _endp=sslConnection.getSslEndPoint();
+            sslConnection.getSslEndPoint().setConnection(connection);
+
+            LOG.debug("upgrade {} to {} for {}",this,sslConnection,connection);
+        }
+
+
+        public Connection getConnection()
+        {
+            return _endp.getConnection();
+        }
+
+        public void setConnection(Connection connection)
+        {
+            _endp.setConnection(connection);
+        }
+
+        public void shutdownOutput() throws IOException
+        {
+            _endp.shutdownOutput();
+        }
+
+        public void dispatch()
+        {
+            _endp.asyncDispatch();
+        }
+
+        public void asyncDispatch()
+        {
+            _endp.asyncDispatch();
+        }
+
+        public boolean isOutputShutdown()
+        {
+            return _endp.isOutputShutdown();
+        }
+
+        public void shutdownInput() throws IOException
+        {
+            _endp.shutdownInput();
+        }
+
+        public void scheduleWrite()
+        {
+            _endp.scheduleWrite();
+        }
+
+        public boolean isInputShutdown()
+        {
+            return _endp.isInputShutdown();
+        }
+
+        public void close() throws IOException
+        {
+            _endp.close();
+        }
+
+        public int fill(Buffer buffer) throws IOException
+        {
+            return _endp.fill(buffer);
+        }
+
+        public boolean isWritable()
+        {
+            return _endp.isWritable();
+        }
+
+        public boolean hasProgressed()
+        {
+            return _endp.hasProgressed();
+        }
+
+        public int flush(Buffer buffer) throws IOException
+        {
+            return _endp.flush(buffer);
+        }
+
+        public void scheduleTimeout(Task task, long timeoutMs)
+        {
+            _endp.scheduleTimeout(task,timeoutMs);
+        }
+
+        public void cancelTimeout(Task task)
+        {
+            _endp.cancelTimeout(task);
+        }
+
+        public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+        {
+            return _endp.flush(header,buffer,trailer);
+        }
+
+        public String getLocalAddr()
+        {
+            return _endp.getLocalAddr();
+        }
+
+        public String getLocalHost()
+        {
+            return _endp.getLocalHost();
+        }
+
+        public int getLocalPort()
+        {
+            return _endp.getLocalPort();
+        }
+
+        public String getRemoteAddr()
+        {
+            return _endp.getRemoteAddr();
+        }
+
+        public String getRemoteHost()
+        {
+            return _endp.getRemoteHost();
+        }
+
+        public int getRemotePort()
+        {
+            return _endp.getRemotePort();
+        }
+
+        public boolean isBlocking()
+        {
+            return _endp.isBlocking();
+        }
+
+        public boolean blockReadable(long millisecs) throws IOException
+        {
+            return _endp.blockReadable(millisecs);
+        }
+
+        public boolean blockWritable(long millisecs) throws IOException
+        {
+            return _endp.blockWritable(millisecs);
+        }
+
+        public boolean isOpen()
+        {
+            return _endp.isOpen();
+        }
+
+        public Object getTransport()
+        {
+            return _endp.getTransport();
+        }
+
+        public void flush() throws IOException
+        {
+            _endp.flush();
+        }
+
+        public int getMaxIdleTime()
+        {
+            return _endp.getMaxIdleTime();
+        }
+
+        public void setMaxIdleTime(int timeMs) throws IOException
+        {
+            _endp.setMaxIdleTime(timeMs);
+        }
+
+        public void onIdleExpired(long idleForMs)
+        {
+            _endp.onIdleExpired(idleForMs);
+        }
+
+        public void setCheckForIdle(boolean check)
+        {
+            _endp.setCheckForIdle(check);
+        }
+
+        public boolean isCheckForIdle()
+        {
+            return _endp.isCheckForIdle();
+        }
+
+        public String toString()
+        {
+            return "Upgradable:"+_endp.toString();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/SocketConnector.java b/src/java/org/eclipse/jetty/client/SocketConnector.java
new file mode 100644
index 0000000..2058b33
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/SocketConnector.java
@@ -0,0 +1,110 @@
+//
+//  ========================================================================
+//  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.client;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.Socket;
+import javax.net.SocketFactory;
+
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+class SocketConnector extends AbstractLifeCycle implements HttpClient.Connector
+{
+    private static final Logger LOG = Log.getLogger(SocketConnector.class);
+
+    /**
+     *
+     */
+    private final HttpClient _httpClient;
+
+    /**
+     * @param httpClient
+     */
+    SocketConnector(HttpClient httpClient)
+    {
+        _httpClient = httpClient;
+    }
+
+    public void startConnection(final HttpDestination destination) throws IOException
+    {
+        Socket socket= destination.isSecure()
+            ? destination.getSslContextFactory().newSslSocket()
+            : SocketFactory.getDefault().createSocket();
+
+        socket.setSoTimeout(0);
+        socket.setTcpNoDelay(true);
+
+        Address address = destination.isProxied() ? destination.getProxy() : destination.getAddress();
+        socket.connect(address.toSocketAddress(), _httpClient.getConnectTimeout());
+
+        final EndPoint endpoint=new SocketEndPoint(socket);
+
+        final AbstractHttpConnection connection=new BlockingHttpConnection(_httpClient.getRequestBuffers(),_httpClient.getResponseBuffers(),endpoint);
+        connection.setDestination(destination);
+        destination.onNewConnection(connection);
+        _httpClient.getThreadPool().dispatch(new Runnable()
+        {
+            public void run()
+            {
+                try
+                {
+                    Connection con = connection;
+                    while(true)
+                    {
+                        final Connection next = con.handle();
+                        if (next!=con)
+                        {
+                            con=next;
+                            continue;
+                        }
+                        break;
+                    }
+                }
+                catch (IOException e)
+                {
+                    if (e instanceof InterruptedIOException)
+                        LOG.ignore(e);
+                    else
+                    {
+                        LOG.debug(e);
+                        destination.onException(e);
+                    }
+                }
+                finally
+                {
+                    try
+                    {
+                        destination.returnConnection(connection,true);
+                    }
+                    catch (IOException e)
+                    {
+                        LOG.debug(e);
+                    }
+                }
+            }
+        });
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/security/Authentication.java b/src/java/org/eclipse/jetty/client/security/Authentication.java
new file mode 100644
index 0000000..9210296
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/Authentication.java
@@ -0,0 +1,33 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpExchange;
+
+/**
+ * Simple authentication interface that sets required fields on the exchange.
+ */
+public interface Authentication
+{
+    public void setCredentials( HttpExchange exchange) throws IOException;
+}
diff --git a/src/java/org/eclipse/jetty/client/security/BasicAuthentication.java b/src/java/org/eclipse/jetty/client/security/BasicAuthentication.java
new file mode 100644
index 0000000..170932a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/BasicAuthentication.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+
+/**
+ * Sets authentication headers for BASIC authentication challenges
+ * 
+ * 
+ */
+public class BasicAuthentication implements Authentication
+{
+    private Buffer _authorization;
+    
+    public BasicAuthentication(Realm realm) throws IOException
+    {
+        String authenticationString = "Basic " + B64Code.encode( realm.getPrincipal() + ":" + realm.getCredentials(), StringUtil.__ISO_8859_1);
+        _authorization= new ByteArrayBuffer(authenticationString);
+    }
+    
+    /**
+     * BASIC authentication is of the form
+     * 
+     * encoded credentials are of the form: username:password
+     * 
+     * 
+     */
+    public void setCredentials( HttpExchange exchange ) throws IOException
+    {
+        exchange.setRequestHeader( HttpHeaders.AUTHORIZATION_BUFFER, _authorization);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/security/DigestAuthentication.java b/src/java/org/eclipse/jetty/client/security/DigestAuthentication.java
new file mode 100644
index 0000000..059f112
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/DigestAuthentication.java
@@ -0,0 +1,141 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.util.Map;
+
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+
+public class DigestAuthentication implements Authentication
+{
+    private static final String NC = "00000001";
+    Realm securityRealm;
+    Map details;
+    
+    public DigestAuthentication(Realm realm, Map details)
+    {
+        this.securityRealm=realm;
+        this.details=details;
+    }
+    
+
+    public void setCredentials( HttpExchange exchange ) 
+    throws IOException
+    {        
+        StringBuilder buffer = new StringBuilder().append("Digest");
+        
+        buffer.append(" ").append("username").append('=').append('"').append(securityRealm.getPrincipal()).append('"');
+        
+        buffer.append(", ").append("realm").append('=').append('"').append(String.valueOf(details.get("realm"))).append('"');
+        
+        buffer.append(", ").append("nonce").append('=').append('"').append(String.valueOf(details.get("nonce"))).append('"');
+        
+        buffer.append(", ").append("uri").append('=').append('"').append(exchange.getURI()).append('"');
+        
+        buffer.append(", ").append("algorithm").append('=').append(String.valueOf(details.get("algorithm")));
+        
+        String cnonce = newCnonce(exchange, securityRealm, details);
+        
+        buffer.append(", ").append("response").append('=').append('"').append(newResponse(cnonce, 
+                exchange, securityRealm, details)).append('"');
+        
+        buffer.append(", ").append("qop").append('=').append(String.valueOf(details.get("qop")));
+        
+
+        buffer.append(", ").append("nc").append('=').append(NC);
+        
+        buffer.append(", ").append("cnonce").append('=').append('"').append(cnonce).append('"');
+        
+        exchange.setRequestHeader( HttpHeaders.AUTHORIZATION, 
+                new String(buffer.toString().getBytes(StringUtil.__ISO_8859_1)));
+    }
+    
+    protected String newResponse(String cnonce, HttpExchange exchange, Realm securityRealm, Map details)
+    {        
+        try{
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            
+            // calc A1 digest
+            md.update(securityRealm.getPrincipal().getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(String.valueOf(details.get("realm")).getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(securityRealm.getCredentials().getBytes(StringUtil.__ISO_8859_1));
+            byte[] ha1 = md.digest();
+            // calc A2 digest
+            md.reset();
+            md.update(exchange.getMethod().getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(exchange.getURI().getBytes(StringUtil.__ISO_8859_1));
+            byte[] ha2=md.digest();
+            
+            md.update(TypeUtil.toString(ha1,16).getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(String.valueOf(details.get("nonce")).getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(NC.getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(cnonce.getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(String.valueOf(details.get("qop")).getBytes(StringUtil.__ISO_8859_1));
+            md.update((byte)':');
+            md.update(TypeUtil.toString(ha2,16).getBytes(StringUtil.__ISO_8859_1));
+            byte[] digest=md.digest();
+            
+            // check digest
+            return encode(digest);
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }        
+    }
+    
+    protected String newCnonce(HttpExchange exchange, Realm securityRealm, Map details)
+    {
+        try
+        {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] b= md.digest(String.valueOf(System.currentTimeMillis()).getBytes(StringUtil.__ISO_8859_1));            
+            return encode(b);
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    private static String encode(byte[] data)
+    {
+        StringBuilder buffer = new StringBuilder();
+        for (int i=0; i<data.length; i++) 
+        {
+            buffer.append(Integer.toHexString((data[i] & 0xf0) >>> 4));
+            buffer.append(Integer.toHexString(data[i] & 0x0f));
+        }
+        return buffer.toString();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/client/security/HashRealmResolver.java b/src/java/org/eclipse/jetty/client/security/HashRealmResolver.java
new file mode 100644
index 0000000..8d3defc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/HashRealmResolver.java
@@ -0,0 +1,45 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jetty.client.HttpDestination;
+
+public class HashRealmResolver implements RealmResolver
+{
+    private Map<String, Realm>_realmMap;  
+    
+    public void addSecurityRealm( Realm realm )
+    {
+        if (_realmMap == null)
+        {
+            _realmMap = new HashMap<String, Realm>();
+        }
+        _realmMap.put( realm.getId(), realm );
+    }
+    
+    public Realm getRealm( String realmName, HttpDestination destination, String path ) throws IOException
+    {
+        return _realmMap.get( realmName );
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/client/security/ProxyAuthorization.java b/src/java/org/eclipse/jetty/client/security/ProxyAuthorization.java
new file mode 100644
index 0000000..4ad968b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/ProxyAuthorization.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+
+/**
+ * Sets proxy authentication headers for BASIC authentication challenges
+ * 
+ * 
+ */
+public class ProxyAuthorization implements Authentication
+{
+    private Buffer _authorization;
+    
+    public ProxyAuthorization(String username,String password) throws IOException
+    {
+        String authenticationString = "Basic " + B64Code.encode( username + ":" + password, StringUtil.__ISO_8859_1);
+        _authorization= new ByteArrayBuffer(authenticationString);
+    }
+    
+    /**
+     * BASIC proxy authentication is of the form
+     * 
+     * encoded credentials are of the form: username:password
+     * 
+     * 
+     */
+    public void setCredentials( HttpExchange exchange ) throws IOException
+    {
+        exchange.setRequestHeader( HttpHeaders.PROXY_AUTHORIZATION_BUFFER, _authorization);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/security/Realm.java b/src/java/org/eclipse/jetty/client/security/Realm.java
new file mode 100644
index 0000000..493f80e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/Realm.java
@@ -0,0 +1,32 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+/**
+ * Simple security realm interface.
+ */
+public interface Realm
+{
+    public String getId();
+
+    public String getPrincipal();
+
+    public String getCredentials();
+
+}
diff --git a/src/java/org/eclipse/jetty/client/security/RealmResolver.java b/src/java/org/eclipse/jetty/client/security/RealmResolver.java
new file mode 100644
index 0000000..a7fd989
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/RealmResolver.java
@@ -0,0 +1,28 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpDestination;
+
+public interface RealmResolver
+{
+    public Realm getRealm( String realmName, HttpDestination destination, String path ) throws IOException;   
+}
diff --git a/src/java/org/eclipse/jetty/client/security/SecurityListener.java b/src/java/org/eclipse/jetty/client/security/SecurityListener.java
new file mode 100644
index 0000000..d3bd51d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/SecurityListener.java
@@ -0,0 +1,276 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.client.HttpDestination;
+import org.eclipse.jetty.client.HttpEventListenerWrapper;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/**
+ * SecurityListener
+ * 
+ * Allow for insertion of security dialog when performing an
+ * HttpExchange.
+ */
+public class SecurityListener extends HttpEventListenerWrapper
+{
+    private static final Logger LOG = Log.getLogger(SecurityListener.class);
+	
+    private HttpDestination _destination;
+    private HttpExchange _exchange;
+    private boolean _requestComplete;
+    private boolean _responseComplete;  
+    private boolean _needIntercept;
+    
+    private int _attempts = 0; // TODO remember to settle on winning solution
+
+    public SecurityListener(HttpDestination destination, HttpExchange ex)
+    {
+        // Start of sending events through to the wrapped listener
+        // Next decision point is the onResponseStatus
+        super(ex.getEventListener(),true);
+        _destination=destination;
+        _exchange=ex;
+    }
+    
+    
+    /**
+     * scrapes an authentication type from the authString
+     * 
+     * @param authString
+     * @return the authentication type
+     */
+    protected String scrapeAuthenticationType( String authString )
+    {
+        String authType;
+
+        if ( authString.indexOf( " " ) == -1 )
+        {
+            authType = authString.toString().trim();
+        }
+        else
+        {
+            String authResponse = authString.toString();
+            authType = authResponse.substring( 0, authResponse.indexOf( " " ) ).trim();
+        }
+        return authType;
+    }
+    
+    /**
+     * scrapes a set of authentication details from the authString
+     * 
+     * @param authString
+     * @return the authentication details
+     */
+    protected Map<String, String> scrapeAuthenticationDetails( String authString )
+    {
+        Map<String, String> authenticationDetails = new HashMap<String, String>();
+        authString = authString.substring( authString.indexOf( " " ) + 1, authString.length() );
+        StringTokenizer strtok = new StringTokenizer( authString, ",");
+        
+        while ( strtok.hasMoreTokens() )
+        {
+            String token = strtok.nextToken();
+            String[] pair = token.split( "=" );
+            
+            // authentication details ought to come in two parts, if not then just skip
+            if ( pair.length == 2 )
+            {
+                String itemName = pair[0].trim();
+                String itemValue = pair[1].trim();
+                
+                itemValue = StringUtil.unquote( itemValue );
+                
+                authenticationDetails.put( itemName, itemValue );
+            }    
+            else
+            {
+                LOG.debug("SecurityListener: missed scraping authentication details - " + token );
+            }
+        }
+        return authenticationDetails;
+    }
+
+  
+    @Override
+    public void onResponseStatus( Buffer version, int status, Buffer reason )
+        throws IOException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("SecurityListener:Response Status: " + status );
+
+        if ( status == HttpStatus.UNAUTHORIZED_401 && _attempts<_destination.getHttpClient().maxRetries()) 
+        {
+            // Let's absorb events until we have done some retries
+            setDelegatingResponses(false);
+            _needIntercept = true;
+        }
+        else 
+        {
+            setDelegatingResponses(true);
+            setDelegatingRequests(true);
+            _needIntercept = false;
+        }
+        super.onResponseStatus(version,status,reason);
+    }
+
+
+    @Override
+    public void onResponseHeader( Buffer name, Buffer value )
+        throws IOException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug( "SecurityListener:Header: " + name.toString() + " / " + value.toString() );
+        
+        
+        if (!isDelegatingResponses())
+        {
+            int header = HttpHeaders.CACHE.getOrdinal(name);
+            switch (header)
+            {
+                case HttpHeaders.WWW_AUTHENTICATE_ORDINAL:
+
+                    // TODO don't hard code this bit.
+                    String authString = value.toString();
+                    String type = scrapeAuthenticationType( authString );                  
+
+                    // TODO maybe avoid this map creation
+                    Map<String,String> details = scrapeAuthenticationDetails( authString );
+                    String pathSpec="/"; // TODO work out the real path spec
+                    RealmResolver realmResolver = _destination.getHttpClient().getRealmResolver();
+                    
+                    if ( realmResolver == null )
+                    {
+                        break;
+                    }
+                    
+                    Realm realm = realmResolver.getRealm( details.get("realm"), _destination, pathSpec ); // TODO work our realm correctly 
+                    
+                    if ( realm == null )
+                    {
+                        LOG.warn( "Unknown Security Realm: " + details.get("realm") );
+                    }
+                    else if ("digest".equalsIgnoreCase(type))
+                    {
+                        _destination.addAuthorization("/",new DigestAuthentication(realm,details));
+                        
+                    }
+                    else if ("basic".equalsIgnoreCase(type))
+                    {
+                        _destination.addAuthorization(pathSpec,new BasicAuthentication(realm));
+                    }
+                    
+                    break;
+            }
+        }
+        super.onResponseHeader(name,value);
+    }
+    
+
+    @Override
+    public void onRequestComplete() throws IOException
+    {
+        _requestComplete = true;
+
+        if (_needIntercept)
+        {
+            if (_requestComplete && _responseComplete)
+            {
+               if (LOG.isDebugEnabled())
+                   LOG.debug("onRequestComplete, Both complete: Resending from onResponseComplete "+_exchange); 
+                _responseComplete = false;
+                _requestComplete = false;
+                setDelegatingRequests(true);
+                setDelegatingResponses(true);
+                _destination.resend(_exchange);  
+            } 
+            else
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("onRequestComplete, Response not yet complete onRequestComplete, calling super for "+_exchange);
+                super.onRequestComplete(); 
+            }
+        }
+        else
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("onRequestComplete, delegating to super with Request complete="+_requestComplete+", response complete="+_responseComplete+" "+_exchange);
+            super.onRequestComplete();
+        }
+    }
+
+
+    @Override
+    public void onResponseComplete() throws IOException
+    {   
+        _responseComplete = true;
+        if (_needIntercept)
+        {  
+            if (_requestComplete && _responseComplete)
+            {              
+                if (LOG.isDebugEnabled())
+                    LOG.debug("onResponseComplete, Both complete: Resending from onResponseComplete"+_exchange);
+                _responseComplete = false;
+                _requestComplete = false;
+                setDelegatingResponses(true);
+                setDelegatingRequests(true);
+                _destination.resend(_exchange); 
+
+            }
+            else
+            {
+               if (LOG.isDebugEnabled())
+                   LOG.debug("onResponseComplete, Request not yet complete from onResponseComplete,  calling super "+_exchange);
+                super.onResponseComplete(); 
+            }
+        }
+        else
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("OnResponseComplete, delegating to super with Request complete="+_requestComplete+", response complete="+_responseComplete+" "+_exchange);
+            super.onResponseComplete();  
+        }
+    }
+
+    @Override
+    public void onRetry()
+    {
+        _attempts++;
+        setDelegatingRequests(true);
+        setDelegatingResponses(true);
+        _requestComplete=false;
+        _responseComplete=false;
+        _needIntercept=false;
+        super.onRetry();
+    }  
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java b/src/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java
new file mode 100644
index 0000000..dca12d6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/security/SimpleRealmResolver.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.client.security;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpDestination;
+
+/**
+ * Simple Realm Resolver.
+ * <p> A Realm Resolver that wraps a single realm.
+ * 
+ *
+ */
+public class SimpleRealmResolver implements RealmResolver
+{
+    private Realm _realm;
+    
+    public SimpleRealmResolver( Realm realm )
+    {
+        _realm=realm;
+    }
+    
+    public Realm getRealm( String realmName, HttpDestination destination, String path ) throws IOException
+    {
+        return _realm;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/webdav/MkcolExchange.java b/src/java/org/eclipse/jetty/client/webdav/MkcolExchange.java
new file mode 100644
index 0000000..2f473a4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/webdav/MkcolExchange.java
@@ -0,0 +1,64 @@
+//
+//  ========================================================================
+//  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.client.webdav;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.CachedExchange;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+public class MkcolExchange extends CachedExchange
+{
+    private static final Logger LOG = Log.getLogger(MkcolExchange.class);
+
+    boolean exists = false;
+
+    public MkcolExchange()
+    {
+        super(true);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        if ( status == HttpStatus.CREATED_201 )
+        {
+            LOG.debug( "MkcolExchange:Status: Successfully created resource" );
+            exists = true;
+        }
+
+        if ( status == HttpStatus.METHOD_NOT_ALLOWED_405 ) // returned when resource exists
+        {
+            LOG.debug( "MkcolExchange:Status: Resource must exist" );
+            exists = true;
+        }
+
+        super.onResponseStatus(version, status, reason);
+    }
+
+    public boolean exists()
+    {
+        return exists;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/webdav/PropfindExchange.java b/src/java/org/eclipse/jetty/client/webdav/PropfindExchange.java
new file mode 100644
index 0000000..78c913f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/webdav/PropfindExchange.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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.client.webdav;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+public class PropfindExchange extends HttpExchange
+{
+    private static final Logger LOG = Log.getLogger(PropfindExchange.class);
+
+    boolean _propertyExists = false;
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        if ( status == HttpStatus.OK_200 )
+        {
+            LOG.debug( "PropfindExchange:Status: Exists" );
+            _propertyExists = true;
+        }
+        else
+        {
+            LOG.debug( "PropfindExchange:Status: Not Exists" );
+        }
+
+        super.onResponseStatus(version, status, reason);
+    }
+
+    public boolean exists()
+    {
+        return _propertyExists;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/client/webdav/WebdavListener.java b/src/java/org/eclipse/jetty/client/webdav/WebdavListener.java
new file mode 100644
index 0000000..8797f31
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/webdav/WebdavListener.java
@@ -0,0 +1,332 @@
+//
+//  ========================================================================
+//  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.client.webdav;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpDestination;
+import org.eclipse.jetty.client.HttpEventListenerWrapper;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.client.security.SecurityListener;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * WebdavListener
+ * 
+ * 
+ * 
+ * 
+ */
+public class WebdavListener extends HttpEventListenerWrapper
+{
+    private static final Logger LOG = Log.getLogger(WebdavListener.class);
+
+    private HttpDestination _destination;
+    private HttpExchange _exchange;
+    private boolean _requestComplete;
+    private boolean _responseComplete; 
+    private boolean _webdavEnabled;
+    private boolean _needIntercept;
+
+    public WebdavListener(HttpDestination destination, HttpExchange ex)
+    {
+        // Start of sending events through to the wrapped listener
+        // Next decision point is the onResponseStatus
+        super(ex.getEventListener(),true);
+        _destination=destination;
+        _exchange=ex;
+
+        // We'll only enable webdav if this is a PUT request
+        if ( HttpMethods.PUT.equalsIgnoreCase( _exchange.getMethod() ) )
+        {
+            _webdavEnabled = true;
+        }
+    }
+
+    @Override
+    public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+    {
+        if ( !_webdavEnabled )
+        {
+            _needIntercept = false;
+            super.onResponseStatus(version, status, reason);
+            return;
+        }
+        
+        if (LOG.isDebugEnabled())
+            LOG.debug("WebdavListener:Response Status: " + status );
+
+        // The dav spec says that CONFLICT should be returned when the parent collection doesn't exist but I am seeing
+        // FORBIDDEN returned instead so running with that.
+        if ( status == HttpStatus.FORBIDDEN_403 || status == HttpStatus.CONFLICT_409 )
+        {
+            if ( _webdavEnabled )
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("WebdavListener:Response Status: dav enabled, taking a stab at resolving put issue" );
+                setDelegatingResponses( false ); // stop delegating, we can try and fix this request
+                _needIntercept = true;
+            }
+            else
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("WebdavListener:Response Status: Webdav Disabled" );
+                setDelegatingResponses( true ); // just make sure we delegate
+                setDelegatingRequests( true );
+                _needIntercept = false;
+            }
+        }
+        else
+        {
+            _needIntercept = false;
+            setDelegatingResponses( true );
+            setDelegatingRequests( true );
+        }
+
+        super.onResponseStatus(version, status, reason);
+    }
+
+    @Override
+    public void onResponseComplete() throws IOException
+    {
+        _responseComplete = true;
+        if (_needIntercept)
+        {
+            if ( _requestComplete && _responseComplete)
+            {
+                try
+                {
+                    // we have some work to do before retrying this
+                    if ( resolveCollectionIssues() )
+                    {
+                        setDelegatingRequests( true );
+                        setDelegatingResponses(true);
+                        _requestComplete = false;
+                        _responseComplete = false;
+                        _destination.resend(_exchange);
+                    }
+                    else
+                    {
+                        // admit defeat but retry because someone else might have 
+                        setDelegationResult(false);
+                        setDelegatingRequests( true );
+                        setDelegatingResponses(true);
+                        super.onResponseComplete();
+                    }
+                }
+                catch ( IOException ioe )
+                {
+                    LOG.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
+                    super.onResponseComplete();
+                }
+            }
+            else
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("WebdavListener:Not ready, calling super");
+                super.onResponseComplete();
+            }
+        }
+        else
+        {
+            super.onResponseComplete();
+        }
+    }
+
+    
+    
+    @Override
+    public void onRequestComplete () throws IOException
+    {
+        _requestComplete = true;
+        if (_needIntercept)
+        {
+            if ( _requestComplete && _responseComplete)
+            {
+                try
+                {
+                    // we have some work to do before retrying this
+                    if ( resolveCollectionIssues() )
+                    {
+                        setDelegatingRequests( true );
+                        setDelegatingResponses(true);
+                        _requestComplete = false;
+                        _responseComplete = false;
+                        _destination.resend(_exchange);
+                    }
+                    else
+                    {
+                        // admit defeat but retry because someone else might have 
+                        setDelegatingRequests( true );
+                        setDelegatingResponses(true);
+                        super.onRequestComplete();
+                    }
+                }
+                catch ( IOException ioe )
+                {
+                    LOG.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
+                    super.onRequestComplete();
+                }
+            }
+            else
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("WebdavListener:Not ready, calling super");
+                super.onRequestComplete();
+            }
+        }
+        else
+        {
+            super.onRequestComplete();
+        } 
+    }
+
+   
+    
+    
+    /**
+     * walk through the steps to try and resolve missing parent collection issues via webdav
+     *
+     * TODO this really ought to use URI itself for this resolution
+     *
+     * @return
+     * @throws IOException
+     */
+    private boolean resolveCollectionIssues() throws IOException
+    {
+
+        String uri = _exchange.getURI();
+        String[] uriCollection = _exchange.getURI().split("/");
+        int checkNum = uriCollection.length;
+        int rewind = 0;
+
+        String parentUri = URIUtil.parentPath( uri );
+        while ( parentUri != null && !checkExists(parentUri) )
+        {
+            ++rewind;
+            parentUri = URIUtil.parentPath( parentUri );
+        }
+
+        // confirm webdav is supported for this collection
+        if ( checkWebdavSupported() )
+        {
+            for (int i = 0; i < rewind;)
+            {
+                makeCollection(parentUri + "/" + uriCollection[checkNum - rewind - 1]);
+                parentUri = parentUri + "/" + uriCollection[checkNum - rewind - 1];
+                --rewind;
+            }
+        }
+        else
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean checkExists( String uri ) throws IOException
+    {
+        if (uri == null)
+        {
+            System.out.println("have failed miserably");
+            return false;
+        }
+        
+        PropfindExchange propfindExchange = new PropfindExchange();
+        propfindExchange.setAddress( _exchange.getAddress() );
+        propfindExchange.setMethod( HttpMethods.GET ); // PROPFIND acts wonky, just use get
+        propfindExchange.setScheme( _exchange.getScheme() );
+        propfindExchange.setEventListener( new SecurityListener( _destination, propfindExchange ) );
+        propfindExchange.setConfigureListeners( false );
+        propfindExchange.setRequestURI( uri );
+
+        _destination.send( propfindExchange );
+
+        try
+        {
+            propfindExchange.waitForDone();
+
+            return propfindExchange.exists();
+        }
+        catch ( InterruptedException ie )
+        {
+            LOG.ignore( ie );                  
+            return false;
+        }
+    }
+
+    private boolean makeCollection( String uri ) throws IOException
+    {
+        MkcolExchange mkcolExchange = new MkcolExchange();
+        mkcolExchange.setAddress( _exchange.getAddress() );
+        mkcolExchange.setMethod( "MKCOL " + uri + " HTTP/1.1" );
+        mkcolExchange.setScheme( _exchange.getScheme() );
+        mkcolExchange.setEventListener( new SecurityListener( _destination, mkcolExchange ) );
+        mkcolExchange.setConfigureListeners( false );
+        mkcolExchange.setRequestURI( uri );
+
+        _destination.send( mkcolExchange );
+
+        try
+        {
+            mkcolExchange.waitForDone();
+
+            return mkcolExchange.exists();
+        }
+        catch ( InterruptedException ie )
+        {
+            LOG.ignore( ie );
+            return false;
+        }
+    }
+
+    
+    private boolean checkWebdavSupported() throws IOException
+    {
+        WebdavSupportedExchange supportedExchange = new WebdavSupportedExchange();
+        supportedExchange.setAddress( _exchange.getAddress() );
+        supportedExchange.setMethod( HttpMethods.OPTIONS );
+        supportedExchange.setScheme( _exchange.getScheme() );
+        supportedExchange.setEventListener( new SecurityListener( _destination, supportedExchange ) );
+        supportedExchange.setConfigureListeners( false );
+        supportedExchange.setRequestURI( _exchange.getURI() );
+
+        _destination.send( supportedExchange );
+
+        try
+        {
+            supportedExchange.waitTilCompletion();
+            return supportedExchange.isWebdavSupported();
+        }
+        catch (InterruptedException ie )
+        {            
+            LOG.ignore( ie );
+            return false;
+        }
+
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java b/src/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java
new file mode 100644
index 0000000..7b4c237
--- /dev/null
+++ b/src/java/org/eclipse/jetty/client/webdav/WebdavSupportedExchange.java
@@ -0,0 +1,75 @@
+//
+//  ========================================================================
+//  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.client.webdav;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+public class WebdavSupportedExchange extends HttpExchange
+{
+    private static final Logger LOG = Log.getLogger(WebdavSupportedExchange.class);
+
+    private boolean _webdavSupported = false;
+    private boolean _isComplete = false;
+
+    @Override
+    protected void onResponseHeader(Buffer name, Buffer value) throws IOException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("WebdavSupportedExchange:Header:" + name.toString() + " / " + value.toString() );
+        if ( "DAV".equals( name.toString() ) )
+        {
+            if ( value.toString().indexOf( "1" ) >= 0 || value.toString().indexOf( "2" ) >= 0 )
+            {
+                _webdavSupported = true;
+            }
+        }
+
+        super.onResponseHeader(name, value);
+    }
+
+    public void waitTilCompletion() throws InterruptedException
+    {
+        synchronized (this)
+        {
+            while ( !_isComplete)
+            {
+                this.wait();
+            }
+        }
+    }
+
+    @Override
+    protected void onResponseComplete() throws IOException
+    {
+        _isComplete = true;
+
+        super.onResponseComplete();
+    }
+
+    public boolean isWebdavSupported()
+    {
+        return _webdavSupported;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/continuation/Continuation.java b/src/java/org/eclipse/jetty/continuation/Continuation.java
new file mode 100644
index 0000000..0eb8ca0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/Continuation.java
@@ -0,0 +1,420 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.Servlet;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+/* ------------------------------------------------------------ */
+/**
+ * Continuation.
+ * 
+ * A continuation is a mechanism by which a HTTP Request can be suspended and
+ * restarted after a timeout or an asynchronous event has occurred.
+ * <p>
+ * The continuation mechanism is a portable mechanism that will work 
+ * asynchronously without additional configuration of all jetty-7, 
+ * jetty-8 and Servlet 3.0 containers.   With the addition of 
+ * the {@link ContinuationFilter}, the mechanism will also work
+ * asynchronously on jetty-6 and non-asynchronously on any 
+ * servlet 2.5 container.
+ * <p>
+ * The Continuation API is a simplification of the richer async API
+ * provided by the servlet-3.0 and an enhancement of the continuation
+ * API that was introduced with jetty-6. 
+ * </p>
+ * <h1>Continuation Usage</h1>
+ * <p>
+ * A continuation object is obtained for a request by calling the 
+ * factory method {@link ContinuationSupport#getContinuation(ServletRequest)}.
+ * The continuation type returned will depend on the servlet container
+ * being used.
+ * </p> 
+ * <p>
+ * There are two distinct style of operation of the continuation API.
+ * </p>
+ * <h3>Suspend/Resume Usage</h3> 
+ * <p>The suspend/resume style is used when a servlet and/or
+ * filter is used to generate the response after a asynchronous wait that is
+ * terminated by an asynchronous handler.
+ * </p>
+ * <pre>
+ * <b>Filter/Servlet:</b>
+ *   // if we need to get asynchronous results
+ *   Object results = request.getAttribute("results);
+ *   if (results==null)
+ *   {
+ *     Continuation continuation = ContinuationSupport.getContinuation(request);
+ *     continuation.suspend();
+ *     myAsyncHandler.register(continuation);
+ *     return; // or continuation.undispatch();
+ *   }
+ * 
+ * async wait ...
+ * 
+ * <b>Async Handler:</b>
+ *   // when the waited for event happens
+ *   continuation.setAttribute("results",event);
+ *   continuation.resume();
+ *   
+ * <b>Filter/Servlet:</b>
+ *   // when the request is redispatched 
+ *   if (results==null)
+ *   {
+ *     ... // see above
+ *   }
+ *   else
+ *   {
+ *     response.getOutputStream().write(process(results));
+ *   }
+ * </pre> 
+ * <h3>Suspend/Complete Usage</h3> 
+ * <p>
+ * The suspend/complete style is used when an asynchronous handler is used to 
+ * generate the response:
+ * </p>
+ * <pre>
+ * <b>Filter/Servlet:</b>
+ *   // when we want to enter asynchronous mode
+ *   Continuation continuation = ContinuationSupport.getContinuation(request);
+ *   continuation.suspend(response); // response may be wrapped
+ *   myAsyncHandler.register(continuation);
+ *   return; // or continuation.undispatch();
+ *
+ * <b>Wrapping Filter:</b>
+ *   // any filter that had wrapped the response should be implemented like:
+ *   try
+ *   {
+ *     chain.doFilter(request,wrappedResponse);
+ *   }
+ *   finally
+ *   {
+ *     if (!continuation.isResponseWrapped())
+ *       wrappedResponse.finish()
+ *     else
+ *       continuation.addContinuationListener(myCompleteListener)
+ *   }
+ *
+ * async wait ...
+ *
+ * <b>Async Handler:</b>
+ *   // when the async event happens
+ *   continuation.getServletResponse().getOutputStream().write(process(event));
+ *   continuation.complete()
+ * </pre>
+ * 
+ * <h1>Continuation Timeout</h1>
+ * <p>
+ * If a continuation is suspended, but neither {@link #complete()} or {@link #resume()} is
+ * called during the period set by {@link #setTimeout(long)}, then the continuation will
+ * expire and {@link #isExpired()} will return true. 
+ * </p>
+ * <p>
+ * When a continuation expires, the {@link ContinuationListener#onTimeout(Continuation)}
+ * method is called on any {@link ContinuationListener} that has been registered via the
+ * {@link #addContinuationListener(ContinuationListener)} method. The onTimeout handlers 
+ * may write a response and call {@link #complete()}. If {@link #complete()} is not called, 
+ * then the container will redispatch the request as if {@link #resume()} had been called,
+ * except that {@link #isExpired()} will be true and {@link #isResumed()} will be false.
+ * </p>
+ * 
+ * @see ContinuationSupport
+ * @see ContinuationListener
+ * 
+ */
+public interface Continuation
+{
+    public final static String ATTRIBUTE = "org.eclipse.jetty.continuation";
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the continuation timeout.
+     * 
+     * @param timeoutMs
+     *            The time in milliseconds to wait before expiring this
+     *            continuation after a call to {@link #suspend()} or {@link #suspend(ServletResponse)}.
+     *            A timeout of <=0 means the continuation will never expire.
+     */
+    void setTimeout(long timeoutMs);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Suspend the processing of the request and associated
+     * {@link ServletResponse}.
+     * 
+     * <p>
+     * After this method has been called, the lifecycle of the request will be
+     * extended beyond the return to the container from the
+     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
+     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
+     * calls. When a suspended request is returned to the container after
+     * a dispatch, then the container will not commit the associated response
+     * (unless an exception other than {@link ContinuationThrowable} is thrown).
+     * </p>
+     * 
+     * <p>
+     * When the thread calling the filter chain and/or servlet has returned to
+     * the container with a suspended request, the thread is freed for other
+     * tasks and the request is held until either:
+     * <ul>
+     * <li>a call to {@link #resume()}.</li>
+     * <li>a call to {@link #complete()}.</li>
+     * <li>the timeout expires.</li>
+     * </ul>
+     * <p>
+     * Typically suspend with no arguments is uses when a call to {@link #resume()}
+     * is expected. If a call to {@link #complete()} is expected, then the 
+     * {@link #suspend(ServletResponse)} method should be used instead of this method.
+     * </p>
+     * 
+     * @exception IllegalStateException
+     *                If the request cannot be suspended
+     */
+    void suspend();
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Suspend the processing of the request and associated
+     * {@link ServletResponse}.
+     * 
+     * <p>
+     * After this method has been called, the lifecycle of the request will be
+     * extended beyond the return to the container from the
+     * {@link Servlet#service(ServletRequest, ServletResponse)} method and
+     * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}
+     * calls. When a suspended request is returned to the container after
+     * a dispatch, then the container will not commit the associated response
+     * (unless an exception other than {@link ContinuationThrowable} is thrown).
+     * </p>
+     * <p>
+     * When the thread calling the filter chain and/or servlet has returned to
+     * the container with a suspended request, the thread is freed for other
+     * tasks and the request is held until either:
+     * <ul>
+     * <li>a call to {@link #resume()}.</li>
+     * <li>a call to {@link #complete()}.</li>
+     * <li>the timeout expires.</li>
+     * </ul>
+     * <p>
+     * Typically suspend with a response argument is uses when a call to {@link #complete()}
+     * is expected. If a call to {@link #resume()} is expected, then the 
+     * {@link #suspend()} method should be used instead of this method.
+     * </p>
+     * <p>
+     * Filters that may wrap the response object should check {@link #isResponseWrapped()}
+     * to decide if they should destroy/finish the wrapper. If {@link #isResponseWrapped()}
+     * returns true, then the wrapped request has been passed to the asynchronous
+     * handler and the wrapper should not be destroyed/finished until after a call to 
+     * {@link #complete()} (potentially using a {@link ContinuationListener#onComplete(Continuation)}
+     * listener).
+     * 
+     * @param response The response to return via a call to {@link #getServletResponse()}
+     * @exception IllegalStateException
+     *                If the request cannot be suspended
+     */
+    void suspend(ServletResponse response);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Resume a suspended request.
+     * 
+     * <p>
+     * This method can be called by any thread that has been passed a reference
+     * to a continuation. When called the request is redispatched to the
+     * normal filter chain and servlet processing with {@link #isInitial()} false.
+     * </p>
+     * <p>
+     * If resume is called before a suspended request is returned to the
+     * container (ie the thread that called {@link #suspend()} is still
+     * within the filter chain and/or servlet service method), then the resume
+     * does not take effect until the call to the filter chain and/or servlet
+     * returns to the container. In this case both {@link #isSuspended()} and
+     * {@link #isResumed()} return true. Multiple calls to resume are ignored.
+     * </p>
+     * <p>
+     * Typically resume() is used after a call to {@link #suspend()} with
+     * no arguments. The dispatch after a resume call will use the original
+     * request and response objects, even if {@link #suspend(ServletResponse)} 
+     * had been passed a wrapped response.
+     * </p>
+     * 
+     * @see #suspend()
+     * @exception IllegalStateException if the request is not suspended.
+     * 
+     */
+    void resume();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Complete a suspended request.
+     * 
+     * <p>
+     * This method can be called by any thread that has been passed a reference
+     * to a suspended request. When a request is completed, the associated
+     * response object committed and flushed. The request is not redispatched.
+     * </p>
+     * 
+     * <p>
+     * If complete is called before a suspended request is returned to the
+     * container (ie the thread that called {@link #suspend()} is still
+     * within the filter chain and/or servlet service method), then the complete
+     * does not take effect until the call to the filter chain and/or servlet
+     * returns to the container. In this case both {@link #isSuspended()} and
+     * {@link #isResumed()} return true.
+     * </p>
+     * 
+     * <p>
+     * Typically resume() is used after a call to {@link #suspend(ServletResponse)} with
+     * a possibly wrapped response. The async handler should use the response
+     * provided by {@link #getServletResponse()} to write the response before
+     * calling {@link #complete()}. If the request was suspended with a 
+     * call to {@link #suspend()} then no response object will be available via
+     * {@link #getServletResponse()}.
+     * </p>
+     * 
+     * <p>
+     * Once complete has been called and any thread calling the filter chain
+     * and/or servlet chain has returned to the container, the request lifecycle
+     * is complete. The container is able to recycle request objects, so it is
+     * not valid hold a request or continuation reference after the end of the 
+     * life cycle.
+     * 
+     * @see #suspend()
+     * @exception IllegalStateException
+     *                if the request is not suspended.
+     * 
+     */
+    void complete();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true after {@link #suspend()} has been called and before the
+     *         request has been redispatched due to being resumed, completed or
+     *         timed out.
+     */
+    boolean isSuspended();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the request has been redispatched by a call to
+     *         {@link #resume()}. Returns false after any subsequent call to
+     *         suspend
+     */
+    boolean isResumed();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true after a request has been redispatched as the result of a
+     *         timeout. Returns false after any subsequent call to suspend.
+     */
+    boolean isExpired();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true while the request is within the initial dispatch to the
+     *         filter chain and/or servlet. Will return false once the calling
+     *         thread has returned to the container after suspend has been
+     *         called and during any subsequent redispatch.
+     */
+    boolean isInitial();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Is the suspended response wrapped.
+     * <p>
+     * Filters that wrap the response object should check this method to 
+     * determine if they should destroy/finish the wrapped response. If 
+     * the request was suspended with a call to {@link #suspend(ServletResponse)}
+     * that passed the wrapped response, then the filter should register
+     * a {@link ContinuationListener} to destroy/finish the wrapped response
+     * during a call to {@link ContinuationListener#onComplete(Continuation)}.
+     * @return True if {@link #suspend(ServletResponse)} has been passed a
+     * {@link ServletResponseWrapper} instance.
+     */
+    boolean isResponseWrapped();
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the suspended response.
+     * @return the {@link ServletResponse} passed to {@link #suspend(ServletResponse)}.
+     */
+    ServletResponse getServletResponse();
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * Add a ContinuationListener.
+     * 
+     * @param listener
+     */
+    void addContinuationListener(ContinuationListener listener);
+    
+    /* ------------------------------------------------------------ */
+    /** Set a request attribute.
+     * This method is a convenience method to call the {@link ServletRequest#setAttribute(String, Object)}
+     * method on the associated request object.
+     * This is a thread safe call and may be called by any thread.
+     * @param name the attribute name
+     * @param attribute the attribute value
+     */
+    public void setAttribute(String name, Object attribute);
+    
+    /* ------------------------------------------------------------ */
+    /** Get a request attribute.
+     * This method is a convenience method to call the {@link ServletRequest#getAttribute(String)}
+     * method on the associated request object.
+     * This is a thread safe call and may be called by any thread.
+     * @param name the attribute name
+     * @return the attribute value
+     */
+    public Object getAttribute(String name);
+    
+    /* ------------------------------------------------------------ */
+    /** Remove a request attribute.
+     * This method is a convenience method to call the {@link ServletRequest#removeAttribute(String)}
+     * method on the associated request object.
+     * This is a thread safe call and may be called by any thread.
+     * @param name the attribute name
+     */
+    public void removeAttribute(String name);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Undispatch the request.
+     * <p>
+     * This method can be called on a suspended continuation in order
+     * to exit the dispatch to the filter/servlet by throwing a {@link ContinuationThrowable}
+     * which is caught either by the container or the {@link ContinuationFilter}.
+     * This is an alternative to simply returning from the dispatch in the case
+     * where filters in the filter chain may not be prepared to handle a suspended
+     * request.
+     * </p>
+     * This method should only be used as a last resort and a normal return is a prefereable
+     * solution if filters can be updated to handle that case.
+     * 
+     * @throws ContinuationThrowable thrown if the request is suspended. The instance of the 
+     * exception may be reused on subsequent calls, so the stack frame may not be accurate.
+     */
+    public void undispatch() throws ContinuationThrowable;
+}
diff --git a/src/java/org/eclipse/jetty/continuation/ContinuationFilter.java b/src/java/org/eclipse/jetty/continuation/ContinuationFilter.java
new file mode 100644
index 0000000..2500463
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/ContinuationFilter.java
@@ -0,0 +1,174 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * <p>ContinuationFilter must be applied to servlet paths that make use of
+ * the asynchronous features provided by {@link Continuation} APIs, but that
+ * are deployed in servlet containers that are neither Jetty (>= 7) nor a
+ * compliant Servlet 3.0 container.</p>
+ * <p>The following init parameters may be used to configure the filter (these are mostly for testing):</p>
+ * <dl>
+ * <dt>debug</dt><dd>Boolean controlling debug output</dd>
+ * <dt>jetty6</dt><dd>Boolean to force use of Jetty 6 continuations</dd>
+ * <dt>faux</dt><dd>Boolean to force use of faux continuations</dd>
+ * </dl>
+ * <p>If the servlet container is not Jetty (either 6 or 7) nor a Servlet 3
+ * container, then "faux" continuations will be used.</p>
+ * <p>Faux continuations will just put the thread that called {@link Continuation#suspend()}
+ * in wait, and will notify that thread when {@link Continuation#resume()} or
+ * {@link Continuation#complete()} is called.</p>
+ * <p>Faux continuations are not threadless continuations (they are "faux" - fake - for this reason)
+ * and as such they will scale less than proper continuations.</p>
+ */
+public class ContinuationFilter implements Filter
+{
+    static boolean _initialized;
+    static boolean __debug; // shared debug status
+    private boolean _faux;
+    private boolean _jetty6;
+    private boolean _filtered;
+    ServletContext _context;
+    private boolean _debug;
+
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        boolean jetty_7_or_greater="org.eclipse.jetty.servlet".equals(filterConfig.getClass().getPackage().getName());
+        _context = filterConfig.getServletContext();
+
+        String param=filterConfig.getInitParameter("debug");
+        _debug=param!=null&&Boolean.parseBoolean(param);
+        if (_debug)
+            __debug=true;
+
+        param=filterConfig.getInitParameter("jetty6");
+        if (param==null)
+            param=filterConfig.getInitParameter("partial");
+        if (param!=null)
+            _jetty6=Boolean.parseBoolean(param);
+        else
+            _jetty6=ContinuationSupport.__jetty6 && !jetty_7_or_greater;
+
+        param=filterConfig.getInitParameter("faux");
+        if (param!=null)
+            _faux=Boolean.parseBoolean(param);
+        else
+            _faux=!(jetty_7_or_greater || _jetty6 || _context.getMajorVersion()>=3);
+
+        _filtered=_faux||_jetty6;
+        if (_debug)
+            _context.log("ContinuationFilter "+
+                    " jetty="+jetty_7_or_greater+
+                    " jetty6="+_jetty6+
+                    " faux="+_faux+
+                    " filtered="+_filtered+
+                    " servlet3="+ContinuationSupport.__servlet3);
+        _initialized=true;
+    }
+
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+    {
+        if (_filtered)
+        {
+            Continuation c = (Continuation) request.getAttribute(Continuation.ATTRIBUTE);
+            FilteredContinuation fc;
+            if (_faux && (c==null || !(c instanceof FauxContinuation)))
+            {
+                fc = new FauxContinuation(request);
+                request.setAttribute(Continuation.ATTRIBUTE,fc);
+            }
+            else
+                fc=(FilteredContinuation)c;
+
+            boolean complete=false;
+            while (!complete)
+            {
+                try
+                {
+                    if (fc==null || (fc).enter(response))
+                        chain.doFilter(request,response);
+                }
+                catch (ContinuationThrowable e)
+                {
+                    debug("faux",e);
+                }
+                finally
+                {
+                    if (fc==null)
+                        fc = (FilteredContinuation) request.getAttribute(Continuation.ATTRIBUTE);
+
+                    complete=fc==null || (fc).exit();
+                }
+            }
+        }
+        else
+        {
+            try
+            {
+                chain.doFilter(request,response);
+            }
+            catch (ContinuationThrowable e)
+            {
+                debug("caught",e);
+            }
+        }
+    }
+
+    private void debug(String string)
+    {
+        if (_debug)
+        {
+            _context.log(string);
+        }
+    }
+
+    private void debug(String string, Throwable th)
+    {
+        if (_debug)
+        {
+            if (th instanceof ContinuationThrowable)
+                _context.log(string+":"+th);
+            else
+                _context.log(string,th);
+        }
+    }
+
+    public void destroy()
+    {
+    }
+
+    public interface FilteredContinuation extends Continuation
+    {
+        boolean enter(ServletResponse response);
+        boolean exit();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/continuation/ContinuationListener.java b/src/java/org/eclipse/jetty/continuation/ContinuationListener.java
new file mode 100644
index 0000000..e4e9ca1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/ContinuationListener.java
@@ -0,0 +1,55 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.util.EventListener;
+
+import javax.servlet.ServletRequestListener;
+
+
+/* ------------------------------------------------------------ */
+/** A Continuation Listener
+ * <p>
+ * A ContinuationListener may be registered with a call to
+ * {@link Continuation#addContinuationListener(ContinuationListener)}.
+ * 
+ */
+public interface ContinuationListener extends EventListener 
+{    
+    /* ------------------------------------------------------------ */
+    /**
+     * Called when a continuation life cycle is complete and after
+     * any calls to {@link ServletRequestListener#requestDestroyed(javax.servlet.ServletRequestEvent)}
+     * The response may still be written to during the call.
+     * 
+     * @param continuation
+     */
+    public void onComplete(Continuation continuation);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Called when a suspended continuation has timed out.
+     * The response may be written to and the methods 
+     * {@link Continuation#resume()} or {@link Continuation#complete()} 
+     * may be called by a onTimeout implementation,
+     * @param continuation
+     */
+    public void onTimeout(Continuation continuation);
+
+}
diff --git a/src/java/org/eclipse/jetty/continuation/ContinuationSupport.java b/src/java/org/eclipse/jetty/continuation/ContinuationSupport.java
new file mode 100644
index 0000000..b4c6210
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/ContinuationSupport.java
@@ -0,0 +1,164 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.lang.reflect.Constructor;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.ServletResponse;
+
+/* ------------------------------------------------------------ */
+/** ContinuationSupport.
+ *
+ * Factory class for accessing Continuation instances, which with either be
+ * native to the container (jetty >= 6), a servlet 3.0 or a faux continuation.
+ *
+ */
+public class ContinuationSupport
+{
+    static final boolean __jetty6;
+    static final boolean __servlet3;
+    static final Class<?> __waitingContinuation;
+    static final Constructor<? extends Continuation> __newServlet3Continuation;
+    static final Constructor<? extends Continuation> __newJetty6Continuation;
+    static
+    {
+        boolean servlet3Support=false;
+        Constructor<? extends Continuation>s3cc=null;
+        try
+        {
+            boolean servlet3=ServletRequest.class.getMethod("startAsync")!=null;
+            if (servlet3)
+            {
+                Class<? extends Continuation> s3c = ContinuationSupport.class.getClassLoader().loadClass("org.eclipse.jetty.continuation.Servlet3Continuation").asSubclass(Continuation.class);
+                s3cc=s3c.getConstructor(ServletRequest.class);
+                servlet3Support=true;
+            }
+        }
+        catch (Exception e)
+        {}
+        finally
+        {
+            __servlet3=servlet3Support;
+            __newServlet3Continuation=s3cc;
+        }
+
+        boolean jetty6Support=false;
+        Constructor<? extends Continuation>j6cc=null;
+        try
+        {
+            Class<?> jetty6ContinuationClass = ContinuationSupport.class.getClassLoader().loadClass("org.mortbay.util.ajax.Continuation");
+            boolean jetty6=jetty6ContinuationClass!=null;
+            if (jetty6)
+            {
+                Class<? extends Continuation> j6c = ContinuationSupport.class.getClassLoader().loadClass("org.eclipse.jetty.continuation.Jetty6Continuation").asSubclass(Continuation.class);
+                j6cc=j6c.getConstructor(ServletRequest.class, jetty6ContinuationClass);
+                jetty6Support=true;
+            }
+        }
+        catch (Exception e)
+        {}
+        finally
+        {
+            __jetty6=jetty6Support;
+            __newJetty6Continuation=j6cc;
+        }
+
+        Class<?> waiting=null;
+        try
+        {
+            waiting=ContinuationSupport.class.getClassLoader().loadClass("org.mortbay.util.ajax.WaitingContinuation");
+        }
+        catch (Exception e)
+        {
+        }
+        finally
+        {
+            __waitingContinuation=waiting;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a Continuation.  The type of the Continuation returned may
+     * vary depending on the container in which the application is
+     * deployed. It may be an implementation native to the container (eg
+     * org.eclipse.jetty.server.AsyncContinuation) or one of the utility
+     * implementations provided such as an internal <code>FauxContinuation</code>
+     * or a real implementation like {@link org.eclipse.jetty.continuation.Servlet3Continuation}.
+     * @param request The request
+     * @return a Continuation instance
+     */
+    public static Continuation getContinuation(ServletRequest request)
+    {
+        Continuation continuation = (Continuation) request.getAttribute(Continuation.ATTRIBUTE);
+        if (continuation!=null)
+            return continuation;
+
+        while (request instanceof ServletRequestWrapper)
+            request=((ServletRequestWrapper)request).getRequest();
+
+        if (__servlet3 )
+        {
+            try
+            {
+                continuation=__newServlet3Continuation.newInstance(request);
+                request.setAttribute(Continuation.ATTRIBUTE,continuation);
+                return continuation;
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        if (__jetty6)
+        {
+            Object c=request.getAttribute("org.mortbay.jetty.ajax.Continuation");
+            try
+            {
+                if (c==null || __waitingContinuation==null || __waitingContinuation.isInstance(c))
+                    continuation=new FauxContinuation(request);
+                else
+                    continuation= __newJetty6Continuation.newInstance(request,c);
+                request.setAttribute(Continuation.ATTRIBUTE,continuation);
+                return continuation;
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        throw new IllegalStateException("!(Jetty || Servlet 3.0 || ContinuationFilter)");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param request the servlet request
+     * @param response the servlet response
+     * @deprecated use {@link #getContinuation(ServletRequest)}
+     * @return the continuation
+     */
+    @Deprecated
+    public static Continuation getContinuation(final ServletRequest request, final ServletResponse response)
+    {
+        return getContinuation(request);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/continuation/ContinuationThrowable.java b/src/java/org/eclipse/jetty/continuation/ContinuationThrowable.java
new file mode 100644
index 0000000..87c9f71
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/ContinuationThrowable.java
@@ -0,0 +1,46 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+
+/* ------------------------------------------------------------ */
+/** ContinuationThrowable
+ * <p>
+ * A ContinuationThrowable is throw by {@link Continuation#undispatch()}
+ * in order to exit the dispatch to a Filter or Servlet.  Use of
+ * ContinuationThrowable is discouraged and it is preferable to 
+ * allow return to be used. ContinuationThrowables should only be
+ * used when there is a Filter/Servlet which cannot be modified
+ * to avoid committing a response when {@link Continuation#isSuspended()}
+ * is true.
+ * </p>
+ * <p>
+ * ContinuationThrowable instances are often reused so that the
+ * stack trace may be entirely unrelated to the calling stack.
+ * A real stack trace may be obtained by enabling debug.
+ * </p>
+ * <p>
+ * ContinuationThrowable extends Error as this is more likely
+ * to be uncaught (or rethrown) by a Filter/Servlet.  A ContinuationThrowable
+ * does not represent and error condition.
+ * </p>
+ */
+public class ContinuationThrowable extends Error
+{}
diff --git a/src/java/org/eclipse/jetty/continuation/FauxContinuation.java b/src/java/org/eclipse/jetty/continuation/FauxContinuation.java
new file mode 100644
index 0000000..777166d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/FauxContinuation.java
@@ -0,0 +1,508 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.util.ArrayList;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import org.eclipse.jetty.continuation.ContinuationFilter.FilteredContinuation;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * A blocking implementation of Continuation.
+ * This implementation of Continuation is used by the {@link ContinuationFilter}
+ * when there are is no native or asynchronous continuation type available. 
+ */
+class FauxContinuation implements FilteredContinuation
+{
+    // common exception used for all continuations.  
+    // Turn on debug in ContinuationFilter to see real stack trace.
+    private final static ContinuationThrowable __exception = new ContinuationThrowable();
+    
+    private static final int __HANDLING=1;   // Request dispatched to filter/servlet
+    private static final int __SUSPENDING=2;   // Suspend called, but not yet returned to container
+    private static final int __RESUMING=3;     // resumed while suspending
+    private static final int __COMPLETING=4;   // resumed while suspending or suspended
+    private static final int __SUSPENDED=5;    // Suspended and parked
+    private static final int __UNSUSPENDING=6;
+    private static final int __COMPLETE=7;
+
+    private final ServletRequest _request;
+    private ServletResponse _response;
+    
+    private int _state=__HANDLING;
+    private boolean _initial=true;
+    private boolean _resumed=false;
+    private boolean _timeout=false;
+    private boolean _responseWrapped=false;
+    private  long _timeoutMs=30000; // TODO configure
+    
+    private ArrayList<ContinuationListener> _listeners; 
+
+    FauxContinuation(final ServletRequest request)
+    {
+        _request=request;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onComplete()
+    {
+        if (_listeners!=null)
+            for (ContinuationListener l:_listeners)
+                l.onComplete(this);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void onTimeout()
+    {
+        if (_listeners!=null)
+            for (ContinuationListener l:_listeners)
+                l.onTimeout(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped()
+     */
+    public boolean isResponseWrapped()
+    {
+        return _responseWrapped;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isInitial()
+    {
+        synchronized(this)
+        {
+            return _initial;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResumed()
+    {
+        synchronized(this)
+        {
+            return _resumed;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        synchronized(this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    return false;
+                case __SUSPENDING:
+                case __RESUMING:
+                case __COMPLETING:
+                case __SUSPENDED:
+                    return true;
+                case __UNSUSPENDING:
+                default:
+                    return false;   
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isExpired()
+    {
+        synchronized(this)
+        {
+            return _timeout;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setTimeout(long timeoutMs)
+    {
+        _timeoutMs = timeoutMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void suspend(ServletResponse response)
+    {
+        _response=response;
+        _responseWrapped=response instanceof ServletResponseWrapper;
+        suspend();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void suspend()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    _timeout=false;
+                    _resumed=false;
+                    _state=__SUSPENDING;
+                    return;
+
+                case __SUSPENDING:
+                case __RESUMING:
+                    return;
+
+                case __COMPLETING:
+                case __SUSPENDED:
+                case __UNSUSPENDING:
+                    throw new IllegalStateException(this.getStatusString());
+
+                default:
+                    throw new IllegalStateException(""+_state);
+            }
+
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see org.mortbay.jetty.Suspendor#resume()
+     */
+    public void resume()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    _resumed=true;
+                    return;
+                    
+                case __SUSPENDING:
+                    _resumed=true;
+                    _state=__RESUMING;
+                    return;
+
+                case __RESUMING:
+                case __COMPLETING:
+                    return;
+                    
+                case __SUSPENDED:
+                    fauxResume();
+                    _resumed=true;
+                    _state=__UNSUSPENDING;
+                    break;
+                    
+                case __UNSUSPENDING:
+                    _resumed=true;
+                    return;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+        
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    public void complete()
+    {
+        // just like resume, except don't set _resumed=true;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    throw new IllegalStateException(this.getStatusString());
+                    
+                case __SUSPENDING:
+                    _state=__COMPLETING;
+                    break;
+                    
+                case __RESUMING:
+                    break;
+
+                case __COMPLETING:
+                    return;
+                    
+                case __SUSPENDED:
+                    _state=__COMPLETING;
+                    fauxResume();
+                    break;
+                    
+                case __UNSUSPENDING:
+                    return;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
+     */
+    public boolean enter(ServletResponse response)
+    {
+        _response=response;
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
+     */
+    public ServletResponse getServletResponse()
+    {
+        return _response;
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    void handling()
+    {
+        synchronized (this)
+        {
+            _responseWrapped=false;
+            switch(_state)
+            {
+                case __HANDLING:
+                    throw new IllegalStateException(this.getStatusString());
+
+                case __SUSPENDING:
+                case __RESUMING:
+                    throw new IllegalStateException(this.getStatusString());
+
+                case __COMPLETING:
+                    return;
+
+                case __SUSPENDED:
+                    fauxResume();
+                case __UNSUSPENDING:
+                    _state=__HANDLING;
+                    return;
+
+                default:
+                    throw new IllegalStateException(""+_state);
+            }
+
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if handling is complete
+     */
+    public boolean exit()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    _state=__COMPLETE;
+                    onComplete();
+                    return true;
+
+                case __SUSPENDING:
+                    _initial=false;
+                    _state=__SUSPENDED;
+                    fauxSuspend(); // could block and change state.
+                    if (_state==__SUSPENDED || _state==__COMPLETING)
+                    {
+                        onComplete();
+                        return true;
+                    }
+                    
+                    _initial=false;
+                    _state=__HANDLING;
+                    return false; 
+
+                case __RESUMING:
+                    _initial=false;
+                    _state=__HANDLING;
+                    return false; 
+
+                case __COMPLETING:
+                    _initial=false;
+                    _state=__COMPLETE;
+                    onComplete();
+                    return true;
+
+                case __SUSPENDED:
+                case __UNSUSPENDING:
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void expire()
+    {
+        // just like resume, except don't set _resumed=true;
+
+        synchronized (this)
+        {
+            _timeout=true;
+        }
+        
+        onTimeout();
+        
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __HANDLING:
+                    return;
+                    
+                case __SUSPENDING:
+                    _timeout=true;
+                    _state=__RESUMING;
+                    fauxResume();
+                    return;
+                    
+                case __RESUMING:
+                    return;
+                    
+                case __COMPLETING:
+                    return;
+                    
+                case __SUSPENDED:
+                    _timeout=true;
+                    _state=__UNSUSPENDING;
+                    break;
+                    
+                case __UNSUSPENDING:
+                    _timeout=true;
+                    return;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    private void fauxSuspend()
+    {
+        long expire_at = System.currentTimeMillis()+_timeoutMs;
+        long wait=_timeoutMs;
+        while (_timeoutMs>0 && wait>0)
+        {
+            try
+            {
+                this.wait(wait);
+            }
+            catch (InterruptedException e)
+            {
+                break;
+            }
+            wait=expire_at-System.currentTimeMillis();
+        }
+
+        if (_timeoutMs>0 && wait<=0)
+            expire();
+    }
+    
+    private void fauxResume()
+    {
+        _timeoutMs=0;
+        this.notifyAll();
+    }
+    
+    @Override
+    public String toString()
+    {
+        return getStatusString();
+    }
+    
+    String getStatusString()
+    {
+        synchronized (this)
+        {
+            return
+            ((_state==__HANDLING)?"HANDLING":
+                    (_state==__SUSPENDING)?"SUSPENDING":
+                        (_state==__SUSPENDED)?"SUSPENDED":
+                            (_state==__RESUMING)?"RESUMING":
+                                (_state==__UNSUSPENDING)?"UNSUSPENDING":
+                                    (_state==__COMPLETING)?"COMPLETING":
+                                    ("???"+_state))+
+            (_initial?",initial":"")+
+            (_resumed?",resumed":"")+
+            (_timeout?",timeout":"");
+        }
+    }
+
+    
+    public void addContinuationListener(ContinuationListener listener)
+    {
+        if (_listeners==null)
+            _listeners=new ArrayList<ContinuationListener>();
+        _listeners.add(listener);
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _request.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _request.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _request.setAttribute(name,attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#undispatch()
+     */
+    public void undispatch()
+    {
+        if (isSuspended())
+        {
+            if (ContinuationFilter.__debug)
+                throw new ContinuationThrowable();
+            throw __exception;
+        }
+        throw new IllegalStateException("!suspended");
+        
+    }
+}
diff --git a/src/java/org/eclipse/jetty/continuation/Jetty6Continuation.java b/src/java/org/eclipse/jetty/continuation/Jetty6Continuation.java
new file mode 100644
index 0000000..3ed177d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/Jetty6Continuation.java
@@ -0,0 +1,267 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+import org.mortbay.log.Log;
+import org.mortbay.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * This implementation of Continuation is used by {@link ContinuationSupport}
+ * when it detects that the application is deployed in a jetty-6 server.
+ * This continuation requires the {@link ContinuationFilter} to be deployed.
+ */
+public class Jetty6Continuation implements ContinuationFilter.FilteredContinuation
+{
+    private static final Logger LOG = Log.getLogger(Jetty6Continuation.class.getName());
+
+    // Exception reused for all continuations
+    // Turn on debug in ContinuationFilter to see real stack trace.
+    private final static ContinuationThrowable __exception = new ContinuationThrowable();
+
+    private final ServletRequest _request;
+    private ServletResponse _response;
+    private final org.mortbay.util.ajax.Continuation _j6Continuation;
+
+    private Throwable _retry;
+    private int _timeout;
+    private boolean _initial=true;
+    private volatile boolean _completed=false;
+    private volatile boolean _resumed=false;
+    private volatile boolean _expired=false;
+    private boolean _responseWrapped=false;
+    private List<ContinuationListener> _listeners;
+
+    public Jetty6Continuation(ServletRequest request, org.mortbay.util.ajax.Continuation continuation)
+    {
+        if (!ContinuationFilter._initialized)
+        {
+            LOG.warn("!ContinuationFilter installed",null,null);
+            throw new IllegalStateException("!ContinuationFilter installed");
+        }
+        _request=request;
+        _j6Continuation=continuation;
+    }
+
+    public void addContinuationListener(final ContinuationListener listener)
+    {
+        if (_listeners==null)
+            _listeners=new ArrayList<ContinuationListener>();
+        _listeners.add(listener);
+    }
+
+    public void complete()
+    {
+        synchronized(this)
+        {
+            if (_resumed)
+                throw new IllegalStateException();
+            _completed=true;
+            if (_j6Continuation.isPending())
+                _j6Continuation.resume();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _request.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _request.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _request.setAttribute(name,attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletResponse getServletResponse()
+    {
+        return _response;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isExpired()
+    {
+        return _expired;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isInitial()
+    {
+        return _initial;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResumed()
+    {
+        return _resumed;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return _retry!=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void resume()
+    {
+        synchronized(this)
+        {
+            if (_completed)
+                throw new IllegalStateException();
+            _resumed=true;
+            if (_j6Continuation.isPending())
+                _j6Continuation.resume();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setTimeout(long timeoutMs)
+    {
+        _timeout=(timeoutMs>Integer.MAX_VALUE)?Integer.MAX_VALUE:(int)timeoutMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#suspend(javax.servlet.ServletResponse)
+     */
+    public void suspend(ServletResponse response)
+    {
+        try
+        {
+            _response=response;
+            _responseWrapped=_response instanceof ServletResponseWrapper;
+            _resumed=false;
+            _expired=false;
+            _completed=false;
+            _j6Continuation.suspend(_timeout);
+        }
+        catch(Throwable retry)
+        {
+            _retry=retry;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void suspend()
+    {
+        try
+        {
+            _response=null;
+            _responseWrapped=false;
+            _resumed=false;
+            _expired=false;
+            _completed=false;
+            _j6Continuation.suspend(_timeout);
+        }
+        catch(Throwable retry)
+        {
+            _retry=retry;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResponseWrapped()
+    {
+        return _responseWrapped;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#undispatch()
+     */
+    public void undispatch()
+    {
+        if (isSuspended())
+        {
+            if (ContinuationFilter.__debug)
+                throw new ContinuationThrowable();
+            throw __exception;
+        }
+        throw new IllegalStateException("!suspended");
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean enter(ServletResponse response)
+    {
+        _response=response;
+        _expired=!_j6Continuation.isResumed();
+
+        if (_initial)
+            return true;
+
+        _j6Continuation.reset();
+
+        if (_expired)
+        {
+            if (_listeners!=null)
+            {
+                for (ContinuationListener l: _listeners)
+                    l.onTimeout(this);
+            }
+        }
+
+        return !_completed;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean exit()
+    {
+        _initial=false;
+
+        Throwable th=_retry;
+        _retry=null;
+        if (th instanceof Error)
+            throw (Error)th;
+        if (th instanceof RuntimeException)
+            throw (RuntimeException)th;
+
+        if (_listeners!=null)
+        {
+            for (ContinuationListener l: _listeners)
+                l.onComplete(this);
+        }
+
+        return true;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/continuation/Servlet3Continuation.java b/src/java/org/eclipse/jetty/continuation/Servlet3Continuation.java
new file mode 100644
index 0000000..f07d3f5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/continuation/Servlet3Continuation.java
@@ -0,0 +1,256 @@
+//
+//  ========================================================================
+//  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.continuation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.DispatcherType;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * This implementation of Continuation is used by {@link ContinuationSupport}
+ * when it detects that the application has been deployed in a non-jetty Servlet 3
+ * server.
+ */
+public class Servlet3Continuation implements Continuation
+{
+    // Exception reused for all continuations
+    // Turn on debug in ContinuationFilter to see real stack trace.
+    private final static ContinuationThrowable __exception = new ContinuationThrowable();
+
+    private final ServletRequest _request;
+    private ServletResponse _response;
+    private AsyncContext _context;
+    private List<AsyncListener> _listeners=new ArrayList<AsyncListener>();
+    private volatile boolean _initial=true;
+    private volatile boolean _resumed=false;
+    private volatile boolean _expired=false;
+    private volatile boolean _responseWrapped=false;
+
+    private long _timeoutMs=-1;
+
+    /* ------------------------------------------------------------ */
+    public Servlet3Continuation(ServletRequest request)
+    {
+        _request=request;
+
+        _listeners.add(new AsyncListener()
+        {
+            public void onComplete(AsyncEvent event) throws IOException
+            {
+            }
+
+            public void onError(AsyncEvent event) throws IOException
+            {
+            }
+
+            public void onStartAsync(AsyncEvent event) throws IOException
+            {
+                event.getAsyncContext().addListener(this);
+            }
+
+            public void onTimeout(AsyncEvent event) throws IOException
+            {
+                _initial=false;
+                event.getAsyncContext().dispatch();
+            }
+        });
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addContinuationListener(final ContinuationListener listener)
+    {
+        AsyncListener wrapped = new AsyncListener()
+        {
+            public void onComplete(final AsyncEvent event) throws IOException
+            {
+                listener.onComplete(Servlet3Continuation.this);
+            }
+
+            public void onError(AsyncEvent event) throws IOException
+            {
+                listener.onComplete(Servlet3Continuation.this);
+            }
+
+            public void onStartAsync(AsyncEvent event) throws IOException
+            {
+                event.getAsyncContext().addListener(this);
+            }
+
+            public void onTimeout(AsyncEvent event) throws IOException
+            {
+                _expired=true;
+                listener.onTimeout(Servlet3Continuation.this);
+            }
+        };
+
+        if (_context!=null)
+            _context.addListener(wrapped);
+        else
+            _listeners.add(wrapped);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void complete()
+    {
+        AsyncContext context=_context;
+        if (context==null)
+            throw new IllegalStateException();
+        _context.complete();
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletResponse getServletResponse()
+    {
+        return _response;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isExpired()
+    {
+        return _expired;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isInitial()
+    {
+        // TODO - this is not perfect if non continuation API is used directly
+        return _initial&&_request.getDispatcherType()!=DispatcherType.ASYNC;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResumed()
+    {
+        return _resumed;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return _request.isAsyncStarted();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void keepWrappers()
+    {
+        _responseWrapped=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void resume()
+    {
+        AsyncContext context=_context;
+        if (context==null)
+            throw new IllegalStateException();
+        _resumed=true;
+        _context.dispatch();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setTimeout(long timeoutMs)
+    {
+        _timeoutMs=timeoutMs;
+        if (_context!=null)
+            _context.setTimeout(timeoutMs);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void suspend(ServletResponse response)
+    {
+        _response=response;
+        _responseWrapped=response instanceof ServletResponseWrapper;
+        _resumed=false;
+        _expired=false;
+        _context=_request.startAsync();
+        _context.setTimeout(_timeoutMs);
+
+        for (AsyncListener listener:_listeners)
+            _context.addListener(listener);
+        _listeners.clear();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void suspend()
+    {
+        _resumed=false;
+        _expired=false;
+        _context=_request.startAsync();
+        _context.setTimeout(_timeoutMs);
+
+        for (AsyncListener listener:_listeners)
+            _context.addListener(listener);
+        _listeners.clear();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResponseWrapped()
+    {
+        return _responseWrapped;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _request.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _request.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _request.setAttribute(name,attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#undispatch()
+     */
+    public void undispatch()
+    {
+        if (isSuspended())
+        {
+            if (ContinuationFilter.__debug)
+                throw new ContinuationThrowable();
+            throw __exception;
+        }
+        throw new IllegalStateException("!suspended");
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/AbstractGenerator.java b/src/java/org/eclipse/jetty/http/AbstractGenerator.java
new file mode 100644
index 0000000..8df3ebe
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/AbstractGenerator.java
@@ -0,0 +1,532 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.View;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Abstract Generator. Builds HTTP Messages.
+ *
+ * Currently this class uses a system parameter "jetty.direct.writers" to control
+ * two optional writer to byte conversions. buffer.writers=true will probably be
+ * faster, but will consume more memory.   This option is just for testing and tuning.
+ *
+ */
+public abstract class AbstractGenerator implements Generator
+{
+    private static final Logger LOG = Log.getLogger(AbstractGenerator.class);
+
+    // states
+    public final static int STATE_HEADER = 0;
+    public final static int STATE_CONTENT = 2;
+    public final static int STATE_FLUSHING = 3;
+    public final static int STATE_END = 4;
+
+    public static final byte[] NO_BYTES = {};
+
+    // data
+
+    protected final Buffers _buffers; // source of buffers
+    protected final EndPoint _endp;
+
+    protected int _state = STATE_HEADER;
+
+    protected int _status = 0;
+    protected int _version = HttpVersions.HTTP_1_1_ORDINAL;
+    protected  Buffer _reason;
+    protected  Buffer _method;
+    protected  String _uri;
+
+    protected long _contentWritten = 0;
+    protected long _contentLength = HttpTokens.UNKNOWN_CONTENT;
+    protected boolean _last = false;
+    protected boolean _head = false;
+    protected boolean _noContent = false;
+    protected Boolean _persistent = null;
+
+    protected Buffer _header; // Buffer for HTTP header (and maybe small _content)
+    protected Buffer _buffer; // Buffer for copy of passed _content
+    protected Buffer _content; // Buffer passed to addContent
+
+    protected Buffer _date;
+
+    private boolean _sendServerVersion;
+
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Constructor.
+     *
+     * @param buffers buffer pool
+     * @param io the end point
+     */
+    public AbstractGenerator(Buffers buffers, EndPoint io)
+    {
+        this._buffers = buffers;
+        this._endp = io;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public abstract boolean isRequest();
+
+    /* ------------------------------------------------------------------------------- */
+    public abstract boolean isResponse();
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean isOpen()
+    {
+        return _endp.isOpen();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void reset()
+    {
+        _state = STATE_HEADER;
+        _status = 0;
+        _version = HttpVersions.HTTP_1_1_ORDINAL;
+        _reason = null;
+        _last = false;
+        _head = false;
+        _noContent=false;
+        _persistent = null;
+        _contentWritten = 0;
+        _contentLength = HttpTokens.UNKNOWN_CONTENT;
+        _date = null;
+
+        _content = null;
+        _method=null;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void returnBuffers()
+    {
+        if (_buffer!=null && _buffer.length()==0)
+        {
+            _buffers.returnBuffer(_buffer);
+            _buffer=null;
+        }
+
+        if (_header!=null && _header.length()==0)
+        {
+            _buffers.returnBuffer(_header);
+            _header=null;
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void resetBuffer()
+    {
+        if(_state>=STATE_FLUSHING)
+            throw new IllegalStateException("Flushed");
+
+        _last = false;
+        _persistent=null;
+        _contentWritten = 0;
+        _contentLength = HttpTokens.UNKNOWN_CONTENT;
+        _content=null;
+        if (_buffer!=null)
+            _buffer.clear();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the contentBufferSize.
+     */
+    public int getContentBufferSize()
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+        return _buffer.capacity();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param contentBufferSize The contentBufferSize to set.
+     */
+    public void increaseContentBufferSize(int contentBufferSize)
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+        if (contentBufferSize > _buffer.capacity())
+        {
+            Buffer nb = _buffers.getBuffer(contentBufferSize);
+            nb.put(_buffer);
+            _buffers.returnBuffer(_buffer);
+            _buffer = nb;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getUncheckedBuffer()
+    {
+        return _buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getSendServerVersion ()
+    {
+        return _sendServerVersion;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setSendServerVersion (boolean sendServerVersion)
+    {
+        _sendServerVersion = sendServerVersion;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getState()
+    {
+        return _state;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isState(int state)
+    {
+        return _state == state;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isComplete()
+    {
+        return _state == STATE_END;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _state == STATE_HEADER && _method==null && _status==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isCommitted()
+    {
+        return _state != STATE_HEADER;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the head.
+     */
+    public boolean isHead()
+    {
+        return _head;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setContentLength(long value)
+    {
+        if (value<0)
+            _contentLength=HttpTokens.UNKNOWN_CONTENT;
+        else
+            _contentLength=value;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param head The head to set.
+     */
+    public void setHead(boolean head)
+    {
+        _head = head;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return <code>false</code> if the connection should be closed after a request has been read,
+     * <code>true</code> if it should be used for additional requests.
+     */
+    public boolean isPersistent()
+    {
+        return _persistent!=null
+        ?_persistent.booleanValue()
+        :(isRequest()?true:_version>HttpVersions.HTTP_1_0_ORDINAL);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setPersistent(boolean persistent)
+    {
+        _persistent=persistent;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param version The version of the client the response is being sent to (NB. Not the version
+     *            in the response, which is the version of the server).
+     */
+    public void setVersion(int version)
+    {
+        if (_state != STATE_HEADER)
+            throw new IllegalStateException("STATE!=START "+_state);
+        _version = version;
+        if (_version==HttpVersions.HTTP_0_9_ORDINAL && _method!=null)
+            _noContent=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getVersion()
+    {
+        return _version;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.Generator#setDate(org.eclipse.jetty.io.Buffer)
+     */
+    public void setDate(Buffer timeStampBuffer)
+    {
+        _date=timeStampBuffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void setRequest(String method, String uri)
+    {
+        if (method==null || HttpMethods.GET.equals(method) )
+            _method=HttpMethods.GET_BUFFER;
+        else
+            _method=HttpMethods.CACHE.lookup(method);
+        _uri=uri;
+        if (_version==HttpVersions.HTTP_0_9_ORDINAL)
+            _noContent=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param status The status code to send.
+     * @param reason the status message to send.
+     */
+    public void setResponse(int status, String reason)
+    {
+        if (_state != STATE_HEADER) throw new IllegalStateException("STATE!=START");
+        _method=null;
+        _status = status;
+        if (reason!=null)
+        {
+            int len=reason.length();
+
+            // TODO don't hard code
+            if (len>1024)
+                len=1024;
+            _reason=new ByteArrayBuffer(len);
+            for (int i=0;i<len;i++)
+            {
+                char ch = reason.charAt(i);
+                if (ch!='\r'&&ch!='\n')
+                    _reason.put((byte)ch);
+                else
+                    _reason.put((byte)' ');
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Prepare buffer for unchecked writes.
+     * Prepare the generator buffer to receive unchecked writes
+     * @return the available space in the buffer.
+     * @throws IOException
+     */
+    public abstract int prepareUncheckedAddContent() throws IOException;
+
+    /* ------------------------------------------------------------ */
+    void uncheckedAddContent(int b)
+    {
+        _buffer.put((byte)b);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void completeUncheckedAddContent()
+    {
+        if (_noContent)
+        {
+            if(_buffer!=null)
+                _buffer.clear();
+        }
+        else
+        {
+            _contentWritten+=_buffer.length();
+            if (_head)
+                _buffer.clear();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isBufferFull()
+    {
+        if (_buffer != null && _buffer.space()==0)
+        {
+            if (_buffer.length()==0 && !_buffer.isImmutable())
+                _buffer.compact();
+            return _buffer.space()==0;
+        }
+
+        return _content!=null && _content.length()>0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isWritten()
+    {
+        return _contentWritten>0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isAllContentWritten()
+    {
+        return _contentLength>=0 && _contentWritten>=_contentLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    public abstract void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Complete the message.
+     *
+     * @throws IOException
+     */
+    public void complete() throws IOException
+    {
+        if (_state == STATE_HEADER)
+        {
+            throw new IllegalStateException("State==HEADER");
+        }
+
+        if (_contentLength >= 0 && _contentLength != _contentWritten && !_head)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("ContentLength written=="+_contentWritten+" != contentLength=="+_contentLength);
+            _persistent = false;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public abstract int flushBuffer() throws IOException;
+
+
+    /* ------------------------------------------------------------ */
+    public void flush(long maxIdleTime) throws IOException
+    {
+        // block until everything is flushed
+        long now=System.currentTimeMillis();
+        long end=now+maxIdleTime;
+        Buffer content = _content;
+        Buffer buffer = _buffer;
+        if (content!=null && content.length()>0 || buffer!=null && buffer.length()>0 || isBufferFull())
+        {
+            flushBuffer();
+
+            while (now<end && (content!=null && content.length()>0 ||buffer!=null && buffer.length()>0) && _endp.isOpen()&& !_endp.isOutputShutdown())
+            {
+                blockForOutput(end-now);
+                now=System.currentTimeMillis();
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Utility method to send an error response. If the builder is not committed, this call is
+     * equivalent to a setResponse, addContent and complete call.
+     *
+     * @param code The error code
+     * @param reason The error reason
+     * @param content Contents of the error page
+     * @param close True if the connection should be closed
+     * @throws IOException if there is a problem flushing the response
+     */
+    public void sendError(int code, String reason, String content, boolean close) throws IOException
+    {
+        if (close)
+            _persistent=false;
+        if (isCommitted())
+        {
+            LOG.debug("sendError on committed: {} {}",code,reason);
+        }
+        else
+        {
+            LOG.debug("sendError: {} {}",code,reason);
+            setResponse(code, reason);
+            if (content != null)
+            {
+                completeHeader(null, false);
+                addContent(new View(new ByteArrayBuffer(content)), Generator.LAST);
+            }
+            else if (code>=400)
+            {
+                completeHeader(null, false);
+                addContent(new View(new ByteArrayBuffer("Error: "+(reason==null?(""+code):reason))), Generator.LAST);
+            }
+            else
+            {
+                completeHeader(null, true);
+            }
+            complete();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the contentWritten.
+     */
+    public long getContentWritten()
+    {
+        return _contentWritten;
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    public void  blockForOutput(long maxIdleTime) throws IOException
+    {
+        if (_endp.isBlocking())
+        {
+            try
+            {
+                flushBuffer();
+            }
+            catch(IOException e)
+            {
+                _endp.close();
+                throw e;
+            }
+        }
+        else
+        {
+            if (!_endp.blockWritable(maxIdleTime))
+            {
+                _endp.close();
+                throw new EofException("timeout");
+            }
+
+            flushBuffer();
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/http/EncodedHttpURI.java b/src/java/org/eclipse/jetty/http/EncodedHttpURI.java
new file mode 100644
index 0000000..1fd22d3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/EncodedHttpURI.java
@@ -0,0 +1,183 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.eclipse.jetty.util.Utf8StringBuffer;
+
+public class EncodedHttpURI extends HttpURI
+{
+    private final String _encoding;
+    
+    public EncodedHttpURI(String encoding)
+    {
+        super();
+        _encoding = encoding;
+    }
+    
+    
+    @Override
+    public String getScheme()
+    {
+        if (_scheme==_authority)
+            return null;
+        int l=_authority-_scheme;
+        if (l==5 && 
+            _raw[_scheme]=='h' && 
+            _raw[_scheme+1]=='t' && 
+            _raw[_scheme+2]=='t' && 
+            _raw[_scheme+3]=='p' )
+            return HttpSchemes.HTTP;
+        if (l==6 && 
+            _raw[_scheme]=='h' && 
+            _raw[_scheme+1]=='t' && 
+            _raw[_scheme+2]=='t' && 
+            _raw[_scheme+3]=='p' && 
+            _raw[_scheme+4]=='s' )
+            return HttpSchemes.HTTPS;
+        
+        return StringUtil.toString(_raw,_scheme,_authority-_scheme-1,_encoding);
+    }
+    
+    @Override
+    public String getAuthority()
+    {
+        if (_authority==_path)
+            return null;
+        return StringUtil.toString(_raw,_authority,_path-_authority,_encoding);
+    }
+    
+    @Override
+    public String getHost()
+    {
+        if (_host==_port)
+            return null;
+        return StringUtil.toString(_raw,_host,_port-_host,_encoding);
+    }
+    
+    @Override
+    public int getPort()
+    {
+        if (_port==_path)
+            return -1;
+        return TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
+    }
+    
+    @Override
+    public String getPath()
+    {
+        if (_path==_param)
+            return null;
+        return StringUtil.toString(_raw,_path,_param-_path,_encoding);
+    }
+    
+    @Override
+    public String getDecodedPath()
+    {
+        if (_path==_param)
+            return null;
+        return URIUtil.decodePath(_raw,_path,_param-_path);
+    }
+    
+    @Override
+    public String getPathAndParam()
+    {
+        if (_path==_query)
+            return null;
+        return StringUtil.toString(_raw,_path,_query-_path,_encoding);
+    }
+    
+    @Override
+    public String getCompletePath()
+    {
+        if (_path==_end)
+            return null;
+        return StringUtil.toString(_raw,_path,_end-_path,_encoding);
+    }
+    
+    @Override
+    public String getParam()
+    {
+        if (_param==_query)
+            return null;
+        return StringUtil.toString(_raw,_param+1,_query-_param-1,_encoding);
+    }
+    
+    @Override
+    public String getQuery()
+    {
+        if (_query==_fragment)
+            return null;
+        return StringUtil.toString(_raw,_query+1,_fragment-_query-1,_encoding);
+    }
+    
+    @Override
+    public boolean hasQuery()
+    {
+        return (_fragment>_query);
+    }
+    
+    @Override
+    public String getFragment()
+    {
+        if (_fragment==_end)
+            return null;
+        return StringUtil.toString(_raw,_fragment+1,_end-_fragment-1,_encoding);
+    }
+
+    @Override
+    public void decodeQueryTo(MultiMap parameters) 
+    {
+        if (_query==_fragment)
+            return;
+        UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,_encoding),parameters,_encoding);
+    }
+
+    @Override
+    public void decodeQueryTo(MultiMap parameters, String encoding) 
+        throws UnsupportedEncodingException
+    {
+        if (_query==_fragment)
+            return;
+       
+        if (encoding==null)
+            encoding=_encoding;
+        UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding);
+    }
+    
+    @Override
+    public String toString()
+    {
+        if (_rawString==null)
+            _rawString= StringUtil.toString(_raw,_scheme,_end-_scheme,_encoding);
+        return _rawString;
+    }
+    
+    public void writeTo(Utf8StringBuffer buf)
+    {
+        buf.getStringBuffer().append(toString());
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/Generator.java b/src/java/org/eclipse/jetty/http/Generator.java
new file mode 100644
index 0000000..4e91434
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/Generator.java
@@ -0,0 +1,96 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+
+public interface Generator
+{
+    public static final boolean LAST=true;
+    public static final boolean MORE=false;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add content.
+     * 
+     * @param content
+     * @param last
+     * @throws IllegalArgumentException if <code>content</code> is {@link Buffer#isImmutable immutable}.
+     * @throws IllegalStateException If the request is not expecting any more content,
+     *   or if the buffers are full and cannot be flushed.
+     * @throws IOException if there is a problem flushing the buffers.
+     */
+    void addContent(Buffer content, boolean last) throws IOException;
+
+    void complete() throws IOException;
+
+    void completeHeader(HttpFields responseFields, boolean last) throws IOException;
+
+    int flushBuffer() throws IOException;
+
+    int getContentBufferSize();
+
+    long getContentWritten();
+
+    boolean isWritten();
+    
+    boolean isAllContentWritten();
+
+    void increaseContentBufferSize(int size);
+    
+    boolean isBufferFull();
+
+    boolean isCommitted();
+
+    boolean isComplete();
+
+    boolean isPersistent();
+
+    void reset();
+
+    void resetBuffer();
+    
+    void returnBuffers();
+
+    void sendError(int code, String reason, String content, boolean close) throws IOException;
+    
+    void setHead(boolean head);
+
+    void setRequest(String method, String uri);
+
+    void setResponse(int status, String reason);
+
+
+    void setSendServerVersion(boolean sendServerVersion);
+ 
+    void setVersion(int version);
+
+    boolean isIdle();
+
+    void setContentLength(long length);
+    
+    void setPersistent(boolean persistent);
+
+    void setDate(Buffer timeStampBuffer);
+    
+
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpBuffers.java b/src/java/org/eclipse/jetty/http/HttpBuffers.java
new file mode 100644
index 0000000..58032bc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpBuffers.java
@@ -0,0 +1,108 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.BuffersFactory;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+
+/* ------------------------------------------------------------ */
+/** Abstract Buffer pool.
+ */
+public interface HttpBuffers
+{
+    /**
+     * @return the requestBufferSize
+     */
+    public int getRequestBufferSize();
+    
+    /**
+     * @param requestBufferSize the requestBufferSize to set
+     */
+    public void setRequestBufferSize(int requestBufferSize);
+
+    /**
+     * @return the requestHeaderSize
+     */
+    public int getRequestHeaderSize();
+
+    /**
+     * @param requestHeaderSize the requestHeaderSize to set
+     */
+    public void setRequestHeaderSize(int requestHeaderSize);
+
+    /**
+     * @return the responseBufferSize
+     */
+    public int getResponseBufferSize();
+
+    /**
+     * @param responseBufferSize the responseBufferSize to set
+     */
+    public void setResponseBufferSize(int responseBufferSize);
+
+    /**
+     * @return the responseHeaderSize
+     */
+    public int getResponseHeaderSize();
+
+    /**
+     * @param responseHeaderSize the responseHeaderSize to set
+     */
+    public void setResponseHeaderSize(int responseHeaderSize);
+
+    /**
+     * @return the requestBufferType
+     */
+    public Buffers.Type getRequestBufferType();
+
+    /**
+     * @return the requestHeaderType
+     */
+    public Buffers.Type getRequestHeaderType();
+
+    /**
+     * @return the responseBufferType
+     */
+    public Buffers.Type getResponseBufferType();
+
+    /**
+     * @return the responseHeaderType
+     */
+    public Buffers.Type getResponseHeaderType();
+
+    /**
+     * @param requestBuffers the requestBuffers to set
+     */
+    public void setRequestBuffers(Buffers requestBuffers);
+
+    /**
+     * @param responseBuffers the responseBuffers to set
+     */
+    public void setResponseBuffers(Buffers responseBuffers);
+
+    public Buffers getRequestBuffers();
+
+    public Buffers getResponseBuffers();
+
+    public void setMaxBuffers(int maxBuffers);
+
+    public int getMaxBuffers();
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpBuffersImpl.java b/src/java/org/eclipse/jetty/http/HttpBuffersImpl.java
new file mode 100644
index 0000000..6bf5ec3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpBuffersImpl.java
@@ -0,0 +1,238 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.BuffersFactory;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+
+/* ------------------------------------------------------------ */
+/** Abstract Buffer pool.
+ * simple unbounded pool of buffers for header, request and response sizes.
+ *
+ */
+public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers
+{
+    private int _requestBufferSize=16*1024;
+    private int _requestHeaderSize=6*1024;
+    private int _responseBufferSize=32*1024;
+    private int _responseHeaderSize=6*1024;
+    private int _maxBuffers=1024;
+    
+    private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY;
+    private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY;
+    private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY;
+    private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY;
+    
+    private Buffers _requestBuffers;
+    private Buffers _responseBuffers;
+    
+    
+    public HttpBuffersImpl()
+    {
+        super();
+    }
+    
+    /**
+     * @return the requestBufferSize
+     */
+    public int getRequestBufferSize()
+    {
+        return _requestBufferSize;
+    }
+    
+    /**
+     * @param requestBufferSize the requestBufferSize to set
+     */
+    public void setRequestBufferSize(int requestBufferSize)
+    {
+        _requestBufferSize = requestBufferSize;
+    }
+
+    /**
+     * @return the requestHeaderSize
+     */
+    public int getRequestHeaderSize()
+    {
+        return _requestHeaderSize;
+    }
+
+    /**
+     * @param requestHeaderSize the requestHeaderSize to set
+     */
+    public void setRequestHeaderSize(int requestHeaderSize)
+    {
+        _requestHeaderSize = requestHeaderSize;
+    }
+
+    /**
+     * @return the responseBufferSize
+     */
+    public int getResponseBufferSize()
+    {
+        return _responseBufferSize;
+    }
+
+    /**
+     * @param responseBufferSize the responseBufferSize to set
+     */
+    public void setResponseBufferSize(int responseBufferSize)
+    {
+        _responseBufferSize = responseBufferSize;
+    }
+
+    /**
+     * @return the responseHeaderSize
+     */
+    public int getResponseHeaderSize()
+    {
+        return _responseHeaderSize;
+    }
+
+    /**
+     * @param responseHeaderSize the responseHeaderSize to set
+     */
+    public void setResponseHeaderSize(int responseHeaderSize)
+    {
+        _responseHeaderSize = responseHeaderSize;
+    }
+
+    /**
+     * @return the requestBufferType
+     */
+    public Buffers.Type getRequestBufferType()
+    {
+        return _requestBufferType;
+    }
+
+    /**
+     * @param requestBufferType the requestBufferType to set
+     */
+    public void setRequestBufferType(Buffers.Type requestBufferType)
+    {
+        _requestBufferType = requestBufferType;
+    }
+
+    /**
+     * @return the requestHeaderType
+     */
+    public Buffers.Type getRequestHeaderType()
+    {
+        return _requestHeaderType;
+    }
+
+    /**
+     * @param requestHeaderType the requestHeaderType to set
+     */
+    public void setRequestHeaderType(Buffers.Type requestHeaderType)
+    {
+        _requestHeaderType = requestHeaderType;
+    }
+
+    /**
+     * @return the responseBufferType
+     */
+    public Buffers.Type getResponseBufferType()
+    {
+        return _responseBufferType;
+    }
+
+    /**
+     * @param responseBufferType the responseBufferType to set
+     */
+    public void setResponseBufferType(Buffers.Type responseBufferType)
+    {
+        _responseBufferType = responseBufferType;
+    }
+
+    /**
+     * @return the responseHeaderType
+     */
+    public Buffers.Type getResponseHeaderType()
+    {
+        return _responseHeaderType;
+    }
+
+    /**
+     * @param responseHeaderType the responseHeaderType to set
+     */
+    public void setResponseHeaderType(Buffers.Type responseHeaderType)
+    {
+        _responseHeaderType = responseHeaderType;
+    }
+
+    /**
+     * @param requestBuffers the requestBuffers to set
+     */
+    public void setRequestBuffers(Buffers requestBuffers)
+    {
+        _requestBuffers = requestBuffers;
+    }
+
+    /**
+     * @param responseBuffers the responseBuffers to set
+     */
+    public void setResponseBuffers(Buffers responseBuffers)
+    {
+        _responseBuffers = responseBuffers;
+    }
+
+    @Override
+    protected void doStart()
+        throws Exception
+    {
+        _requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers());
+        _responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers());
+        super.doStart();
+    }
+    
+    @Override
+    protected void doStop()
+        throws Exception
+    {
+        _requestBuffers=null;
+        _responseBuffers=null;
+    }
+
+    public Buffers getRequestBuffers()
+    {
+        return _requestBuffers;
+    }
+    
+
+    public Buffers getResponseBuffers()
+    {
+        return _responseBuffers;
+    }
+
+    public void setMaxBuffers(int maxBuffers)
+    {
+        _maxBuffers = maxBuffers;
+    }
+
+    public int getMaxBuffers()
+    {
+        return _maxBuffers;
+    }
+    
+    public String toString()
+    {
+        return _requestBuffers+"/"+_responseBuffers;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpContent.java b/src/java/org/eclipse/jetty/http/HttpContent.java
new file mode 100644
index 0000000..5961591
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpContent.java
@@ -0,0 +1,167 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/* ------------------------------------------------------------ */
+/** HttpContent.
+ * 
+ *
+ */
+public interface HttpContent
+{
+    Buffer getContentType();
+    Buffer getLastModified();
+    Buffer getIndirectBuffer();
+    Buffer getDirectBuffer();
+    Buffer getETag();
+    Resource getResource();
+    long getContentLength();
+    InputStream getInputStream() throws IOException;
+    void release();
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class ResourceAsHttpContent implements HttpContent
+    {
+        private static final Logger LOG = Log.getLogger(ResourceAsHttpContent.class);
+        
+        final Resource _resource;
+        final Buffer _mimeType;
+        final int _maxBuffer;
+        final Buffer _etag;
+
+        /* ------------------------------------------------------------ */
+        public ResourceAsHttpContent(final Resource resource, final Buffer mimeType)
+        {
+            this(resource,mimeType,-1,false);
+        }
+
+        /* ------------------------------------------------------------ */
+        public ResourceAsHttpContent(final Resource resource, final Buffer mimeType, int maxBuffer)
+        {
+            this(resource,mimeType,maxBuffer,false);
+        }
+
+        /* ------------------------------------------------------------ */
+        public ResourceAsHttpContent(final Resource resource, final Buffer mimeType, boolean etag)
+        {
+            this(resource,mimeType,-1,etag);
+        }
+
+        /* ------------------------------------------------------------ */
+        public ResourceAsHttpContent(final Resource resource, final Buffer mimeType, int maxBuffer, boolean etag)
+        {
+            _resource=resource;
+            _mimeType=mimeType;
+            _maxBuffer=maxBuffer;
+            _etag=etag?new ByteArrayBuffer(resource.getWeakETag()):null;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getContentType()
+        {
+            return _mimeType;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getLastModified()
+        {
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getDirectBuffer()
+        {
+            return null;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public Buffer getETag()
+        {
+            return _etag;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getIndirectBuffer()
+        {
+            InputStream inputStream = null;
+            try
+            {
+                if (_resource.length() <= 0 || _maxBuffer < _resource.length())
+                    return null;
+                ByteArrayBuffer buffer = new ByteArrayBuffer((int)_resource.length());
+                inputStream = _resource.getInputStream();
+                buffer.readFrom(inputStream,(int)_resource.length());
+                return buffer;
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+            finally
+            {
+                if (inputStream != null)
+                {
+                    try
+                    {
+                        inputStream.close();
+                    }
+                    catch (IOException e)
+                    {
+                        LOG.warn("Couldn't close inputStream. Possible file handle leak",e);
+                    }
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public long getContentLength()
+        {
+            return _resource.length();
+        }
+
+        /* ------------------------------------------------------------ */
+        public InputStream getInputStream() throws IOException
+        {
+            return _resource.getInputStream();
+        }
+
+        /* ------------------------------------------------------------ */
+        public Resource getResource()
+        {
+            return _resource;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void release()
+        {
+            _resource.release();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpCookie.java b/src/java/org/eclipse/jetty/http/HttpCookie.java
new file mode 100644
index 0000000..02da647
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpCookie.java
@@ -0,0 +1,191 @@
+//
+//  ========================================================================
+//  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.http;
+
+public class HttpCookie
+{
+    private final String _name;        
+    private final String _value;     
+    private final String _comment;                               
+    private final String _domain;    
+    private final int _maxAge;  
+    private final String _path;       
+    private final boolean _secure;   
+    private final int _version;   
+    private final boolean _httpOnly;
+
+    /* ------------------------------------------------------------ */
+    public HttpCookie(String name, String value)
+    {
+        super();
+        _name = name;
+        _value = value;
+        _comment = null;
+        _domain = null;
+        _httpOnly = false;
+        _maxAge = -1;
+        _path = null;
+        _secure = false;
+        _version = 0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public HttpCookie(String name, String value, String domain, String path)
+    {
+        super();
+        _name = name;
+        _value = value;
+        _comment = null;
+        _domain = domain;
+        _httpOnly = false;
+        _maxAge = -1;
+        _path = path;
+        _secure = false;
+        _version = 0;
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    public HttpCookie(String name, String value, int maxAge)
+    {
+        super();
+        _name = name;
+        _value = value;
+        _comment = null;
+        _domain = null;
+        _httpOnly = false;
+        _maxAge = maxAge;
+        _path = null;
+        _secure = false;
+        _version = 0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure)
+    {
+        super();
+        _comment = null;
+        _domain = domain;
+        _httpOnly = httpOnly;
+        _maxAge = maxAge;
+        _name = name;
+        _path = path;
+        _secure = secure;
+        _value = value;
+        _version = 0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public HttpCookie(String name, String value, String domain, String path, int maxAge, boolean httpOnly, boolean secure, String comment, int version)
+    {
+        super();
+        _comment = comment;
+        _domain = domain;
+        _httpOnly = httpOnly;
+        _maxAge = maxAge;
+        _name = name;
+        _path = path;
+        _secure = secure;
+        _value = value;
+        _version = version;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the name.
+     * @return the name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the value.
+     * @return the value
+     */
+    public String getValue()
+    {
+        return _value;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the comment.
+     * @return the comment
+     */
+    public String getComment()
+    {
+        return _comment;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the domain.
+     * @return the domain
+     */
+    public String getDomain()
+    {
+        return _domain;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the maxAge.
+     * @return the maxAge
+     */
+    public int getMaxAge()
+    {
+        return _maxAge;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the path.
+     * @return the path
+     */
+    public String getPath()
+    {
+        return _path;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the secure.
+     * @return the secure
+     */
+    public boolean isSecure()
+    {
+        return _secure;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the version.
+     * @return the version
+     */
+    public int getVersion()
+    {
+        return _version;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the isHttpOnly.
+     * @return the isHttpOnly
+     */
+    public boolean isHttpOnly()
+    {
+        return _httpOnly;
+    }
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpException.java b/src/java/org/eclipse/jetty/http/HttpException.java
new file mode 100644
index 0000000..4d01cda
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpException.java
@@ -0,0 +1,94 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+
+public class HttpException extends IOException
+{
+    int _status;
+    String _reason;
+
+    /* ------------------------------------------------------------ */
+    public HttpException(int status)
+    {
+        _status=status;
+        _reason=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public HttpException(int status,String reason)
+    {
+        _status=status;
+        _reason=reason;
+    }
+
+    /* ------------------------------------------------------------ */
+    public HttpException(int status,String reason, Throwable rootCause)
+    {
+        _status=status;
+        _reason=reason;
+        initCause(rootCause);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the reason.
+     */
+    public String getReason()
+    {
+        return _reason;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param reason The reason to set.
+     */
+    public void setReason(String reason)
+    {
+        _reason = reason;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the status.
+     */
+    public int getStatus()
+    {
+        return _status;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param status The status to set.
+     */
+    public void setStatus(int status)
+    {
+        _status = status;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return ("HttpException("+_status+","+_reason+","+super.getCause()+")");
+    }
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpFields.java b/src/java/org/eclipse/jetty/http/HttpFields.java
new file mode 100644
index 0000000..d485956
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpFields.java
@@ -0,0 +1,1406 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.BufferDateCache;
+import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringMap;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * HTTP Fields. A collection of HTTP header and or Trailer fields. 
+ * 
+ * <p>This class is not synchronized as it is expected that modifications will only be performed by a
+ * single thread.
+ * 
+ * 
+ */
+public class HttpFields
+{
+    private static final Logger LOG = Log.getLogger(HttpFields.class);
+    
+    /* ------------------------------------------------------------ */
+    public static final String __COOKIE_DELIM="\"\\\n\r\t\f\b%+ ;=";
+    public static final TimeZone __GMT = TimeZone.getTimeZone("GMT");
+    public static final BufferDateCache __dateCache = new BufferDateCache("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
+
+    /* -------------------------------------------------------------- */
+    static
+    {
+        __GMT.setID("GMT");
+        __dateCache.setTimeZone(__GMT);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public final static String __separators = ", \t";
+
+    /* ------------------------------------------------------------ */
+    private static final String[] DAYS =
+    { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+    private static final String[] MONTHS =
+    { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan"};
+
+    
+    /* ------------------------------------------------------------ */
+    private static class DateGenerator
+    {
+        private final StringBuilder buf = new StringBuilder(32);
+        private final GregorianCalendar gc = new GregorianCalendar(__GMT);
+        
+        /**
+         * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" 
+         */
+        public String formatDate(long date)
+        {
+            buf.setLength(0);
+            gc.setTimeInMillis(date);
+            
+            int day_of_week = gc.get(Calendar.DAY_OF_WEEK);
+            int day_of_month = gc.get(Calendar.DAY_OF_MONTH);
+            int month = gc.get(Calendar.MONTH);
+            int year = gc.get(Calendar.YEAR);
+            int century = year / 100;
+            year = year % 100;
+            
+            int hours = gc.get(Calendar.HOUR_OF_DAY);
+            int minutes = gc.get(Calendar.MINUTE);
+            int seconds = gc.get(Calendar.SECOND);
+
+            buf.append(DAYS[day_of_week]);
+            buf.append(',');
+            buf.append(' ');
+            StringUtil.append2digits(buf, day_of_month);
+
+            buf.append(' ');
+            buf.append(MONTHS[month]);
+            buf.append(' ');
+            StringUtil.append2digits(buf, century);
+            StringUtil.append2digits(buf, year);
+            
+            buf.append(' ');
+            StringUtil.append2digits(buf, hours);
+            buf.append(':');
+            StringUtil.append2digits(buf, minutes);
+            buf.append(':');
+            StringUtil.append2digits(buf, seconds);
+            buf.append(" GMT");
+            return buf.toString();
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Format "EEE, dd-MMM-yy HH:mm:ss 'GMT'" for cookies
+         */
+        public void formatCookieDate(StringBuilder buf, long date)
+        {
+            gc.setTimeInMillis(date);
+            
+            int day_of_week = gc.get(Calendar.DAY_OF_WEEK);
+            int day_of_month = gc.get(Calendar.DAY_OF_MONTH);
+            int month = gc.get(Calendar.MONTH);
+            int year = gc.get(Calendar.YEAR);
+            year = year % 10000;
+
+            int epoch = (int) ((date / 1000) % (60 * 60 * 24));
+            int seconds = epoch % 60;
+            epoch = epoch / 60;
+            int minutes = epoch % 60;
+            int hours = epoch / 60;
+
+            buf.append(DAYS[day_of_week]);
+            buf.append(',');
+            buf.append(' ');
+            StringUtil.append2digits(buf, day_of_month);
+
+            buf.append('-');
+            buf.append(MONTHS[month]);
+            buf.append('-');
+            StringUtil.append2digits(buf, year/100);
+            StringUtil.append2digits(buf, year%100);
+            
+            buf.append(' ');
+            StringUtil.append2digits(buf, hours);
+            buf.append(':');
+            StringUtil.append2digits(buf, minutes);
+            buf.append(':');
+            StringUtil.append2digits(buf, seconds);
+            buf.append(" GMT");
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private static final ThreadLocal<DateGenerator> __dateGenerator =new ThreadLocal<DateGenerator>()
+    {
+        @Override
+        protected DateGenerator initialValue()
+        {
+            return new DateGenerator();
+        }
+    };
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Format HTTP date "EEE, dd MMM yyyy HH:mm:ss 'GMT'" 
+     */
+    public static String formatDate(long date)
+    {
+        return __dateGenerator.get().formatDate(date);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies
+     */
+    public static void formatCookieDate(StringBuilder buf, long date)
+    {
+        __dateGenerator.get().formatCookieDate(buf,date);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Format "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'" for cookies
+     */
+    public static String formatCookieDate(long date)
+    {
+        StringBuilder buf = new StringBuilder(28);
+        formatCookieDate(buf, date);
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    private final static String __dateReceiveFmt[] =
+    {   
+        "EEE, dd MMM yyyy HH:mm:ss zzz", 
+        "EEE, dd-MMM-yy HH:mm:ss",
+        "EEE MMM dd HH:mm:ss yyyy",
+
+        "EEE, dd MMM yyyy HH:mm:ss", "EEE dd MMM yyyy HH:mm:ss zzz", 
+        "EEE dd MMM yyyy HH:mm:ss", "EEE MMM dd yyyy HH:mm:ss zzz", "EEE MMM dd yyyy HH:mm:ss", 
+        "EEE MMM-dd-yyyy HH:mm:ss zzz", "EEE MMM-dd-yyyy HH:mm:ss", "dd MMM yyyy HH:mm:ss zzz", 
+        "dd MMM yyyy HH:mm:ss", "dd-MMM-yy HH:mm:ss zzz", "dd-MMM-yy HH:mm:ss", "MMM dd HH:mm:ss yyyy zzz", 
+        "MMM dd HH:mm:ss yyyy", "EEE MMM dd HH:mm:ss yyyy zzz",  
+        "EEE, MMM dd HH:mm:ss yyyy zzz", "EEE, MMM dd HH:mm:ss yyyy", "EEE, dd-MMM-yy HH:mm:ss zzz", 
+        "EEE dd-MMM-yy HH:mm:ss zzz", "EEE dd-MMM-yy HH:mm:ss",
+    };
+
+    /* ------------------------------------------------------------ */
+    private static class DateParser
+    {
+        final SimpleDateFormat _dateReceive[]= new SimpleDateFormat[__dateReceiveFmt.length];
+ 
+        long parse(final String dateVal)
+        {
+            for (int i = 0; i < _dateReceive.length; i++)
+            {
+                if (_dateReceive[i] == null)
+                {
+                    _dateReceive[i] = new SimpleDateFormat(__dateReceiveFmt[i], Locale.US);
+                    _dateReceive[i].setTimeZone(__GMT);
+                }
+
+                try
+                {
+                    Date date = (Date) _dateReceive[i].parseObject(dateVal);
+                    return date.getTime();
+                }
+                catch (java.lang.Exception e)
+                {
+                    // LOG.ignore(e);
+                }
+            }
+            
+            if (dateVal.endsWith(" GMT"))
+            {
+                final String val = dateVal.substring(0, dateVal.length() - 4);
+
+                for (int i = 0; i < _dateReceive.length; i++)
+                {
+                    try
+                    {
+                        Date date = (Date) _dateReceive[i].parseObject(val);
+                        return date.getTime();
+                    }
+                    catch (java.lang.Exception e)
+                    {
+                        // LOG.ignore(e);
+                    }
+                }
+            }    
+            return -1;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static long parseDate(String date)
+    {
+        return __dateParser.get().parse(date);
+    }
+
+    /* ------------------------------------------------------------ */
+    private static final ThreadLocal<DateParser> __dateParser =new ThreadLocal<DateParser>()
+    {
+        @Override
+        protected DateParser initialValue()
+        {
+            return new DateParser();
+        }
+    };
+
+    /* -------------------------------------------------------------- */
+    public final static String __01Jan1970=formatDate(0);
+    public final static Buffer __01Jan1970_BUFFER=new ByteArrayBuffer(__01Jan1970);
+    public final static String __01Jan1970_COOKIE = formatCookieDate(0).trim();
+
+    /* -------------------------------------------------------------- */
+    private final ArrayList<Field> _fields = new ArrayList<Field>(20);
+    private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructor.
+     */
+    public HttpFields()
+    {
+    }
+
+    // TODO externalize this cache so it can be configurable
+    private static ConcurrentMap<String, Buffer> __cache = new ConcurrentHashMap<String, Buffer>();
+    private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000);
+    
+    /* -------------------------------------------------------------- */
+    private Buffer convertValue(String value)
+    {
+        Buffer buffer = __cache.get(value);
+        if (buffer!=null)
+            return buffer;
+        
+        try
+        {   
+            buffer = new ByteArrayBuffer(value,StringUtil.__ISO_8859_1);
+            
+            if (__cacheSize>0)
+            {
+                if (__cache.size()>__cacheSize)
+                    __cache.clear();
+                Buffer b=__cache.putIfAbsent(value,buffer);
+                if (b!=null)
+                    buffer=b;
+            }
+            
+            return buffer;
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /* -------------------------------------------------------------- */
+    /**
+     * Get Collection of header names. 
+     */
+    public Collection<String> getFieldNamesCollection()
+    {
+        final List<String> list = new ArrayList<String>(_fields.size());
+
+	for (Field f : _fields)
+	{
+	    if (f!=null)
+	        list.add(BufferUtil.to8859_1_String(f._name));
+	}
+	return list;
+    }
+    
+    /* -------------------------------------------------------------- */
+    /**
+     * Get enumeration of header _names. Returns an enumeration of strings representing the header
+     * _names for this request.
+     */
+    public Enumeration<String> getFieldNames()
+    {
+        final Enumeration<?> buffers = Collections.enumeration(_names.keySet());
+        return new Enumeration<String>()
+        {
+            public String nextElement()
+            {
+                return buffers.nextElement().toString();
+            }
+            
+            public boolean hasMoreElements()
+            {
+                return buffers.hasMoreElements();
+            }
+        }; 
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int size()
+    {
+        return _fields.size();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a Field by index.
+     * @return A Field value or null if the Field value has not been set
+     * 
+     */
+    public Field getField(int i)
+    {
+        return _fields.get(i);
+    }
+
+    /* ------------------------------------------------------------ */
+    private Field getField(String name)
+    {
+        return _names.get(HttpHeaders.CACHE.lookup(name));
+    }
+
+    /* ------------------------------------------------------------ */
+    private Field getField(Buffer name)
+    {
+        return _names.get(HttpHeaders.CACHE.lookup(name));
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean containsKey(Buffer name)
+    {
+        return _names.containsKey(HttpHeaders.CACHE.lookup(name));
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean containsKey(String name)
+    {
+        return _names.containsKey(HttpHeaders.CACHE.lookup(name));
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * @return the value of a field, or null if not found. For multiple fields of the same name,
+     *         only the first is returned.
+     * @param name the case-insensitive field name
+     */
+    public String getStringField(String name)
+    {
+        Field field = getField(name);
+        return field==null?null:field.getValue();
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * @return the value of a field, or null if not found. For multiple fields of the same name,
+     *         only the first is returned.
+     * @param name the case-insensitive field name
+     */
+    public String getStringField(Buffer name)
+    {
+        Field field = getField(name);
+        return field==null?null:field.getValue();
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * @return the value of a field, or null if not found. For multiple fields of the same name,
+     *         only the first is returned.
+     * @param name the case-insensitive field name
+     */
+    public Buffer get(Buffer name)
+    {
+        Field field = getField(name);
+        return field==null?null:field._value;
+    }
+
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get multi headers
+     * 
+     * @return Enumeration of the values, or null if no such header.
+     * @param name the case-insensitive field name
+     */
+    public Collection<String> getValuesCollection(String name)
+    {
+        Field field = getField(name);
+	if (field==null)
+	    return null;
+
+        final List<String> list = new ArrayList<String>();
+
+	while(field!=null)
+	{
+	    list.add(field.getValue());
+	    field=field._next;
+	}
+	return list;
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get multi headers
+     * 
+     * @return Enumeration of the values
+     * @param name the case-insensitive field name
+     */
+    public Enumeration<String> getValues(String name)
+    {
+        final Field field = getField(name);
+        if (field == null) 
+        {
+            List<String> empty=Collections.emptyList();
+            return Collections.enumeration(empty);
+        }
+
+        return new Enumeration<String>()
+        {
+            Field f = field;
+
+            public boolean hasMoreElements()
+            {
+                return f != null;
+            }
+
+            public String nextElement() throws NoSuchElementException
+            {
+                if (f == null) throw new NoSuchElementException();
+                Field n = f;
+                f = f._next;
+                return n.getValue();
+            }
+        };
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get multi headers
+     * 
+     * @return Enumeration of the value Strings
+     * @param name the case-insensitive field name
+     */
+    public Enumeration<String> getValues(Buffer name)
+    {
+        final Field field = getField(name);
+        if (field == null) 
+        {
+            List<String> empty=Collections.emptyList();
+            return Collections.enumeration(empty);
+        }
+
+        return new Enumeration<String>()
+        {
+            Field f = field;
+
+            public boolean hasMoreElements()
+            {
+                return f != null;
+            }
+
+            public String nextElement() throws NoSuchElementException
+            {
+                if (f == null) throw new NoSuchElementException();
+                Field n = f;
+                f = f._next;
+                return n.getValue();
+            }
+        };
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get multi field values with separator. The multiple values can be represented as separate
+     * headers of the same name, or by a single header using the separator(s), or a combination of
+     * both. Separators may be quoted.
+     * 
+     * @param name the case-insensitive field name
+     * @param separators String of separators.
+     * @return Enumeration of the values, or null if no such header.
+     */
+    public Enumeration<String> getValues(String name, final String separators)
+    {
+        final Enumeration<String> e = getValues(name);
+        if (e == null) 
+            return null;
+        return new Enumeration<String>()
+        {
+            QuotedStringTokenizer tok = null;
+
+            public boolean hasMoreElements()
+            {
+                if (tok != null && tok.hasMoreElements()) return true;
+                while (e.hasMoreElements())
+                {
+                    String value = e.nextElement();
+                    tok = new QuotedStringTokenizer(value, separators, false, false);
+                    if (tok.hasMoreElements()) return true;
+                }
+                tok = null;
+                return false;
+            }
+
+            public String nextElement() throws NoSuchElementException
+            {
+                if (!hasMoreElements()) throw new NoSuchElementException();
+                String next = (String) tok.nextElement();
+                if (next != null) next = next.trim();
+                return next;
+            }
+        };
+    }
+
+    
+    /* -------------------------------------------------------------- */
+    /**
+     * Set a field.
+     * 
+     * @param name the name of the field
+     * @param value the value of the field. If null the field is cleared.
+     */
+    public void put(String name, String value)
+    {
+        if (value==null)
+            remove(name);
+        else
+        {
+            Buffer n = HttpHeaders.CACHE.lookup(name);
+            Buffer v = convertValue(value);
+            put(n, v);
+        }
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Set a field.
+     * 
+     * @param name the name of the field
+     * @param value the value of the field. If null the field is cleared.
+     */
+    public void put(Buffer name, String value)
+    {
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        Buffer v = convertValue(value);
+        put(n, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Set a field.
+     * 
+     * @param name the name of the field
+     * @param value the value of the field. If null the field is cleared.
+     */
+    public void put(Buffer name, Buffer value)
+    {
+        remove(name);
+        if (value == null)
+            return;
+
+        if (!(name instanceof BufferCache.CachedBuffer)) 
+            name = HttpHeaders.CACHE.lookup(name);
+        if (!(value instanceof CachedBuffer))
+            value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer();
+        
+        // new value;
+        Field field = new Field(name, value);
+        _fields.add(field);
+        _names.put(name, field);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Set a field.
+     * 
+     * @param name the name of the field
+     * @param list the List value of the field. If null the field is cleared.
+     */
+    public void put(String name, List<?> list)
+    {
+        if (list == null || list.size() == 0)
+        {
+            remove(name);
+            return;
+        }
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+
+        Object v = list.get(0);
+        if (v != null)
+            put(n, HttpHeaderValues.CACHE.lookup(v.toString()));
+        else
+            remove(n);
+
+        if (list.size() > 1)
+        {
+            java.util.Iterator<?> iter = list.iterator();
+            iter.next();
+            while (iter.hasNext())
+            {
+                v = iter.next();
+                if (v != null) put(n, HttpHeaderValues.CACHE.lookup(v.toString()));
+            }
+        }
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Add to or set a field. If the field is allowed to have multiple values, add will add multiple
+     * headers of the same name.
+     * 
+     * @param name the name of the field
+     * @param value the value of the field.
+     * @exception IllegalArgumentException If the name is a single valued field and already has a
+     *                value.
+     */
+    public void add(String name, String value) throws IllegalArgumentException
+    {
+        if (value==null)
+            return;
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        Buffer v = convertValue(value);
+        add(n, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Add to or set a field. If the field is allowed to have multiple values, add will add multiple
+     * headers of the same name.
+     * 
+     * @param name the name of the field
+     * @param value the value of the field.
+     * @exception IllegalArgumentException If the name is a single valued field and already has a
+     *                value.
+     */
+    public void add(Buffer name, Buffer value) throws IllegalArgumentException
+    {   
+        if (value == null) throw new IllegalArgumentException("null value");
+
+        if (!(name instanceof CachedBuffer))
+            name = HttpHeaders.CACHE.lookup(name);
+        name=name.asImmutableBuffer();
+        
+        if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name)))
+            value= HttpHeaderValues.CACHE.lookup(value);
+        value=value.asImmutableBuffer();
+        
+        Field field = _names.get(name);
+        Field last = null;
+        while (field != null)
+        {
+            last = field;
+            field = field._next;
+        }
+
+        // create the field
+        field = new Field(name, value);
+        _fields.add(field);
+
+        // look for chain to add too
+        if (last != null)
+            last._next = field;
+        else
+            _names.put(name, field);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Remove a field.
+     * 
+     * @param name
+     */
+    public void remove(String name)
+    {
+        remove(HttpHeaders.CACHE.lookup(name));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Remove a field.
+     * 
+     * @param name
+     */
+    public void remove(Buffer name)
+    {
+        if (!(name instanceof BufferCache.CachedBuffer)) 
+            name = HttpHeaders.CACHE.lookup(name);
+        Field field = _names.remove(name);
+        while (field != null)
+        {
+            _fields.remove(field);
+            field = field._next;
+        }
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get a header as an long value. Returns the value of an integer field or -1 if not found. The
+     * case of the field name is ignored.
+     * 
+     * @param name the case-insensitive field name
+     * @exception NumberFormatException If bad long found
+     */
+    public long getLongField(String name) throws NumberFormatException
+    {
+        Field field = getField(name);
+        return field==null?-1L:field.getLongValue();
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get a header as an long value. Returns the value of an integer field or -1 if not found. The
+     * case of the field name is ignored.
+     * 
+     * @param name the case-insensitive field name
+     * @exception NumberFormatException If bad long found
+     */
+    public long getLongField(Buffer name) throws NumberFormatException
+    {
+        Field field = getField(name);
+        return field==null?-1L:field.getLongValue();
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Get a header as a date value. Returns the value of a date field, or -1 if not found. The case
+     * of the field name is ignored.
+     * 
+     * @param name the case-insensitive field name
+     */
+    public long getDateField(String name)
+    {
+        Field field = getField(name);
+        if (field == null) 
+            return -1;
+
+        String val = valueParameters(BufferUtil.to8859_1_String(field._value), null);
+        if (val == null) 
+            return -1;
+
+        final long date = __dateParser.get().parse(val);
+        if (date==-1)
+            throw new IllegalArgumentException("Cannot convert date: " + val);
+        return date;
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of an long field.
+     * 
+     * @param name the field name
+     * @param value the field long value
+     */
+    public void putLongField(Buffer name, long value)
+    {
+        Buffer v = BufferUtil.toBuffer(value);
+        put(name, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of an long field.
+     * 
+     * @param name the field name
+     * @param value the field long value
+     */
+    public void putLongField(String name, long value)
+    {
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        Buffer v = BufferUtil.toBuffer(value);
+        put(n, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of an long field.
+     * 
+     * @param name the field name
+     * @param value the field long value
+     */
+    public void addLongField(String name, long value)
+    {
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        Buffer v = BufferUtil.toBuffer(value);
+        add(n, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of an long field.
+     * 
+     * @param name the field name
+     * @param value the field long value
+     */
+    public void addLongField(Buffer name, long value)
+    {
+        Buffer v = BufferUtil.toBuffer(value);
+        add(name, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of a date field.
+     * 
+     * @param name the field name
+     * @param date the field date value
+     */
+    public void putDateField(Buffer name, long date)
+    {
+        String d=formatDate(date);
+        Buffer v = new ByteArrayBuffer(d);
+        put(name, v);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of a date field.
+     * 
+     * @param name the field name
+     * @param date the field date value
+     */
+    public void putDateField(String name, long date)
+    {
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        putDateField(n,date);
+    }
+
+    /* -------------------------------------------------------------- */
+    /**
+     * Sets the value of a date field.
+     * 
+     * @param name the field name
+     * @param date the field date value
+     */
+    public void addDateField(String name, long date)
+    {
+        String d=formatDate(date);
+        Buffer n = HttpHeaders.CACHE.lookup(name);
+        Buffer v = new ByteArrayBuffer(d);
+        add(n, v);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Format a set cookie value
+     * 
+     * @param cookie The cookie.
+     */
+    public void addSetCookie(HttpCookie cookie)
+    {
+        addSetCookie(
+                cookie.getName(),
+                cookie.getValue(),
+                cookie.getDomain(),
+                cookie.getPath(),
+                cookie.getMaxAge(),
+                cookie.getComment(),
+                cookie.isSecure(),
+                cookie.isHttpOnly(),
+                cookie.getVersion());
+    }
+
+    /**
+     * Format a set cookie value
+     * 
+     * @param name the name
+     * @param value the value
+     * @param domain the domain
+     * @param path the path
+     * @param maxAge the maximum age
+     * @param comment the comment (only present on versions > 0)
+     * @param isSecure true if secure cookie
+     * @param isHttpOnly true if for http only
+     * @param version version of cookie logic to use (0 == default behavior)
+     */
+    public void addSetCookie(
+            final String name, 
+            final String value, 
+            final String domain,
+            final String path, 
+            final long maxAge,
+            final String comment, 
+            final boolean isSecure,
+            final boolean isHttpOnly, 
+            int version)
+    {
+    	String delim=__COOKIE_DELIM;
+    	
+        // Check arguments
+        if (name == null || name.length() == 0) 
+            throw new IllegalArgumentException("Bad cookie name");
+
+        // Format value and params
+        StringBuilder buf = new StringBuilder(128);
+        String name_value_params;
+        QuotedStringTokenizer.quoteIfNeeded(buf, name, delim);
+        buf.append('=');
+        String start=buf.toString();
+        boolean hasDomain = false;
+        boolean hasPath = false;
+        
+        if (value != null && value.length() > 0)
+            QuotedStringTokenizer.quoteIfNeeded(buf, value, delim);        
+
+        if (comment != null && comment.length() > 0)
+        {
+            buf.append(";Comment=");
+            QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim);
+        }
+
+        if (path != null && path.length() > 0)
+        {
+            hasPath = true;
+            buf.append(";Path=");
+            if (path.trim().startsWith("\""))
+                buf.append(path);
+            else
+                QuotedStringTokenizer.quoteIfNeeded(buf,path,delim);
+        }
+        if (domain != null && domain.length() > 0)
+        {
+            hasDomain = true;
+            buf.append(";Domain=");
+            QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(Locale.ENGLISH),delim);
+        }
+
+        if (maxAge >= 0)
+        {
+            // Always add the expires param as some browsers still don't handle max-age
+            buf.append(";Expires=");
+            if (maxAge == 0)
+                buf.append(__01Jan1970_COOKIE);
+            else
+                formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge);
+
+            if (version >0)
+            {
+                buf.append(";Max-Age=");
+                buf.append(maxAge);
+            }
+        }
+
+        if (isSecure)
+            buf.append(";Secure");
+        if (isHttpOnly) 
+            buf.append(";HttpOnly");
+
+        name_value_params = buf.toString();
+        
+        // remove existing set-cookie of same name
+        Field field = getField(HttpHeaders.SET_COOKIE);
+        Field last=null;
+        while (field!=null)
+        {
+            String val = (field._value == null ? null : field._value.toString());
+            if (val!=null && val.startsWith(start))
+            {
+                //existing cookie has same name, does it also match domain and path?
+                if (((!hasDomain && !val.contains("Domain")) || (hasDomain && val.contains("Domain="+domain))) &&
+                    ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path="+path))))
+                {
+                    _fields.remove(field);
+                    if (last==null)
+                        _names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next);
+                    else
+                        last._next=field._next;
+                    break;
+                }
+            }
+            last=field;
+            field=field._next;
+        }
+
+        add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params));
+        
+        // Expire responses with set-cookie headers so they do not get cached.
+        put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER);
+    }
+
+    /* -------------------------------------------------------------- */
+    public void putTo(Buffer buffer) throws IOException
+    {
+        for (int i = 0; i < _fields.size(); i++)
+        {
+            Field field = _fields.get(i);
+            if (field != null) 
+                field.putTo(buffer);
+        }
+        BufferUtil.putCRLF(buffer);
+    }
+
+    /* -------------------------------------------------------------- */
+    public String toString()
+    {
+        try
+        {
+            StringBuffer buffer = new StringBuffer();
+            for (int i = 0; i < _fields.size(); i++)
+            {
+                Field field = (Field) _fields.get(i);
+                if (field != null)
+                {
+                    String tmp = field.getName();
+                    if (tmp != null) buffer.append(tmp);
+                    buffer.append(": ");
+                    tmp = field.getValue();
+                    if (tmp != null) buffer.append(tmp);
+                    buffer.append("\r\n");
+                }
+            }
+            buffer.append("\r\n");
+            return buffer.toString();
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+            return e.toString();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Clear the header.
+     */
+    public void clear()
+    {
+        _fields.clear();
+        _names.clear();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add fields from another HttpFields instance. Single valued fields are replaced, while all
+     * others are added.
+     * 
+     * @param fields
+     */
+    public void add(HttpFields fields)
+    {
+        if (fields == null) return;
+
+        Enumeration e = fields.getFieldNames();
+        while (e.hasMoreElements())
+        {
+            String name = (String) e.nextElement();
+            Enumeration values = fields.getValues(name);
+            while (values.hasMoreElements())
+                add(name, (String) values.nextElement());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get field value parameters. Some field values can have parameters. This method separates the
+     * value from the parameters and optionally populates a map with the parameters. For example:
+     * 
+     * <PRE>
+     * 
+     * FieldName : Value ; param1=val1 ; param2=val2
+     * 
+     * </PRE>
+     * 
+     * @param value The Field value, possibly with parameteres.
+     * @param parameters A map to populate with the parameters, or null
+     * @return The value.
+     */
+    public static String valueParameters(String value, Map<String,String> parameters)
+    {
+        if (value == null) return null;
+
+        int i = value.indexOf(';');
+        if (i < 0) return value;
+        if (parameters == null) return value.substring(0, i).trim();
+
+        StringTokenizer tok1 = new QuotedStringTokenizer(value.substring(i), ";", false, true);
+        while (tok1.hasMoreTokens())
+        {
+            String token = tok1.nextToken();
+            StringTokenizer tok2 = new QuotedStringTokenizer(token, "= ");
+            if (tok2.hasMoreTokens())
+            {
+                String paramName = tok2.nextToken();
+                String paramVal = null;
+                if (tok2.hasMoreTokens()) paramVal = tok2.nextToken();
+                parameters.put(paramName, paramVal);
+            }
+        }
+
+        return value.substring(0, i).trim();
+    }
+
+    /* ------------------------------------------------------------ */
+    private static final Float __one = new Float("1.0");
+    private static final Float __zero = new Float("0.0");
+    private static final StringMap __qualities = new StringMap();
+    static
+    {
+        __qualities.put(null, __one);
+        __qualities.put("1.0", __one);
+        __qualities.put("1", __one);
+        __qualities.put("0.9", new Float("0.9"));
+        __qualities.put("0.8", new Float("0.8"));
+        __qualities.put("0.7", new Float("0.7"));
+        __qualities.put("0.66", new Float("0.66"));
+        __qualities.put("0.6", new Float("0.6"));
+        __qualities.put("0.5", new Float("0.5"));
+        __qualities.put("0.4", new Float("0.4"));
+        __qualities.put("0.33", new Float("0.33"));
+        __qualities.put("0.3", new Float("0.3"));
+        __qualities.put("0.2", new Float("0.2"));
+        __qualities.put("0.1", new Float("0.1"));
+        __qualities.put("0", __zero);
+        __qualities.put("0.0", __zero);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static Float getQuality(String value)
+    {
+        if (value == null) return __zero;
+
+        int qe = value.indexOf(";");
+        if (qe++ < 0 || qe == value.length()) return __one;
+
+        if (value.charAt(qe++) == 'q')
+        {
+            qe++;
+            Map.Entry entry = __qualities.getEntry(value, qe, value.length() - qe);
+            if (entry != null) return (Float) entry.getValue();
+        }
+
+        HashMap params = new HashMap(3);
+        valueParameters(value, params);
+        String qs = (String) params.get("q");
+        Float q = (Float) __qualities.get(qs);
+        if (q == null)
+        {
+            try
+            {
+                q = new Float(qs);
+            }
+            catch (Exception e)
+            {
+                q = __one;
+            }
+        }
+        return q;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * List values in quality order.
+     * 
+     * @param e Enumeration of values with quality parameters
+     * @return values in quality order.
+     */
+    public static List qualityList(Enumeration e)
+    {
+        if (e == null || !e.hasMoreElements()) return Collections.EMPTY_LIST;
+
+        Object list = null;
+        Object qual = null;
+
+        // Assume list will be well ordered and just add nonzero
+        while (e.hasMoreElements())
+        {
+            String v = e.nextElement().toString();
+            Float q = getQuality(v);
+
+            if (q.floatValue() >= 0.001)
+            {
+                list = LazyList.add(list, v);
+                qual = LazyList.add(qual, q);
+            }
+        }
+
+        List vl = LazyList.getList(list, false);
+        if (vl.size() < 2) return vl;
+
+        List ql = LazyList.getList(qual, false);
+
+        // sort list with swaps
+        Float last = __zero;
+        for (int i = vl.size(); i-- > 0;)
+        {
+            Float q = (Float) ql.get(i);
+            if (last.compareTo(q) > 0)
+            {
+                Object tmp = vl.get(i);
+                vl.set(i, vl.get(i + 1));
+                vl.set(i + 1, tmp);
+                ql.set(i, ql.get(i + 1));
+                ql.set(i + 1, q);
+                last = __zero;
+                i = vl.size();
+                continue;
+            }
+            last = q;
+        }
+        ql.clear();
+        return vl;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static final class Field
+    {
+        private Buffer _name;
+        private Buffer _value;
+        private Field _next;
+
+        /* ------------------------------------------------------------ */
+        private Field(Buffer name, Buffer value)
+        {
+            _name = name;
+            _value = value;
+            _next = null;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public void putTo(Buffer buffer) throws IOException
+        {
+            int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1;
+            if (o>=0)
+                buffer.put(_name);
+            else
+            {
+                int s=_name.getIndex();
+                int e=_name.putIndex();
+                while (s<e)
+                {
+                    byte b=_name.peek(s++);
+                    switch(b)
+                    {
+                        case '\r':
+                        case '\n':
+                        case ':' :
+                            continue;
+                        default:
+                            buffer.put(b);
+                    }
+                }
+            }
+            
+            buffer.put((byte) ':');
+            buffer.put((byte) ' ');
+            
+            o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1;
+            if (o>=0)
+                buffer.put(_value);
+            else
+            {
+                int s=_value.getIndex();
+                int e=_value.putIndex();
+                while (s<e)
+                {
+                    byte b=_value.peek(s++);
+                    switch(b)
+                    {
+                        case '\r':
+                        case '\n':
+                            continue;
+                        default:
+                            buffer.put(b);
+                    }
+                }
+            }
+
+            BufferUtil.putCRLF(buffer);
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getName()
+        {
+            return BufferUtil.to8859_1_String(_name);
+        }
+
+        /* ------------------------------------------------------------ */
+        Buffer getNameBuffer()
+        {
+            return _name;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getNameOrdinal()
+        {
+            return HttpHeaders.CACHE.getOrdinal(_name);
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getValue()
+        {
+            return BufferUtil.to8859_1_String(_value);
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getValueBuffer()
+        {
+            return _value;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getValueOrdinal()
+        {
+            return HttpHeaderValues.CACHE.getOrdinal(_value);
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getIntValue()
+        {
+            return (int) getLongValue();
+        }
+
+        /* ------------------------------------------------------------ */
+        public long getLongValue()
+        {
+            return BufferUtil.toLong(_value);
+        }
+
+        /* ------------------------------------------------------------ */
+        public String toString()
+        {
+            return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]");
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpGenerator.java b/src/java/org/eclipse/jetty/http/HttpGenerator.java
new file mode 100644
index 0000000..3a234f7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpGenerator.java
@@ -0,0 +1,1092 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * HttpGenerator. Builds HTTP Messages.
+ *
+ *
+ *
+ */
+public class HttpGenerator extends AbstractGenerator
+{
+    private static final Logger LOG = Log.getLogger(HttpGenerator.class);
+
+    // Build cache of response lines for status
+    private static class Status
+    {
+        Buffer _reason;
+        Buffer _schemeCode;
+        Buffer _responseLine;
+    }
+    private static final Status[] __status = new Status[HttpStatus.MAX_CODE+1];
+    static
+    {
+        int versionLength=HttpVersions.HTTP_1_1_BUFFER.length();
+
+        for (int i=0;i<__status.length;i++)
+        {
+            HttpStatus.Code code = HttpStatus.getCode(i);
+            if (code==null)
+                continue;
+            String reason=code.getMessage();
+            byte[] bytes=new byte[versionLength+5+reason.length()+2];
+            HttpVersions.HTTP_1_1_BUFFER.peek(0,bytes, 0, versionLength);
+            bytes[versionLength+0]=' ';
+            bytes[versionLength+1]=(byte)('0'+i/100);
+            bytes[versionLength+2]=(byte)('0'+(i%100)/10);
+            bytes[versionLength+3]=(byte)('0'+(i%10));
+            bytes[versionLength+4]=' ';
+            for (int j=0;j<reason.length();j++)
+                bytes[versionLength+5+j]=(byte)reason.charAt(j);
+            bytes[versionLength+5+reason.length()]=HttpTokens.CARRIAGE_RETURN;
+            bytes[versionLength+6+reason.length()]=HttpTokens.LINE_FEED;
+
+            __status[i] = new Status();
+            __status[i]._reason=new ByteArrayBuffer(bytes,versionLength+5,bytes.length-versionLength-7,Buffer.IMMUTABLE);
+            __status[i]._schemeCode=new ByteArrayBuffer(bytes,0,versionLength+5,Buffer.IMMUTABLE);
+            __status[i]._responseLine=new ByteArrayBuffer(bytes,0,bytes.length,Buffer.IMMUTABLE);
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public static Buffer getReasonBuffer(int code)
+    {
+        Status status = code<__status.length?__status[code]:null;
+        if (status!=null)
+            return status._reason;
+        return null;
+    }
+
+
+    // common _content
+    private static final byte[] LAST_CHUNK =
+    { (byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'};
+    private static final byte[] CONTENT_LENGTH_0 = StringUtil.getBytes("Content-Length: 0\015\012");
+    private static final byte[] CONNECTION_KEEP_ALIVE = StringUtil.getBytes("Connection: keep-alive\015\012");
+    private static final byte[] CONNECTION_CLOSE = StringUtil.getBytes("Connection: close\015\012");
+    private static final byte[] CONNECTION_ = StringUtil.getBytes("Connection: ");
+    private static final byte[] CRLF = StringUtil.getBytes("\015\012");
+    private static final byte[] TRANSFER_ENCODING_CHUNKED = StringUtil.getBytes("Transfer-Encoding: chunked\015\012");
+    private static byte[] SERVER = StringUtil.getBytes("Server: Jetty(7.0.x)\015\012");
+
+    // other statics
+    private static final int CHUNK_SPACE = 12;
+
+    public static void setServerVersion(String version)
+    {
+        SERVER=StringUtil.getBytes("Server: Jetty("+version+")\015\012");
+    }
+
+    // data
+    protected boolean _bypass = false; // True if _content buffer can be written directly to endp and bypass the content buffer
+    private boolean _needCRLF = false;
+    private boolean _needEOC = false;
+    private boolean _bufferChunked = false;
+
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Constructor.
+     *
+     * @param buffers buffer pool
+     * @param io the end point to use
+     */
+    public HttpGenerator(Buffers buffers, EndPoint io)
+    {
+        super(buffers,io);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void reset()
+    {
+        if (_persistent!=null && !_persistent && _endp!=null && !_endp.isOutputShutdown())
+        {
+            try
+            {
+                _endp.shutdownOutput();
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+        super.reset();
+        if (_buffer!=null)
+            _buffer.clear();
+        if (_header!=null)
+            _header.clear();
+        if (_content!=null)
+            _content=null;
+        _bypass = false;
+        _needCRLF = false;
+        _needEOC = false;
+        _bufferChunked=false;
+        _method=null;
+        _uri=null;
+        _noContent=false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add content.
+     *
+     * @param content
+     * @param last
+     * @throws IllegalArgumentException if <code>content</code> is {@link Buffer#isImmutable immutable}.
+     * @throws IllegalStateException If the request is not expecting any more content,
+     *   or if the buffers are full and cannot be flushed.
+     * @throws IOException if there is a problem flushing the buffers.
+     */
+    public void addContent(Buffer content, boolean last) throws IOException
+    {
+        if (_noContent)
+            throw new IllegalStateException("NO CONTENT");
+
+        if (_last || _state==STATE_END)
+        {
+            LOG.warn("Ignoring extra content {}",content);
+            content.clear();
+            return;
+        }
+        _last = last;
+
+        // Handle any unfinished business?
+        if (_content!=null && _content.length()>0 || _bufferChunked)
+        {
+            if (_endp.isOutputShutdown())
+                throw new EofException();
+            flushBuffer();
+            if (_content != null && _content.length()>0)
+            {
+                if (_bufferChunked)
+                {
+                    Buffer nc=_buffers.getBuffer(_content.length()+CHUNK_SPACE+content.length());
+                    nc.put(_content);
+                    nc.put(HttpTokens.CRLF);
+                    BufferUtil.putHexInt(nc, content.length());
+                    nc.put(HttpTokens.CRLF);
+                    nc.put(content);
+                    content=nc;
+                }
+                else
+                {
+                    Buffer nc=_buffers.getBuffer(_content.length()+content.length());
+                    nc.put(_content);
+                    nc.put(content);
+                    content=nc;
+                }
+            }
+        }
+
+        _content = content;
+        _contentWritten += content.length();
+
+        // Handle the _content
+        if (_head)
+        {
+            content.clear();
+            _content=null;
+        }
+        else if (_endp != null && (_buffer==null || _buffer.length()==0) && _content.length() > 0 && (_last || isCommitted() && _content.length()>1024))
+        {
+            _bypass = true;
+        }
+        else if (!_bufferChunked)
+        {
+            // Yes - so we better check we have a buffer
+            if (_buffer == null)
+                _buffer = _buffers.getBuffer();
+
+            // Copy _content to buffer;
+            int len=_buffer.put(_content);
+            _content.skip(len);
+            if (_content.length() == 0)
+                _content = null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * send complete response.
+     *
+     * @param response
+     */
+    public void sendResponse(Buffer response) throws IOException
+    {
+        if (_noContent || _state!=STATE_HEADER || _content!=null && _content.length()>0 || _bufferChunked || _head )
+            throw new IllegalStateException();
+
+        _last = true;
+
+        _content = response;
+        _bypass = true;
+        _state = STATE_FLUSHING;
+
+        // TODO this is not exactly right, but should do.
+        _contentLength =_contentWritten = response.length();
+
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Prepare buffer for unchecked writes.
+     * Prepare the generator buffer to receive unchecked writes
+     * @return the available space in the buffer.
+     * @throws IOException
+     */
+    @Override
+    public int prepareUncheckedAddContent() throws IOException
+    {
+        if (_noContent)
+            return -1;
+
+        if (_last || _state==STATE_END)
+            return -1;
+
+        // Handle any unfinished business?
+        Buffer content = _content;
+        if (content != null && content.length()>0 || _bufferChunked)
+        {
+            flushBuffer();
+            if (content != null && content.length()>0 || _bufferChunked)
+                throw new IllegalStateException("FULL");
+        }
+
+        // we better check we have a buffer
+        if (_buffer == null)
+            _buffer = _buffers.getBuffer();
+
+        _contentWritten-=_buffer.length();
+
+        // Handle the _content
+        if (_head)
+            return Integer.MAX_VALUE;
+
+        return _buffer.space()-(_contentLength == HttpTokens.CHUNKED_CONTENT?CHUNK_SPACE:0);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isBufferFull()
+    {
+        // Should we flush the buffers?
+        return super.isBufferFull() || _bufferChunked || _bypass  || (_contentLength == HttpTokens.CHUNKED_CONTENT && _buffer != null && _buffer.space() < CHUNK_SPACE);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void send1xx(int code) throws IOException
+    {
+        if (_state != STATE_HEADER)
+            return;
+
+        if (code<100||code>199)
+            throw new IllegalArgumentException("!1xx");
+        Status status=__status[code];
+        if (status==null)
+            throw new IllegalArgumentException(code+"?");
+
+        // get a header buffer
+        if (_header == null)
+            _header = _buffers.getHeader();
+
+        _header.put(status._responseLine);
+        _header.put(HttpTokens.CRLF);
+
+        try
+        {
+            // nasty semi busy flush!
+            while(_header.length()>0)
+            {
+                int len = _endp.flush(_header);
+                if (len<0)
+                    throw new EofException();
+                if (len==0)
+                    Thread.sleep(100);
+            }
+        }
+        catch(InterruptedException e)
+        {
+            LOG.debug(e);
+            throw new InterruptedIOException(e.toString());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isRequest()
+    {
+        return _method!=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isResponse()
+    {
+        return _method==null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void completeHeader(HttpFields fields, boolean allContentAdded) throws IOException
+    {
+        if (_state != STATE_HEADER)
+            return;
+
+        // handle a reset
+        if (isResponse() && _status==0)
+            throw new EofException();
+
+        if (_last && !allContentAdded)
+            throw new IllegalStateException("last?");
+        _last = _last | allContentAdded;
+
+        // get a header buffer
+        if (_header == null)
+            _header = _buffers.getHeader();
+
+        boolean has_server = false;
+
+        try
+        {
+            if (isRequest())
+            {
+                _persistent=true;
+
+                if (_version == HttpVersions.HTTP_0_9_ORDINAL)
+                {
+                    _contentLength = HttpTokens.NO_CONTENT;
+                    _header.put(_method);
+                    _header.put((byte)' ');
+                    _header.put(_uri.getBytes("UTF-8")); // TODO check
+                    _header.put(HttpTokens.CRLF);
+                    _state = STATE_FLUSHING;
+                    _noContent=true;
+                    return;
+                }
+                else
+                {
+                    _header.put(_method);
+                    _header.put((byte)' ');
+                    _header.put(_uri.getBytes("UTF-8")); // TODO check
+                    _header.put((byte)' ');
+                    _header.put(_version==HttpVersions.HTTP_1_0_ORDINAL?HttpVersions.HTTP_1_0_BUFFER:HttpVersions.HTTP_1_1_BUFFER);
+                    _header.put(HttpTokens.CRLF);
+                }
+            }
+            else
+            {
+                // Responses
+                if (_version == HttpVersions.HTTP_0_9_ORDINAL)
+                {
+                    _persistent = false;
+                    _contentLength = HttpTokens.EOF_CONTENT;
+                    _state = STATE_CONTENT;
+                    return;
+                }
+                else
+                {
+                    if (_persistent==null)
+                        _persistent= (_version > HttpVersions.HTTP_1_0_ORDINAL);
+
+                    // add response line
+                    Status status = _status<__status.length?__status[_status]:null;
+
+                    if (status==null)
+                    {
+                        _header.put(HttpVersions.HTTP_1_1_BUFFER);
+                        _header.put((byte) ' ');
+                        _header.put((byte) ('0' + _status / 100));
+                        _header.put((byte) ('0' + (_status % 100) / 10));
+                        _header.put((byte) ('0' + (_status % 10)));
+                        _header.put((byte) ' ');
+                        if (_reason==null)
+                        {
+                            _header.put((byte) ('0' + _status / 100));
+                            _header.put((byte) ('0' + (_status % 100) / 10));
+                            _header.put((byte) ('0' + (_status % 10)));
+                        }
+                        else
+                            _header.put(_reason);
+                        _header.put(HttpTokens.CRLF);
+                    }
+                    else
+                    {
+                        if (_reason==null)
+                            _header.put(status._responseLine);
+                        else
+                        {
+                            _header.put(status._schemeCode);
+                            _header.put(_reason);
+                            _header.put(HttpTokens.CRLF);
+                        }
+                    }
+
+                    if (_status<200 && _status>=100 )
+                    {
+                        _noContent=true;
+                        _content=null;
+                        if (_buffer!=null)
+                            _buffer.clear();
+                        // end the header.
+
+                        if (_status!=101 )
+                        {
+                            _header.put(HttpTokens.CRLF);
+                            _state = STATE_CONTENT;
+                            return;
+                        }
+                    }
+                    else if (_status==204 || _status==304)
+                    {
+                        _noContent=true;
+                        _content=null;
+                        if (_buffer!=null)
+                            _buffer.clear();
+                    }
+                }
+            }
+
+            // Add headers
+            if (_status>=200 && _date!=null)
+            {
+                _header.put(HttpHeaders.DATE_BUFFER);
+                _header.put((byte)':');
+                _header.put((byte)' ');
+                _header.put(_date);
+                _header.put(CRLF);
+            }
+
+            // key field values
+            HttpFields.Field content_length = null;
+            HttpFields.Field transfer_encoding = null;
+            boolean keep_alive = false;
+            boolean close=false;
+            boolean content_type=false;
+            StringBuilder connection = null;
+
+            if (fields != null)
+            {
+                int s=fields.size();
+                for (int f=0;f<s;f++)
+                {
+                    HttpFields.Field field = fields.getField(f);
+                    if (field==null)
+                        continue;
+
+                    switch (field.getNameOrdinal())
+                    {
+                        case HttpHeaders.CONTENT_LENGTH_ORDINAL:
+                            content_length = field;
+                            _contentLength = field.getLongValue();
+
+                            if (_contentLength < _contentWritten || _last && _contentLength != _contentWritten)
+                                content_length = null;
+
+                            // write the field to the header buffer
+                            field.putTo(_header);
+                            break;
+
+                        case HttpHeaders.CONTENT_TYPE_ORDINAL:
+                            if (BufferUtil.isPrefix(MimeTypes.MULTIPART_BYTERANGES_BUFFER, field.getValueBuffer())) _contentLength = HttpTokens.SELF_DEFINING_CONTENT;
+
+                            // write the field to the header buffer
+                            content_type=true;
+                            field.putTo(_header);
+                            break;
+
+                        case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
+                            if (_version == HttpVersions.HTTP_1_1_ORDINAL)
+                                transfer_encoding = field;
+                            // Do NOT add yet!
+                            break;
+
+                        case HttpHeaders.CONNECTION_ORDINAL:
+                            if (isRequest())
+                                field.putTo(_header);
+
+                            int connection_value = field.getValueOrdinal();
+                            switch (connection_value)
+                            {
+                                case -1:
+                                {
+                                    String[] values = field.getValue().split(",");
+                                    for  (int i=0;values!=null && i<values.length;i++)
+                                    {
+                                        CachedBuffer cb = HttpHeaderValues.CACHE.get(values[i].trim());
+
+                                        if (cb!=null)
+                                        {
+                                            switch(cb.getOrdinal())
+                                            {
+                                                case HttpHeaderValues.CLOSE_ORDINAL:
+                                                    close=true;
+                                                    if (isResponse())
+                                                        _persistent=false;
+                                                    keep_alive=false;
+                                                    if (!_persistent && isResponse() && _contentLength == HttpTokens.UNKNOWN_CONTENT)
+                                                        _contentLength = HttpTokens.EOF_CONTENT;
+                                                    break;
+
+                                                case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
+                                                    if (_version == HttpVersions.HTTP_1_0_ORDINAL)
+                                                    {
+                                                        keep_alive = true;
+                                                        if (isResponse())
+                                                            _persistent = true;
+                                                    }
+                                                    break;
+
+                                                default:
+                                                    if (connection==null)
+                                                        connection=new StringBuilder();
+                                                    else
+                                                        connection.append(',');
+                                                    connection.append(values[i]);
+                                            }
+                                        }
+                                        else
+                                        {
+                                            if (connection==null)
+                                                connection=new StringBuilder();
+                                            else
+                                                connection.append(',');
+                                            connection.append(values[i]);
+                                        }
+                                    }
+
+                                    break;
+                                }
+                                case HttpHeaderValues.UPGRADE_ORDINAL:
+                                {
+                                    // special case for websocket connection ordering
+                                    if (isResponse())
+                                    {
+                                        field.putTo(_header);
+                                        continue;
+                                    }
+                                }
+                                case HttpHeaderValues.CLOSE_ORDINAL:
+                                {
+                                    close=true;
+                                    if (isResponse())
+                                        _persistent=false;
+                                    if (!_persistent && isResponse() && _contentLength == HttpTokens.UNKNOWN_CONTENT)
+                                        _contentLength = HttpTokens.EOF_CONTENT;
+                                    break;
+                                }
+                                case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
+                                {
+                                    if (_version == HttpVersions.HTTP_1_0_ORDINAL)
+                                    {
+                                        keep_alive = true;
+                                        if (isResponse())
+                                            _persistent=true;
+                                    }
+                                    break;
+                                }
+                                default:
+                                {
+                                    if (connection==null)
+                                        connection=new StringBuilder();
+                                    else
+                                        connection.append(',');
+                                    connection.append(field.getValue());
+                                }
+                            }
+
+                            // Do NOT add yet!
+                            break;
+
+                        case HttpHeaders.SERVER_ORDINAL:
+                            if (getSendServerVersion())
+                            {
+                                has_server=true;
+                                field.putTo(_header);
+                            }
+                            break;
+
+                        default:
+                            // write the field to the header buffer
+                            field.putTo(_header);
+                    }
+                }
+            }
+
+            // Calculate how to end _content and connection, _content length and transfer encoding
+            // settings.
+            // From RFC 2616 4.4:
+            // 1. No body for 1xx, 204, 304 & HEAD response
+            // 2. Force _content-length?
+            // 3. If Transfer-Encoding!=identity && HTTP/1.1 && !HttpConnection==close then chunk
+            // 4. Content-Length
+            // 5. multipart/byteranges
+            // 6. close
+            switch ((int) _contentLength)
+            {
+                case HttpTokens.UNKNOWN_CONTENT:
+                    // It may be that we have no _content, or perhaps _content just has not been
+                    // written yet?
+
+                    // Response known not to have a body
+                    if (_contentWritten == 0 && isResponse() && (_status < 200 || _status == 204 || _status == 304))
+                        _contentLength = HttpTokens.NO_CONTENT;
+                    else if (_last)
+                    {
+                        // we have seen all the _content there is
+                        _contentLength = _contentWritten;
+                        if (content_length == null && (isResponse() || _contentLength>0 || content_type ) && !_noContent)
+                        {
+                            // known length but not actually set.
+                            _header.put(HttpHeaders.CONTENT_LENGTH_BUFFER);
+                            _header.put(HttpTokens.COLON);
+                            _header.put((byte) ' ');
+                            BufferUtil.putDecLong(_header, _contentLength);
+                            _header.put(HttpTokens.CRLF);
+                        }
+                    }
+                    else
+                    {
+                        // No idea, so we must assume that a body is coming
+                        _contentLength = (!_persistent || _version < HttpVersions.HTTP_1_1_ORDINAL ) ? HttpTokens.EOF_CONTENT : HttpTokens.CHUNKED_CONTENT;
+                        if (isRequest() && _contentLength==HttpTokens.EOF_CONTENT)
+                        {
+                            _contentLength=HttpTokens.NO_CONTENT;
+                            _noContent=true;
+                        }
+                    }
+                    break;
+
+                case HttpTokens.NO_CONTENT:
+                    if (content_length == null && isResponse() && _status >= 200 && _status != 204 && _status != 304)
+                        _header.put(CONTENT_LENGTH_0);
+                    break;
+
+                case HttpTokens.EOF_CONTENT:
+                    _persistent = isRequest();
+                    break;
+
+                case HttpTokens.CHUNKED_CONTENT:
+                    break;
+
+                default:
+                    // TODO - maybe allow forced chunking by setting te ???
+                    break;
+            }
+
+            // Add transfer_encoding if needed
+            if (_contentLength == HttpTokens.CHUNKED_CONTENT)
+            {
+                // try to use user supplied encoding as it may have other values.
+                if (transfer_encoding != null && HttpHeaderValues.CHUNKED_ORDINAL != transfer_encoding.getValueOrdinal())
+                {
+                    String c = transfer_encoding.getValue();
+                    if (c.endsWith(HttpHeaderValues.CHUNKED))
+                        transfer_encoding.putTo(_header);
+                    else
+                        throw new IllegalArgumentException("BAD TE");
+                }
+                else
+                    _header.put(TRANSFER_ENCODING_CHUNKED);
+            }
+
+            // Handle connection if need be
+            if (_contentLength==HttpTokens.EOF_CONTENT)
+            {
+                keep_alive=false;
+                _persistent=false;
+            }
+
+            if (isResponse())
+            {
+                if (!_persistent && (close || _version > HttpVersions.HTTP_1_0_ORDINAL))
+                {
+                    _header.put(CONNECTION_CLOSE);
+                    if (connection!=null)
+                    {
+                        _header.setPutIndex(_header.putIndex()-2);
+                        _header.put((byte)',');
+                        _header.put(connection.toString().getBytes());
+                        _header.put(CRLF);
+                    }
+                }
+                else if (keep_alive)
+                {
+                    _header.put(CONNECTION_KEEP_ALIVE);
+                    if (connection!=null)
+                    {
+                        _header.setPutIndex(_header.putIndex()-2);
+                        _header.put((byte)',');
+                        _header.put(connection.toString().getBytes());
+                        _header.put(CRLF);
+                    }
+                }
+                else if (connection!=null)
+                {
+                    _header.put(CONNECTION_);
+                    _header.put(connection.toString().getBytes());
+                    _header.put(CRLF);
+                }
+            }
+
+            if (!has_server && _status>199 && getSendServerVersion())
+                _header.put(SERVER);
+
+            // end the header.
+            _header.put(HttpTokens.CRLF);
+            _state = STATE_CONTENT;
+
+        }
+        catch(ArrayIndexOutOfBoundsException e)
+        {
+            throw new RuntimeException("Header>"+_header.capacity(),e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Complete the message.
+     *
+     * @throws IOException
+     */
+    @Override
+    public void complete() throws IOException
+    {
+        if (_state == STATE_END)
+            return;
+
+        super.complete();
+
+        if (_state < STATE_FLUSHING)
+        {
+            _state = STATE_FLUSHING;
+            if (_contentLength == HttpTokens.CHUNKED_CONTENT)
+                _needEOC = true;
+        }
+
+        flushBuffer();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int flushBuffer() throws IOException
+    {
+        try
+        {
+
+            if (_state == STATE_HEADER)
+                throw new IllegalStateException("State==HEADER");
+
+            prepareBuffers();
+
+            if (_endp == null)
+            {
+                if (_needCRLF && _buffer!=null)
+                    _buffer.put(HttpTokens.CRLF);
+                if (_needEOC && _buffer!=null && !_head)
+                    _buffer.put(LAST_CHUNK);
+                _needCRLF=false;
+                _needEOC=false;
+                return 0;
+            }
+
+            int total= 0;
+
+            int len = -1;
+            int to_flush = flushMask();
+            int last_flush;
+
+            do
+            {
+                last_flush=to_flush;
+                switch (to_flush)
+                {
+                    case 7:
+                        throw new IllegalStateException(); // should never happen!
+                    case 6:
+                        len = _endp.flush(_header, _buffer, null);
+                        break;
+                    case 5:
+                        len = _endp.flush(_header, _content, null);
+                        break;
+                    case 4:
+                        len = _endp.flush(_header);
+                        break;
+                    case 3:
+                        len = _endp.flush(_buffer, _content, null);
+                        break;
+                    case 2:
+                        len = _endp.flush(_buffer);
+                        break;
+                    case 1:
+                        len = _endp.flush(_content);
+                        break;
+                    case 0:
+                    {
+                        len=0;
+                        // Nothing more we can write now.
+                        if (_header != null)
+                            _header.clear();
+
+                        _bypass = false;
+                        _bufferChunked = false;
+
+                        if (_buffer != null)
+                        {
+                            _buffer.clear();
+                            if (_contentLength == HttpTokens.CHUNKED_CONTENT)
+                            {
+                                // reserve some space for the chunk header
+                                _buffer.setPutIndex(CHUNK_SPACE);
+                                _buffer.setGetIndex(CHUNK_SPACE);
+
+                                // Special case handling for small left over buffer from
+                                // an addContent that caused a buffer flush.
+                                if (_content != null && _content.length() < _buffer.space() && _state != STATE_FLUSHING)
+                                {
+                                    _buffer.put(_content);
+                                    _content.clear();
+                                    _content=null;
+                                }
+                            }
+                        }
+
+                        // Are we completely finished for now?
+                        if (!_needCRLF && !_needEOC && (_content==null || _content.length()==0))
+                        {
+                            if (_state == STATE_FLUSHING)
+                                _state = STATE_END;
+
+                            if (_state==STATE_END && _persistent != null && !_persistent && _status!=100 && _method==null)
+                                _endp.shutdownOutput();
+                        }
+                        else
+                            // Try to prepare more to write.
+                            prepareBuffers();
+                    }
+
+                }
+
+                if (len > 0)
+                    total+=len;
+
+                to_flush = flushMask();
+            }
+            // loop while progress is being made (OR we have prepared some buffers that might make progress)
+            while (len>0 || (to_flush!=0 && last_flush==0));
+
+            return total;
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+            throw (e instanceof EofException) ? e:new EofException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private int flushMask()
+    {
+        return  ((_header != null && _header.length() > 0)?4:0)
+        | ((_buffer != null && _buffer.length() > 0)?2:0)
+        | ((_bypass && _content != null && _content.length() > 0)?1:0);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void prepareBuffers()
+    {
+        // if we are not flushing an existing chunk
+        if (!_bufferChunked)
+        {
+            // Refill buffer if possible
+            if (!_bypass && _content != null && _content.length() > 0 && _buffer != null && _buffer.space() > 0)
+            {
+                int len = _buffer.put(_content);
+                _content.skip(len);
+                if (_content.length() == 0)
+                    _content = null;
+            }
+
+            // Chunk buffer if need be
+            if (_contentLength == HttpTokens.CHUNKED_CONTENT)
+            {
+                if (_bypass && (_buffer==null||_buffer.length()==0) && _content!=null)
+                {
+                    // this is a bypass write
+                    int size = _content.length();
+                    _bufferChunked = true;
+
+                    if (_header == null)
+                        _header = _buffers.getHeader();
+
+                    // if we need CRLF add this to header
+                    if (_needCRLF)
+                    {
+                        if (_header.length() > 0) throw new IllegalStateException("EOC");
+                        _header.put(HttpTokens.CRLF);
+                        _needCRLF = false;
+                    }
+                    // Add the chunk size to the header
+                    BufferUtil.putHexInt(_header, size);
+                    _header.put(HttpTokens.CRLF);
+
+                    // Need a CRLF after the content
+                    _needCRLF=true;
+                }
+                else if (_buffer!=null)
+                {
+                    int size = _buffer.length();
+                    if (size > 0)
+                    {
+                        // Prepare a chunk!
+                        _bufferChunked = true;
+
+                        // Did we leave space at the start of the buffer.
+                        //noinspection ConstantConditions
+                        if (_buffer.getIndex() == CHUNK_SPACE)
+                        {
+                            // Oh yes, goodie! let's use it then!
+                            _buffer.poke(_buffer.getIndex() - 2, HttpTokens.CRLF, 0, 2);
+                            _buffer.setGetIndex(_buffer.getIndex() - 2);
+                            BufferUtil.prependHexInt(_buffer, size);
+
+                            if (_needCRLF)
+                            {
+                                _buffer.poke(_buffer.getIndex() - 2, HttpTokens.CRLF, 0, 2);
+                                _buffer.setGetIndex(_buffer.getIndex() - 2);
+                                _needCRLF = false;
+                            }
+                        }
+                        else
+                        {
+                            // No space so lets use a header buffer.
+                            if (_header == null)
+                                _header = _buffers.getHeader();
+
+                            if (_needCRLF)
+                            {
+                                if (_header.length() > 0) throw new IllegalStateException("EOC");
+                                _header.put(HttpTokens.CRLF);
+                                _needCRLF = false;
+                            }
+                            BufferUtil.putHexInt(_header, size);
+                            _header.put(HttpTokens.CRLF);
+                        }
+
+                        // Add end chunk trailer.
+                        if (_buffer.space() >= 2)
+                            _buffer.put(HttpTokens.CRLF);
+                        else
+                            _needCRLF = true;
+                    }
+                }
+
+                // If we need EOC and everything written
+                if (_needEOC && (_content == null || _content.length() == 0))
+                {
+                    if (_header == null && _buffer == null)
+                        _header = _buffers.getHeader();
+
+                    if (_needCRLF)
+                    {
+                        if (_buffer == null && _header != null && _header.space() >= HttpTokens.CRLF.length)
+                        {
+                            _header.put(HttpTokens.CRLF);
+                            _needCRLF = false;
+                        }
+                        else if (_buffer!=null && _buffer.space() >= HttpTokens.CRLF.length)
+                        {
+                            _buffer.put(HttpTokens.CRLF);
+                            _needCRLF = false;
+                        }
+                    }
+
+                    if (!_needCRLF && _needEOC)
+                    {
+                        if (_buffer == null && _header != null && _header.space() >= LAST_CHUNK.length)
+                        {
+                            if (!_head)
+                            {
+                                _header.put(LAST_CHUNK);
+                                _bufferChunked=true;
+                            }
+                            _needEOC = false;
+                        }
+                        else if (_buffer!=null && _buffer.space() >= LAST_CHUNK.length)
+                        {
+                            if (!_head)
+                            {
+                                _buffer.put(LAST_CHUNK);
+                                _bufferChunked=true;
+                            }
+                            _needEOC = false;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (_content != null && _content.length() == 0)
+            _content = null;
+
+    }
+
+    public int getBytesBuffered()
+    {
+        return(_header==null?0:_header.length())+
+        (_buffer==null?0:_buffer.length())+
+        (_content==null?0:_content.length());
+    }
+
+    public boolean isEmpty()
+    {
+        return (_header==null||_header.length()==0) &&
+        (_buffer==null||_buffer.length()==0) &&
+        (_content==null||_content.length()==0);
+    }
+
+    @Override
+    public String toString()
+    {
+        Buffer header=_header;
+        Buffer buffer=_buffer;
+        Buffer content=_content;
+        return String.format("%s{s=%d,h=%d,b=%d,c=%d}",
+                getClass().getSimpleName(),
+                _state,
+                header == null ? -1 : header.length(),
+                buffer == null ? -1 : buffer.length(),
+                content == null ? -1 : content.length());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpHeaderValues.java b/src/java/org/eclipse/jetty/http/HttpHeaderValues.java
new file mode 100644
index 0000000..995b744
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpHeaderValues.java
@@ -0,0 +1,88 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+
+/**
+ * Cached HTTP Header values.
+ * This class caches the conversion of common HTTP Header values to and from {@link ByteArrayBuffer} instances.
+ * The resource "/org/eclipse/jetty/useragents" is checked for a list of common user agents, so that repeated
+ * creation of strings for these agents can be avoided.
+ * 
+ * 
+ */
+public class HttpHeaderValues extends BufferCache
+{
+    public final static String
+        CLOSE="close",
+        CHUNKED="chunked",
+        GZIP="gzip",
+        IDENTITY="identity",
+        KEEP_ALIVE="keep-alive",
+        CONTINUE="100-continue",
+        PROCESSING="102-processing",
+        TE="TE",
+        BYTES="bytes",
+        NO_CACHE="no-cache",
+        UPGRADE="Upgrade";
+
+    public final static int
+        CLOSE_ORDINAL=1,
+        CHUNKED_ORDINAL=2,
+        GZIP_ORDINAL=3,
+        IDENTITY_ORDINAL=4,
+        KEEP_ALIVE_ORDINAL=5,
+        CONTINUE_ORDINAL=6,
+        PROCESSING_ORDINAL=7,
+        TE_ORDINAL=8,
+        BYTES_ORDINAL=9,
+        NO_CACHE_ORDINAL=10,
+        UPGRADE_ORDINAL=11;
+    
+    public final static HttpHeaderValues CACHE= new HttpHeaderValues();
+
+    public final static Buffer 
+        CLOSE_BUFFER=CACHE.add(CLOSE,CLOSE_ORDINAL),
+        CHUNKED_BUFFER=CACHE.add(CHUNKED,CHUNKED_ORDINAL),
+        GZIP_BUFFER=CACHE.add(GZIP,GZIP_ORDINAL),
+        IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL),
+        KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL),
+        CONTINUE_BUFFER=CACHE.add(CONTINUE, CONTINUE_ORDINAL),
+        PROCESSING_BUFFER=CACHE.add(PROCESSING, PROCESSING_ORDINAL),
+        TE_BUFFER=CACHE.add(TE,TE_ORDINAL),
+        BYTES_BUFFER=CACHE.add(BYTES,BYTES_ORDINAL),
+        NO_CACHE_BUFFER=CACHE.add(NO_CACHE,NO_CACHE_ORDINAL),
+        UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL);
+        
+
+    public static boolean hasKnownValues(int httpHeaderOrdinal)
+    {
+        switch(httpHeaderOrdinal)
+        {
+            case HttpHeaders.CONNECTION_ORDINAL:
+            case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
+            case HttpHeaders.CONTENT_ENCODING_ORDINAL:
+                return true;
+        }
+        return false;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpHeaders.java b/src/java/org/eclipse/jetty/http/HttpHeaders.java
new file mode 100644
index 0000000..719e91b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpHeaders.java
@@ -0,0 +1,241 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ */
+public class HttpHeaders extends BufferCache
+{
+    /* ------------------------------------------------------------ */
+    /** General Fields.
+     */
+    public final static String 
+        CONNECTION= "Connection",
+        CACHE_CONTROL= "Cache-Control",
+        DATE= "Date",
+        PRAGMA= "Pragma",
+        PROXY_CONNECTION = "Proxy-Connection",
+        TRAILER= "Trailer",
+        TRANSFER_ENCODING= "Transfer-Encoding",
+        UPGRADE= "Upgrade",
+        VIA= "Via",
+        WARNING= "Warning",
+        NEGOTIATE= "Negotiate";
+
+    /* ------------------------------------------------------------ */
+    /** Entity Fields.
+     */
+    public final static String ALLOW= "Allow",
+        CONTENT_ENCODING= "Content-Encoding",
+        CONTENT_LANGUAGE= "Content-Language",
+        CONTENT_LENGTH= "Content-Length",
+        CONTENT_LOCATION= "Content-Location",
+        CONTENT_MD5= "Content-MD5",
+        CONTENT_RANGE= "Content-Range",
+        CONTENT_TYPE= "Content-Type",
+        EXPIRES= "Expires",
+        LAST_MODIFIED= "Last-Modified";
+
+    /* ------------------------------------------------------------ */
+    /** Request Fields.
+     */
+    public final static String ACCEPT= "Accept",
+        ACCEPT_CHARSET= "Accept-Charset",
+        ACCEPT_ENCODING= "Accept-Encoding",
+        ACCEPT_LANGUAGE= "Accept-Language",
+        AUTHORIZATION= "Authorization",
+        EXPECT= "Expect",
+        FORWARDED= "Forwarded",
+        FROM= "From",
+        HOST= "Host",
+        IF_MATCH= "If-Match",
+        IF_MODIFIED_SINCE= "If-Modified-Since",
+        IF_NONE_MATCH= "If-None-Match",
+        IF_RANGE= "If-Range",
+        IF_UNMODIFIED_SINCE= "If-Unmodified-Since",
+        KEEP_ALIVE= "Keep-Alive",
+        MAX_FORWARDS= "Max-Forwards",
+        PROXY_AUTHORIZATION= "Proxy-Authorization",
+        RANGE= "Range",
+        REQUEST_RANGE= "Request-Range",
+        REFERER= "Referer",
+        TE= "TE",
+        USER_AGENT= "User-Agent",
+        X_FORWARDED_FOR= "X-Forwarded-For",
+        X_FORWARDED_PROTO= "X-Forwarded-Proto",
+        X_FORWARDED_SERVER= "X-Forwarded-Server",
+        X_FORWARDED_HOST= "X-Forwarded-Host";
+
+    /* ------------------------------------------------------------ */
+    /** Response Fields.
+     */
+    public final static String ACCEPT_RANGES= "Accept-Ranges",
+        AGE= "Age",
+        ETAG= "ETag",
+        LOCATION= "Location",
+        PROXY_AUTHENTICATE= "Proxy-Authenticate",
+        RETRY_AFTER= "Retry-After",
+        SERVER= "Server",
+        SERVLET_ENGINE= "Servlet-Engine",
+        VARY= "Vary",
+        WWW_AUTHENTICATE= "WWW-Authenticate";
+
+    /* ------------------------------------------------------------ */
+    /** Other Fields.
+     */
+    public final static String COOKIE= "Cookie",
+        SET_COOKIE= "Set-Cookie",
+        SET_COOKIE2= "Set-Cookie2",
+        MIME_VERSION= "MIME-Version",
+        IDENTITY= "identity";
+
+    public final static int CONNECTION_ORDINAL= 1,
+        DATE_ORDINAL= 2,
+        PRAGMA_ORDINAL= 3,
+        TRAILER_ORDINAL= 4,
+        TRANSFER_ENCODING_ORDINAL= 5,
+        UPGRADE_ORDINAL= 6,
+        VIA_ORDINAL= 7,
+        WARNING_ORDINAL= 8,
+        ALLOW_ORDINAL= 9,
+        CONTENT_ENCODING_ORDINAL= 10,
+        CONTENT_LANGUAGE_ORDINAL= 11,
+        CONTENT_LENGTH_ORDINAL= 12,
+        CONTENT_LOCATION_ORDINAL= 13,
+        CONTENT_MD5_ORDINAL= 14,
+        CONTENT_RANGE_ORDINAL= 15,
+        CONTENT_TYPE_ORDINAL= 16,
+        EXPIRES_ORDINAL= 17,
+        LAST_MODIFIED_ORDINAL= 18,
+        ACCEPT_ORDINAL= 19,
+        ACCEPT_CHARSET_ORDINAL= 20,
+        ACCEPT_ENCODING_ORDINAL= 21,
+        ACCEPT_LANGUAGE_ORDINAL= 22,
+        AUTHORIZATION_ORDINAL= 23,
+        EXPECT_ORDINAL= 24,
+        FORWARDED_ORDINAL= 25,
+        FROM_ORDINAL= 26,
+        HOST_ORDINAL= 27,
+        IF_MATCH_ORDINAL= 28,
+        IF_MODIFIED_SINCE_ORDINAL= 29,
+        IF_NONE_MATCH_ORDINAL= 30,
+        IF_RANGE_ORDINAL= 31,
+        IF_UNMODIFIED_SINCE_ORDINAL= 32,
+        KEEP_ALIVE_ORDINAL= 33,
+        MAX_FORWARDS_ORDINAL= 34,
+        PROXY_AUTHORIZATION_ORDINAL= 35,
+        RANGE_ORDINAL= 36,
+        REQUEST_RANGE_ORDINAL= 37,
+        REFERER_ORDINAL= 38,
+        TE_ORDINAL= 39,
+        USER_AGENT_ORDINAL= 40,
+        X_FORWARDED_FOR_ORDINAL= 41,
+        ACCEPT_RANGES_ORDINAL= 42,
+        AGE_ORDINAL= 43,
+        ETAG_ORDINAL= 44,
+        LOCATION_ORDINAL= 45,
+        PROXY_AUTHENTICATE_ORDINAL= 46,
+        RETRY_AFTER_ORDINAL= 47,
+        SERVER_ORDINAL= 48,
+        SERVLET_ENGINE_ORDINAL= 49,
+        VARY_ORDINAL= 50,
+        WWW_AUTHENTICATE_ORDINAL= 51,
+        COOKIE_ORDINAL= 52,
+        SET_COOKIE_ORDINAL= 53,
+        SET_COOKIE2_ORDINAL= 54,
+        MIME_VERSION_ORDINAL= 55,
+        IDENTITY_ORDINAL= 56,
+        CACHE_CONTROL_ORDINAL=57,
+        PROXY_CONNECTION_ORDINAL=58,
+        X_FORWARDED_PROTO_ORDINAL=59,
+        X_FORWARDED_SERVER_ORDINAL=60,
+        X_FORWARDED_HOST_ORDINAL=61;
+
+    public final static HttpHeaders CACHE= new HttpHeaders();
+    
+    public final static Buffer
+        HOST_BUFFER=CACHE.add(HOST,HOST_ORDINAL),
+        ACCEPT_BUFFER=CACHE.add(ACCEPT,ACCEPT_ORDINAL),
+        ACCEPT_CHARSET_BUFFER=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL),
+        ACCEPT_ENCODING_BUFFER=CACHE.add(ACCEPT_ENCODING,ACCEPT_ENCODING_ORDINAL),
+        ACCEPT_LANGUAGE_BUFFER=CACHE.add(ACCEPT_LANGUAGE,ACCEPT_LANGUAGE_ORDINAL),
+        
+        CONTENT_LENGTH_BUFFER=CACHE.add(CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL),
+        CONNECTION_BUFFER=CACHE.add(CONNECTION,CONNECTION_ORDINAL),
+        CACHE_CONTROL_BUFFER=CACHE.add(CACHE_CONTROL,CACHE_CONTROL_ORDINAL),
+        DATE_BUFFER=CACHE.add(DATE,DATE_ORDINAL),
+        PRAGMA_BUFFER=CACHE.add(PRAGMA,PRAGMA_ORDINAL),
+        TRAILER_BUFFER=CACHE.add(TRAILER,TRAILER_ORDINAL),
+        TRANSFER_ENCODING_BUFFER=CACHE.add(TRANSFER_ENCODING,TRANSFER_ENCODING_ORDINAL),
+        UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL),
+        VIA_BUFFER=CACHE.add(VIA,VIA_ORDINAL),
+        WARNING_BUFFER=CACHE.add(WARNING,WARNING_ORDINAL),
+        ALLOW_BUFFER=CACHE.add(ALLOW,ALLOW_ORDINAL),
+        CONTENT_ENCODING_BUFFER=CACHE.add(CONTENT_ENCODING,CONTENT_ENCODING_ORDINAL),
+        CONTENT_LANGUAGE_BUFFER=CACHE.add(CONTENT_LANGUAGE,CONTENT_LANGUAGE_ORDINAL),
+        CONTENT_LOCATION_BUFFER=CACHE.add(CONTENT_LOCATION,CONTENT_LOCATION_ORDINAL),
+        CONTENT_MD5_BUFFER=CACHE.add(CONTENT_MD5,CONTENT_MD5_ORDINAL),
+        CONTENT_RANGE_BUFFER=CACHE.add(CONTENT_RANGE,CONTENT_RANGE_ORDINAL),
+        CONTENT_TYPE_BUFFER=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL),
+        EXPIRES_BUFFER=CACHE.add(EXPIRES,EXPIRES_ORDINAL),
+        LAST_MODIFIED_BUFFER=CACHE.add(LAST_MODIFIED,LAST_MODIFIED_ORDINAL),
+        AUTHORIZATION_BUFFER=CACHE.add(AUTHORIZATION,AUTHORIZATION_ORDINAL),
+        EXPECT_BUFFER=CACHE.add(EXPECT,EXPECT_ORDINAL),
+        FORWARDED_BUFFER=CACHE.add(FORWARDED,FORWARDED_ORDINAL),
+        FROM_BUFFER=CACHE.add(FROM,FROM_ORDINAL),
+        IF_MATCH_BUFFER=CACHE.add(IF_MATCH,IF_MATCH_ORDINAL),
+        IF_MODIFIED_SINCE_BUFFER=CACHE.add(IF_MODIFIED_SINCE,IF_MODIFIED_SINCE_ORDINAL),
+        IF_NONE_MATCH_BUFFER=CACHE.add(IF_NONE_MATCH,IF_NONE_MATCH_ORDINAL),
+        IF_RANGE_BUFFER=CACHE.add(IF_RANGE,IF_RANGE_ORDINAL),
+        IF_UNMODIFIED_SINCE_BUFFER=CACHE.add(IF_UNMODIFIED_SINCE,IF_UNMODIFIED_SINCE_ORDINAL),
+        KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL),
+        MAX_FORWARDS_BUFFER=CACHE.add(MAX_FORWARDS,MAX_FORWARDS_ORDINAL),
+        PROXY_AUTHORIZATION_BUFFER=CACHE.add(PROXY_AUTHORIZATION,PROXY_AUTHORIZATION_ORDINAL),
+        RANGE_BUFFER=CACHE.add(RANGE,RANGE_ORDINAL),
+        REQUEST_RANGE_BUFFER=CACHE.add(REQUEST_RANGE,REQUEST_RANGE_ORDINAL),
+        REFERER_BUFFER=CACHE.add(REFERER,REFERER_ORDINAL),
+        TE_BUFFER=CACHE.add(TE,TE_ORDINAL),
+        USER_AGENT_BUFFER=CACHE.add(USER_AGENT,USER_AGENT_ORDINAL),
+        X_FORWARDED_FOR_BUFFER=CACHE.add(X_FORWARDED_FOR,X_FORWARDED_FOR_ORDINAL),
+        X_FORWARDED_PROTO_BUFFER=CACHE.add(X_FORWARDED_PROTO,X_FORWARDED_PROTO_ORDINAL),
+        X_FORWARDED_SERVER_BUFFER=CACHE.add(X_FORWARDED_SERVER,X_FORWARDED_SERVER_ORDINAL),
+        X_FORWARDED_HOST_BUFFER=CACHE.add(X_FORWARDED_HOST,X_FORWARDED_HOST_ORDINAL),
+        ACCEPT_RANGES_BUFFER=CACHE.add(ACCEPT_RANGES,ACCEPT_RANGES_ORDINAL),
+        AGE_BUFFER=CACHE.add(AGE,AGE_ORDINAL),
+        ETAG_BUFFER=CACHE.add(ETAG,ETAG_ORDINAL),
+        LOCATION_BUFFER=CACHE.add(LOCATION,LOCATION_ORDINAL),
+        PROXY_AUTHENTICATE_BUFFER=CACHE.add(PROXY_AUTHENTICATE,PROXY_AUTHENTICATE_ORDINAL),
+        RETRY_AFTER_BUFFER=CACHE.add(RETRY_AFTER,RETRY_AFTER_ORDINAL),
+        SERVER_BUFFER=CACHE.add(SERVER,SERVER_ORDINAL),
+        SERVLET_ENGINE_BUFFER=CACHE.add(SERVLET_ENGINE,SERVLET_ENGINE_ORDINAL),
+        VARY_BUFFER=CACHE.add(VARY,VARY_ORDINAL),
+        WWW_AUTHENTICATE_BUFFER=CACHE.add(WWW_AUTHENTICATE,WWW_AUTHENTICATE_ORDINAL),
+        COOKIE_BUFFER=CACHE.add(COOKIE,COOKIE_ORDINAL),
+        SET_COOKIE_BUFFER=CACHE.add(SET_COOKIE,SET_COOKIE_ORDINAL),
+        SET_COOKIE2_BUFFER=CACHE.add(SET_COOKIE2,SET_COOKIE2_ORDINAL),
+        MIME_VERSION_BUFFER=CACHE.add(MIME_VERSION,MIME_VERSION_ORDINAL),
+        IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL),
+        PROXY_CONNECTION_BUFFER=CACHE.add(PROXY_CONNECTION,PROXY_CONNECTION_ORDINAL);
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpMethods.java b/src/java/org/eclipse/jetty/http/HttpMethods.java
new file mode 100644
index 0000000..2042bf1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpMethods.java
@@ -0,0 +1,64 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * 
+ * 
+ */
+public class HttpMethods
+{
+    public final static String GET= "GET",
+        POST= "POST",
+        HEAD= "HEAD",
+        PUT= "PUT",
+        OPTIONS= "OPTIONS",
+        DELETE= "DELETE",
+        TRACE= "TRACE",
+        CONNECT= "CONNECT",
+        MOVE= "MOVE";
+
+    public final static int GET_ORDINAL= 1,
+        POST_ORDINAL= 2,
+        HEAD_ORDINAL= 3,
+        PUT_ORDINAL= 4,
+        OPTIONS_ORDINAL= 5,
+        DELETE_ORDINAL= 6,
+        TRACE_ORDINAL= 7,
+        CONNECT_ORDINAL= 8,
+        MOVE_ORDINAL= 9;
+
+    public final static BufferCache CACHE= new BufferCache();
+
+    public final static Buffer 
+        GET_BUFFER= CACHE.add(GET, GET_ORDINAL),
+        POST_BUFFER= CACHE.add(POST, POST_ORDINAL),
+        HEAD_BUFFER= CACHE.add(HEAD, HEAD_ORDINAL),
+        PUT_BUFFER= CACHE.add(PUT, PUT_ORDINAL),
+        OPTIONS_BUFFER= CACHE.add(OPTIONS, OPTIONS_ORDINAL),
+        DELETE_BUFFER= CACHE.add(DELETE, DELETE_ORDINAL),
+        TRACE_BUFFER= CACHE.add(TRACE, TRACE_ORDINAL),
+        CONNECT_BUFFER= CACHE.add(CONNECT, CONNECT_ORDINAL),
+        MOVE_BUFFER= CACHE.add(MOVE, MOVE_ORDINAL);
+
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpParser.java b/src/java/org/eclipse/jetty/http/HttpParser.java
new file mode 100644
index 0000000..f4471a3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpParser.java
@@ -0,0 +1,1279 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.View;
+import org.eclipse.jetty.io.bio.StreamEndPoint;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class HttpParser implements Parser
+{
+    private static final Logger LOG = Log.getLogger(HttpParser.class);
+
+    // States
+    public static final int STATE_START=-14;
+    public static final int STATE_FIELD0=-13;
+    public static final int STATE_SPACE1=-12;
+    public static final int STATE_STATUS=-11;
+    public static final int STATE_URI=-10;
+    public static final int STATE_SPACE2=-9;
+    public static final int STATE_END0=-8;
+    public static final int STATE_END1=-7;
+    public static final int STATE_FIELD2=-6;
+    public static final int STATE_HEADER=-5;
+    public static final int STATE_HEADER_NAME=-4;
+    public static final int STATE_HEADER_IN_NAME=-3;
+    public static final int STATE_HEADER_VALUE=-2;
+    public static final int STATE_HEADER_IN_VALUE=-1;
+    public static final int STATE_END=0;
+    public static final int STATE_EOF_CONTENT=1;
+    public static final int STATE_CONTENT=2;
+    public static final int STATE_CHUNKED_CONTENT=3;
+    public static final int STATE_CHUNK_SIZE=4;
+    public static final int STATE_CHUNK_PARAMS=5;
+    public static final int STATE_CHUNK=6;
+    public static final int STATE_SEEKING_EOF=7;
+
+    private final EventHandler _handler;
+    private final Buffers _buffers; // source of buffers
+    private final EndPoint _endp;
+    private Buffer _header; // Buffer for header data (and small _content)
+    private Buffer _body; // Buffer for large content
+    private Buffer _buffer; // The current buffer in use (either _header or _content)
+    private CachedBuffer _cached;
+    private final View.CaseInsensitive _tok0; // Saved token: header name, request method or response version
+    private final View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code
+    private String _multiLineValue;
+    private int _responseStatus; // If >0 then we are parsing a response
+    private boolean _forceContentBuffer;
+    private boolean _persistent;
+
+    /* ------------------------------------------------------------------------------- */
+    protected final View  _contentView=new View(); // View of the content in the buffer for {@link Input}
+    protected int _state=STATE_START;
+    protected byte _eol;
+    protected int _length;
+    protected long _contentLength;
+    protected long _contentPosition;
+    protected int _chunkLength;
+    protected int _chunkPosition;
+    private boolean _headResponse;
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Constructor.
+     */
+    public HttpParser(Buffer buffer, EventHandler handler)
+    {
+        _endp=null;
+        _buffers=null;
+        _header=buffer;
+        _buffer=buffer;
+        _handler=handler;
+
+        _tok0=new View.CaseInsensitive(_header);
+        _tok1=new View.CaseInsensitive(_header);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Constructor.
+     * @param buffers the buffers to use
+     * @param endp the endpoint
+     * @param handler the even handler
+     */
+    public HttpParser(Buffers buffers, EndPoint endp, EventHandler handler)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _handler=handler;
+        _tok0=new View.CaseInsensitive();
+        _tok1=new View.CaseInsensitive();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public long getContentLength()
+    {
+        return _contentLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    public long getContentRead()
+    {
+        return _contentPosition;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set if a HEAD response is expected
+     * @param head
+     */
+    public void setHeadResponse(boolean head)
+    {
+        _headResponse=head;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public int getState()
+    {
+        return _state;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean inContentState()
+    {
+        return _state > 0;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean inHeaderState()
+    {
+        return _state < 0;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean isChunking()
+    {
+        return _contentLength==HttpTokens.CHUNKED_CONTENT;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return isState(STATE_START);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isComplete()
+    {
+        return isState(STATE_END);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isMoreInBuffer()
+    throws IOException
+    {
+        return ( _header!=null && _header.hasContent() ||
+             _body!=null && _body.hasContent());
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean isState(int state)
+    {
+        return _state == state;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean isPersistent()
+    {
+        return _persistent;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void setPersistent(boolean persistent)
+    {
+        _persistent = persistent;
+        if (!_persistent &&(_state==STATE_END || _state==STATE_START))
+            _state=STATE_SEEKING_EOF;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Parse until {@link #STATE_END END} state.
+     * If the parser is already in the END state, then it is {@link #reset reset} and re-parsed.
+     * @throws IllegalStateException If the buffers have already been partially parsed.
+     */
+    public void parse() throws IOException
+    {
+        if (_state==STATE_END)
+            reset();
+        if (_state!=STATE_START)
+            throw new IllegalStateException("!START");
+
+        // continue parsing
+        while (_state != STATE_END)
+            if (parseNext()<0)
+                return;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Parse until END state.
+     * This method will parse any remaining content in the current buffer as long as there is
+     * no unconsumed content. It does not care about the {@link #getState current state} of the parser.
+     * @see #parse
+     * @see #parseNext
+     */
+    public boolean parseAvailable() throws IOException
+    {
+        boolean progress=parseNext()>0;
+
+        // continue parsing
+        while (!isComplete() && _buffer!=null && _buffer.length()>0 && !_contentView.hasContent())
+        {
+            progress |= parseNext()>0;
+        }
+        return progress;
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Parse until next Event.
+     * @return an indication of progress <0 EOF, 0 no progress, >0 progress.
+     */
+    public int parseNext() throws IOException
+    {
+        try
+        {
+            int progress=0;
+
+            if (_state == STATE_END)
+                return 0;
+
+            if (_buffer==null)
+                _buffer=getHeaderBuffer();
+
+
+            if (_state == STATE_CONTENT && _contentPosition == _contentLength)
+            {
+                _state=STATE_END;
+                _handler.messageComplete(_contentPosition);
+                return 1;
+            }
+
+            int length=_buffer.length();
+
+            // Fill buffer if we can
+            if (length == 0)
+            {
+                int filled=-1;
+                IOException ex=null;
+                try
+                {
+                    filled=fill();
+                    LOG.debug("filled {}/{}",filled,_buffer.length());
+                }
+                catch(IOException e)
+                {
+                    LOG.debug(this.toString(),e);
+                    ex=e;
+                }
+
+                if (filled > 0 )
+                    progress++;
+                else if (filled < 0 )
+                {
+                    _persistent=false;
+
+                    // do we have content to deliver?
+                    if (_state>STATE_END)
+                    {
+                        if (_buffer.length()>0 && !_headResponse)
+                        {
+                            Buffer chunk=_buffer.get(_buffer.length());
+                            _contentPosition += chunk.length();
+                            _contentView.update(chunk);
+                            _handler.content(chunk); // May recurse here
+                        }
+                    }
+
+                    // was this unexpected?
+                    switch(_state)
+                    {
+                        case STATE_END:
+                        case STATE_SEEKING_EOF:
+                            _state=STATE_END;
+                            break;
+
+                        case STATE_EOF_CONTENT:
+                            _state=STATE_END;
+                            _handler.messageComplete(_contentPosition);
+                            break;
+
+                        default:
+                            _state=STATE_END;
+                            if (!_headResponse)
+                                _handler.earlyEOF();
+                            _handler.messageComplete(_contentPosition);
+                    }
+
+                    if (ex!=null)
+                        throw ex;
+
+                    if (!isComplete() && !isIdle())
+                        throw new EofException();
+
+                    return -1;
+                }
+                length=_buffer.length();
+            }
+
+
+            // Handle header states
+            byte ch;
+            byte[] array=_buffer.array();
+            int last=_state;
+            while (_state<STATE_END && length-->0)
+            {
+                if (last!=_state)
+                {
+                    progress++;
+                    last=_state;
+                }
+
+                ch=_buffer.get();
+
+                if (_eol == HttpTokens.CARRIAGE_RETURN)
+                {
+                    if (ch == HttpTokens.LINE_FEED)
+                    {
+                        _eol=HttpTokens.LINE_FEED;
+                        continue;
+                    }
+                    throw new HttpException(HttpStatus.BAD_REQUEST_400);
+                }
+                _eol=0;
+
+                switch (_state)
+                {
+                    case STATE_START:
+                        _contentLength=HttpTokens.UNKNOWN_CONTENT;
+                        _cached=null;
+                        if (ch > HttpTokens.SPACE || ch<0)
+                        {
+                            _buffer.mark();
+                            _state=STATE_FIELD0;
+                        }
+                        break;
+
+                    case STATE_FIELD0:
+                        if (ch == HttpTokens.SPACE)
+                        {
+                            _tok0.update(_buffer.markIndex(), _buffer.getIndex() - 1);
+                            _responseStatus=HttpVersions.CACHE.get(_tok0)==null?-1:0;
+                            _state=STATE_SPACE1;
+                            continue;
+                        }
+                        else if (ch < HttpTokens.SPACE && ch>=0)
+                        {
+                            throw new HttpException(HttpStatus.BAD_REQUEST_400);
+                        }
+                        break;
+
+                    case STATE_SPACE1:
+                        if (ch > HttpTokens.SPACE || ch<0)
+                        {
+                            _buffer.mark();
+                            if (_responseStatus>=0)
+                            {
+                                _state=STATE_STATUS;
+                                _responseStatus=ch-'0';
+                            }
+                            else
+                                _state=STATE_URI;
+                        }
+                        else if (ch < HttpTokens.SPACE)
+                        {
+                            throw new HttpException(HttpStatus.BAD_REQUEST_400);
+                        }
+                        break;
+
+                    case STATE_STATUS:
+                        if (ch == HttpTokens.SPACE)
+                        {
+                            _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1);
+                            _state=STATE_SPACE2;
+                            continue;
+                        }
+                        else if (ch>='0' && ch<='9')
+                        {
+                            _responseStatus=_responseStatus*10+(ch-'0');
+                            continue;
+                        }
+                        else if (ch < HttpTokens.SPACE && ch>=0)
+                        {
+                            _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null);
+                            _eol=ch;
+                            _state=STATE_HEADER;
+                            _tok0.setPutIndex(_tok0.getIndex());
+                            _tok1.setPutIndex(_tok1.getIndex());
+                            _multiLineValue=null;
+                            continue;
+                        }
+                        // not a digit, so must be a URI
+                        _state=STATE_URI;
+                        _responseStatus=-1;
+                        break;
+
+                    case STATE_URI:
+                        if (ch == HttpTokens.SPACE)
+                        {
+                            _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1);
+                            _state=STATE_SPACE2;
+                            continue;
+                        }
+                        else if (ch < HttpTokens.SPACE && ch>=0)
+                        {
+                            // HTTP/0.9
+                            _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _buffer.sliceFromMark(), null);
+                            _persistent=false;
+                            _state=STATE_SEEKING_EOF;
+                            _handler.headerComplete();
+                            _handler.messageComplete(_contentPosition);
+                            return 1;
+                        }
+                        break;
+
+                    case STATE_SPACE2:
+                        if (ch > HttpTokens.SPACE || ch<0)
+                        {
+                            _buffer.mark();
+                            _state=STATE_FIELD2;
+                        }
+                        else if (ch < HttpTokens.SPACE)
+                        {
+                            if (_responseStatus>0)
+                            {
+                                _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null);
+                                _eol=ch;
+                                _state=STATE_HEADER;
+                                _tok0.setPutIndex(_tok0.getIndex());
+                                _tok1.setPutIndex(_tok1.getIndex());
+                                _multiLineValue=null;
+                            }
+                            else
+                            {
+                                // HTTP/0.9
+                                _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, null);
+                                _persistent=false;
+                                _state=STATE_SEEKING_EOF;
+                                _handler.headerComplete();
+                                _handler.messageComplete(_contentPosition);
+                                return 1;
+                            }
+                        }
+                        break;
+
+                    case STATE_FIELD2:
+                        if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
+                        {
+                            Buffer version;
+                            if (_responseStatus>0)
+                                _handler.startResponse(version=HttpVersions.CACHE.lookup(_tok0), _responseStatus,_buffer.sliceFromMark());
+                            else
+                                _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, version=HttpVersions.CACHE.lookup(_buffer.sliceFromMark()));
+                            _eol=ch;
+                            _persistent=HttpVersions.CACHE.getOrdinal(version)>=HttpVersions.HTTP_1_1_ORDINAL;
+                            _state=STATE_HEADER;
+                            _tok0.setPutIndex(_tok0.getIndex());
+                            _tok1.setPutIndex(_tok1.getIndex());
+                            _multiLineValue=null;
+                            continue;
+                        }
+                        break;
+
+                    case STATE_HEADER:
+                        switch(ch)
+                        {
+                            case HttpTokens.COLON:
+                            case HttpTokens.SPACE:
+                            case HttpTokens.TAB:
+                            {
+                                // header value without name - continuation?
+                                _length=-1;
+                                _state=STATE_HEADER_VALUE;
+                                break;
+                            }
+
+                            default:
+                            {
+                                // handler last header if any
+                                if (_cached!=null || _tok0.length() > 0 || _tok1.length() > 0 || _multiLineValue != null)
+                                {
+                                    Buffer header=_cached!=null?_cached:HttpHeaders.CACHE.lookup(_tok0);
+                                    _cached=null;
+                                    Buffer value=_multiLineValue == null ? _tok1 : new ByteArrayBuffer(_multiLineValue);
+
+                                    int ho=HttpHeaders.CACHE.getOrdinal(header);
+                                    if (ho >= 0)
+                                    {
+                                        int vo;
+
+                                        switch (ho)
+                                        {
+                                            case HttpHeaders.CONTENT_LENGTH_ORDINAL:
+                                                if (_contentLength != HttpTokens.CHUNKED_CONTENT )
+                                                {
+                                                    try
+                                                    {
+                                                        _contentLength=BufferUtil.toLong(value);
+                                                    }
+                                                    catch(NumberFormatException e)
+                                                    {
+                                                        LOG.ignore(e);
+                                                        throw new HttpException(HttpStatus.BAD_REQUEST_400);
+                                                    }
+                                                    if (_contentLength <= 0)
+                                                        _contentLength=HttpTokens.NO_CONTENT;
+                                                }
+                                                break;
+
+                                            case HttpHeaders.TRANSFER_ENCODING_ORDINAL:
+                                                value=HttpHeaderValues.CACHE.lookup(value);
+                                                vo=HttpHeaderValues.CACHE.getOrdinal(value);
+                                                if (HttpHeaderValues.CHUNKED_ORDINAL == vo)
+                                                    _contentLength=HttpTokens.CHUNKED_CONTENT;
+                                                else
+                                                {
+                                                    String c=value.toString(StringUtil.__ISO_8859_1);
+                                                    if (c.endsWith(HttpHeaderValues.CHUNKED))
+                                                        _contentLength=HttpTokens.CHUNKED_CONTENT;
+
+                                                    else if (c.indexOf(HttpHeaderValues.CHUNKED) >= 0)
+                                                        throw new HttpException(400,null);
+                                                }
+                                                break;
+
+                                            case HttpHeaders.CONNECTION_ORDINAL:
+                                                switch(HttpHeaderValues.CACHE.getOrdinal(value))
+                                                {
+                                                    case HttpHeaderValues.CLOSE_ORDINAL:
+                                                        _persistent=false;
+                                                        break;
+
+                                                    case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
+                                                        _persistent=true;
+                                                        break;
+
+                                                    case -1: // No match, may be multi valued
+                                                    {
+                                                        for (String v : value.toString().split(","))
+                                                        {
+                                                            switch(HttpHeaderValues.CACHE.getOrdinal(v.trim()))
+                                                            {
+                                                                case HttpHeaderValues.CLOSE_ORDINAL:
+                                                                    _persistent=false;
+                                                                    break;
+
+                                                                case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
+                                                                    _persistent=true;
+                                                                    break;
+                                                            }
+                                                        }
+                                                        break;
+                                                    }
+                                                }
+                                        }
+                                    }
+
+                                    _handler.parsedHeader(header, value);
+                                    _tok0.setPutIndex(_tok0.getIndex());
+                                    _tok1.setPutIndex(_tok1.getIndex());
+                                    _multiLineValue=null;
+                                }
+                                _buffer.setMarkIndex(-1);
+
+                                // now handle ch
+                                if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
+                                {
+                                    // is it a response that cannot have a body?
+                                    if (_responseStatus > 0  && // response  
+                                       (_responseStatus == 304  || // not-modified response
+                                        _responseStatus == 204 || // no-content response
+                                        _responseStatus < 200)) // 1xx response
+                                        _contentLength=HttpTokens.NO_CONTENT; // ignore any other headers set
+                                    // else if we don't know framing
+                                    else if (_contentLength == HttpTokens.UNKNOWN_CONTENT)
+                                    {
+                                        if (_responseStatus == 0  // request
+                                                || _responseStatus == 304 // not-modified response
+                                                || _responseStatus == 204 // no-content response
+                                                || _responseStatus < 200) // 1xx response
+                                            _contentLength=HttpTokens.NO_CONTENT;
+                                        else
+                                            _contentLength=HttpTokens.EOF_CONTENT;
+                                    }
+
+                                    _contentPosition=0;
+                                    _eol=ch;
+                                    if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED)
+                                        _eol=_buffer.get();
+
+                                    // We convert _contentLength to an int for this switch statement because
+                                    // we don't care about the amount of data available just whether there is some.
+                                    switch (_contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) _contentLength)
+                                    {
+                                        case HttpTokens.EOF_CONTENT:
+                                            _state=STATE_EOF_CONTENT;
+                                            _handler.headerComplete(); // May recurse here !
+                                            break;
+
+                                        case HttpTokens.CHUNKED_CONTENT:
+                                            _state=STATE_CHUNKED_CONTENT;
+                                            _handler.headerComplete(); // May recurse here !
+                                            break;
+
+                                        case HttpTokens.NO_CONTENT:
+                                            _handler.headerComplete();
+                                            _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF;
+                                            _handler.messageComplete(_contentPosition);
+                                            return 1;
+
+                                        default:
+                                            _state=STATE_CONTENT;
+                                            _handler.headerComplete(); // May recurse here !
+                                            break;
+                                    }
+                                    return 1;
+                                }
+                                else
+                                {
+                                    // New header
+                                    _length=1;
+                                    _buffer.mark();
+                                    _state=STATE_HEADER_NAME;
+
+                                    // try cached name!
+                                    if (array!=null)
+                                    {
+                                        _cached=HttpHeaders.CACHE.getBest(array, _buffer.markIndex(), length+1);
+
+                                        if (_cached!=null)
+                                        {
+                                            _length=_cached.length();
+                                            _buffer.setGetIndex(_buffer.markIndex()+_length);
+                                            length=_buffer.length();
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        break;
+
+                    case STATE_HEADER_NAME:
+                        switch(ch)
+                        {
+                            case HttpTokens.CARRIAGE_RETURN:
+                            case HttpTokens.LINE_FEED:
+                                if (_length > 0)
+                                    _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                _eol=ch;
+                                _state=STATE_HEADER;
+                                break;
+                            case HttpTokens.COLON:
+                                if (_length > 0 && _cached==null)
+                                    _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                _length=-1;
+                                _state=STATE_HEADER_VALUE;
+                                break;
+                            case HttpTokens.SPACE:
+                            case HttpTokens.TAB:
+                                break;
+                            default:
+                            {
+                                _cached=null;
+                                if (_length == -1)
+                                    _buffer.mark();
+                                _length=_buffer.getIndex() - _buffer.markIndex();
+                                _state=STATE_HEADER_IN_NAME;
+                            }
+                        }
+
+                        break;
+
+                    case STATE_HEADER_IN_NAME:
+                        switch(ch)
+                        {
+                            case HttpTokens.CARRIAGE_RETURN:
+                            case HttpTokens.LINE_FEED:
+                                if (_length > 0)
+                                    _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                _eol=ch;
+                                _state=STATE_HEADER;
+                                break;
+                            case HttpTokens.COLON:
+                                if (_length > 0 && _cached==null)
+                                    _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                _length=-1;
+                                _state=STATE_HEADER_VALUE;
+                                break;
+                            case HttpTokens.SPACE:
+                            case HttpTokens.TAB:
+                                _state=STATE_HEADER_NAME;
+                                break;
+                            default:
+                            {
+                                _cached=null;
+                                _length++;
+                            }
+                        }
+                        break;
+
+                    case STATE_HEADER_VALUE:
+                        switch(ch)
+                        {
+                            case HttpTokens.CARRIAGE_RETURN:
+                            case HttpTokens.LINE_FEED:
+                                if (_length > 0)
+                                {
+                                    if (_tok1.length() == 0)
+                                        _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                    else
+                                    {
+                                        // Continuation line!
+                                        if (_multiLineValue == null) _multiLineValue=_tok1.toString(StringUtil.__ISO_8859_1);
+                                        _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                        _multiLineValue += " " + _tok1.toString(StringUtil.__ISO_8859_1);
+                                    }
+                                }
+                                _eol=ch;
+                                _state=STATE_HEADER;
+                                break;
+                            case HttpTokens.SPACE:
+                            case HttpTokens.TAB:
+                                break;
+                            default:
+                            {
+                                if (_length == -1)
+                                    _buffer.mark();
+                                _length=_buffer.getIndex() - _buffer.markIndex();
+                                _state=STATE_HEADER_IN_VALUE;
+                            }
+                        }
+                        break;
+
+                    case STATE_HEADER_IN_VALUE:
+                        switch(ch)
+                        {
+                            case HttpTokens.CARRIAGE_RETURN:
+                            case HttpTokens.LINE_FEED:
+                                if (_length > 0)
+                                {
+                                    if (_tok1.length() == 0)
+                                        _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                    else
+                                    {
+                                        // Continuation line!
+                                        if (_multiLineValue == null) _multiLineValue=_tok1.toString(StringUtil.__ISO_8859_1);
+                                        _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length);
+                                        _multiLineValue += " " + _tok1.toString(StringUtil.__ISO_8859_1);
+                                    }
+                                }
+                                _eol=ch;
+                                _state=STATE_HEADER;
+                                break;
+                            case HttpTokens.SPACE:
+                            case HttpTokens.TAB:
+                                _state=STATE_HEADER_VALUE;
+                                break;
+                            default:
+                                _length++;
+                        }
+                        break;
+                }
+            } // end of HEADER states loop
+
+            // ==========================
+
+            // Handle HEAD response
+            if (_responseStatus>0 && _headResponse)
+            {
+                _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF;
+                _handler.messageComplete(_contentLength);
+            }
+
+
+            // ==========================
+
+            // Handle _content
+            length=_buffer.length();
+            Buffer chunk;
+            last=_state;
+            while (_state > STATE_END && length > 0)
+            {
+                if (last!=_state)
+                {
+                    progress++;
+                    last=_state;
+                }
+
+                if (_eol == HttpTokens.CARRIAGE_RETURN && _buffer.peek() == HttpTokens.LINE_FEED)
+                {
+                    _eol=_buffer.get();
+                    length=_buffer.length();
+                    continue;
+                }
+                _eol=0;
+                switch (_state)
+                {
+                    case STATE_EOF_CONTENT:
+                        chunk=_buffer.get(_buffer.length());
+                        _contentPosition += chunk.length();
+                        _contentView.update(chunk);
+                        _handler.content(chunk); // May recurse here
+                        // TODO adjust the _buffer to keep unconsumed content
+                        return 1;
+
+                    case STATE_CONTENT:
+                    {
+                        long remaining=_contentLength - _contentPosition;
+                        if (remaining == 0)
+                        {
+                            _state=_persistent?STATE_END:STATE_SEEKING_EOF;
+                            _handler.messageComplete(_contentPosition);
+                            return 1;
+                        }
+
+                        if (length > remaining)
+                        {
+                            // We can cast reamining to an int as we know that it is smaller than
+                            // or equal to length which is already an int.
+                            length=(int)remaining;
+                        }
+
+                        chunk=_buffer.get(length);
+                        _contentPosition += chunk.length();
+                        _contentView.update(chunk);
+                        _handler.content(chunk); // May recurse here
+
+                        if(_contentPosition == _contentLength)
+                        {
+                            _state=_persistent?STATE_END:STATE_SEEKING_EOF;
+                            _handler.messageComplete(_contentPosition);
+                        }
+                        // TODO adjust the _buffer to keep unconsumed content
+                        return 1;
+                    }
+
+                    case STATE_CHUNKED_CONTENT:
+                    {
+                        ch=_buffer.peek();
+                        if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
+                            _eol=_buffer.get();
+                        else if (ch <= HttpTokens.SPACE)
+                            _buffer.get();
+                        else
+                        {
+                            _chunkLength=0;
+                            _chunkPosition=0;
+                            _state=STATE_CHUNK_SIZE;
+                        }
+                        break;
+                    }
+
+                    case STATE_CHUNK_SIZE:
+                    {
+                        ch=_buffer.get();
+                        if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
+                        {
+                            _eol=ch;
+
+                            if (_chunkLength == 0)
+                            {
+                                if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED)
+                                    _eol=_buffer.get();
+                                _state=_persistent?STATE_END:STATE_SEEKING_EOF;
+                                _handler.messageComplete(_contentPosition);
+                                return 1;
+                            }
+                            else
+                                _state=STATE_CHUNK;
+                        }
+                        else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON)
+                            _state=STATE_CHUNK_PARAMS;
+                        else if (ch >= '0' && ch <= '9')
+                            _chunkLength=_chunkLength * 16 + (ch - '0');
+                        else if (ch >= 'a' && ch <= 'f')
+                            _chunkLength=_chunkLength * 16 + (10 + ch - 'a');
+                        else if (ch >= 'A' && ch <= 'F')
+                            _chunkLength=_chunkLength * 16 + (10 + ch - 'A');
+                        else
+                            throw new IOException("bad chunk char: " + ch);
+                        break;
+                    }
+
+                    case STATE_CHUNK_PARAMS:
+                    {
+                        ch=_buffer.get();
+                        if (ch == HttpTokens.CARRIAGE_RETURN || ch == HttpTokens.LINE_FEED)
+                        {
+                            _eol=ch;
+                            if (_chunkLength == 0)
+                            {
+                                if (_eol==HttpTokens.CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==HttpTokens.LINE_FEED)
+                                    _eol=_buffer.get();
+                                _state=_persistent?STATE_END:STATE_SEEKING_EOF;
+                                _handler.messageComplete(_contentPosition);
+                                return 1;
+                            }
+                            else
+                                _state=STATE_CHUNK;
+                        }
+                        break;
+                    }
+
+                    case STATE_CHUNK:
+                    {
+                        int remaining=_chunkLength - _chunkPosition;
+                        if (remaining == 0)
+                        {
+                            _state=STATE_CHUNKED_CONTENT;
+                            break;
+                        }
+                        else if (length > remaining)
+                            length=remaining;
+                        chunk=_buffer.get(length);
+                        _contentPosition += chunk.length();
+                        _chunkPosition += chunk.length();
+                        _contentView.update(chunk);
+                        _handler.content(chunk); // May recurse here
+                        // TODO adjust the _buffer to keep unconsumed content
+                        return 1;
+                    }
+
+                    case STATE_SEEKING_EOF:
+                    {                        
+                        // Close if there is more data than CRLF
+                        if (_buffer.length()>2)
+                        {
+                            _state=STATE_END;
+                            _endp.close();
+                        }
+                        else  
+                        {
+                            // or if the data is not white space
+                            while (_buffer.length()>0)
+                                if (!Character.isWhitespace(_buffer.get()))
+                                {
+                                    _state=STATE_END;
+                                    _endp.close();
+                                    _buffer.clear();
+                                }
+                        }
+                        
+                        _buffer.clear();
+                        break;
+                    }
+                }
+
+                length=_buffer.length();
+            }
+
+            return progress;
+        }
+        catch(HttpException e)
+        {
+            _persistent=false;
+            _state=STATE_SEEKING_EOF;
+            throw e;
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /** fill the buffers from the endpoint
+     *
+     */
+    protected int fill() throws IOException
+    {
+        // Do we have a buffer?
+        if (_buffer==null)
+            _buffer=getHeaderBuffer();
+
+        // Is there unconsumed content in body buffer
+        if (_state>STATE_END && _buffer==_header && _header!=null && !_header.hasContent() && _body!=null && _body.hasContent())
+        {
+            _buffer=_body;
+            return _buffer.length();
+        }
+
+        // Shall we switch to a body buffer?
+        if (_buffer==_header && _state>STATE_END && _header.length()==0 && (_forceContentBuffer || (_contentLength-_contentPosition)>_header.capacity()) && (_body!=null||_buffers!=null))
+        {
+            if (_body==null)
+                _body=_buffers.getBuffer();
+            _buffer=_body;
+        }
+
+        // Do we have somewhere to fill from?
+        if (_endp != null )
+        {
+            // Shall we compact the body?
+            if (_buffer==_body || _state>STATE_END)
+            {
+                _buffer.compact();
+            }
+
+            // Are we full?
+            if (_buffer.space() == 0)
+            {
+                LOG.warn("HttpParser Full for {} ",_endp);
+                _buffer.clear();
+                throw new HttpException(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large: "+(_buffer==_body?"body":"head"));
+            }
+
+            try
+            {
+                int filled = _endp.fill(_buffer);
+                return filled;
+            }
+            catch(IOException e)
+            {
+                LOG.debug(e);
+                throw (e instanceof EofException) ? e:new EofException(e);
+            }
+        }
+
+        return -1;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void reset()
+    {
+        // reset state
+        _contentView.setGetIndex(_contentView.putIndex());
+        _state=_persistent?STATE_START:(_endp.isInputShutdown()?STATE_END:STATE_SEEKING_EOF);
+        _contentLength=HttpTokens.UNKNOWN_CONTENT;
+        _contentPosition=0;
+        _length=0;
+        _responseStatus=0;
+
+        // Consume LF if CRLF
+        if (_eol == HttpTokens.CARRIAGE_RETURN && _buffer!=null && _buffer.hasContent() && _buffer.peek() == HttpTokens.LINE_FEED)
+            _eol=_buffer.get();
+
+        if (_body!=null && _body.hasContent())
+        {
+            // There is content in the body after the end of the request.
+            // This is probably a pipelined header of the next request, so we need to
+            // copy it to the header buffer.
+            if (_header==null)
+                getHeaderBuffer();
+            else
+            {
+                _header.setMarkIndex(-1);
+                _header.compact();
+            }
+            int take=_header.space();
+            if (take>_body.length())
+                take=_body.length();
+            _body.peek(_body.getIndex(),take);
+            _body.skip(_header.put(_body.peek(_body.getIndex(),take)));
+        }
+
+        if (_header!=null)
+        {
+            _header.setMarkIndex(-1);
+            _header.compact();
+        }
+        if (_body!=null)
+            _body.setMarkIndex(-1);
+
+        _buffer=_header;
+        returnBuffers();
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    public void returnBuffers()
+    {
+        if (_body!=null && !_body.hasContent() && _body.markIndex()==-1 && _buffers!=null)
+        {
+            if (_buffer==_body)
+                _buffer=_header;
+            if (_buffers!=null)
+                _buffers.returnBuffer(_body);
+            _body=null;
+        }
+
+        if (_header!=null && !_header.hasContent() && _header.markIndex()==-1 && _buffers!=null)
+        {
+            if (_buffer==_header)
+                _buffer=null;
+            _buffers.returnBuffer(_header);
+            _header=null;
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public void setState(int state)
+    {
+        this._state=state;
+        _contentLength=HttpTokens.UNKNOWN_CONTENT;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public String toString(Buffer buf)
+    {
+        return "state=" + _state + " length=" + _length + " buf=" + buf.hashCode();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public String toString()
+    {
+        return String.format("%s{s=%d,l=%d,c=%d}",
+                getClass().getSimpleName(),
+                _state,
+                _length,
+                _contentLength);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getHeaderBuffer()
+    {
+        if (_header == null)
+        {
+            _header=_buffers.getHeader();
+            _tok0.update(_header);
+            _tok1.update(_header);
+        }
+        return _header;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBodyBuffer()
+    {
+        return _body;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param force True if a new buffer will be forced to be used for content and the header buffer will not be used.
+     */
+    public void setForceContentBuffer(boolean force)
+    {
+        _forceContentBuffer=force;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer blockForContent(long maxIdleTime) throws IOException
+    {
+        if (_contentView.length()>0)
+            return _contentView;
+
+        if (getState() <= STATE_END || isState(STATE_SEEKING_EOF))
+            return null;
+
+        try
+        {
+            parseNext();
+
+            // parse until some progress is made (or IOException thrown for timeout)
+            while(_contentView.length() == 0 && !(isState(HttpParser.STATE_END)||isState(HttpParser.STATE_SEEKING_EOF)) && _endp!=null && _endp.isOpen())
+            {
+                if (!_endp.isBlocking())
+                {
+                    if (parseNext()>0)
+                        continue;
+
+                    if (!_endp.blockReadable(maxIdleTime))
+                    {
+                        _endp.close();
+                        throw new EofException("timeout");
+                    }
+                }
+
+                parseNext();
+            }
+        }
+        catch(IOException e)
+        {
+            // TODO is this needed?
+            _endp.close();
+            throw e;
+        }
+
+        return _contentView.length()>0?_contentView:null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see java.io.InputStream#available()
+     */
+    public int available() throws IOException
+    {
+        if (_contentView!=null && _contentView.length()>0)
+            return _contentView.length();
+
+        if (_endp.isBlocking())
+        {
+            if (_state>0 && _endp instanceof StreamEndPoint)
+                return ((StreamEndPoint)_endp).getInputStream().available()>0?1:0;
+
+            return 0;
+        }
+
+        parseNext();
+        return _contentView==null?0:_contentView.length();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static abstract class EventHandler
+    {
+        public abstract void content(Buffer ref) throws IOException;
+
+        public void headerComplete() throws IOException
+        {
+        }
+
+        public void messageComplete(long contentLength) throws IOException
+        {
+        }
+
+        /**
+         * This is the method called by parser when a HTTP Header name and value is found
+         */
+        public void parsedHeader(Buffer name, Buffer value) throws IOException
+        {
+        }
+
+        /**
+         * This is the method called by parser when the HTTP request line is parsed
+         */
+        public abstract void startRequest(Buffer method, Buffer url, Buffer version)
+                throws IOException;
+
+        /**
+         * This is the method called by parser when the HTTP request line is parsed
+         */
+        public abstract void startResponse(Buffer version, int status, Buffer reason)
+                throws IOException;
+
+        public void earlyEOF()
+        {}
+    }
+
+
+
+
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpSchemes.java b/src/java/org/eclipse/jetty/http/HttpSchemes.java
new file mode 100644
index 0000000..ceef394
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpSchemes.java
@@ -0,0 +1,38 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * 
+ * 
+ */
+public class HttpSchemes
+{
+    public final static String
+        HTTP ="http",
+        HTTPS="https";
+    
+    public final static Buffer
+        HTTP_BUFFER = new ByteArrayBuffer(HTTP),
+        HTTPS_BUFFER = new ByteArrayBuffer(HTTPS);
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpStatus.java b/src/java/org/eclipse/jetty/http/HttpStatus.java
new file mode 100644
index 0000000..7db1fa6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpStatus.java
@@ -0,0 +1,1036 @@
+//
+//  ========================================================================
+//  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.http;
+
+/**
+ * <p>
+ * HttpStatusCode enum class, for status codes based on various HTTP RFCs. (see
+ * table below)
+ * </p>
+ *
+ * <table border="1" cellpadding="5">
+ * <tr>
+ * <th>Enum</th>
+ * <th>Code</th>
+ * <th>Message</th>
+ * <th>
+ * <a href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a></th>
+ * <th>
+ * <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a></th>
+ * <th>
+ * <a href="http://tools.ietf.org/html/rfc2518">RFC 2518 - WEBDAV</a></th>
+ * </tr>
+ *
+ * <tr>
+ * <td><strong><code>Informational - 1xx</code></strong></td>
+ * <td colspan="5">{@link #isInformational(int)}</td>
+ * </tr>
+ *
+ * <tr>
+ * <td>{@link #CONTINUE_100}</td>
+ * <td>100</td>
+ * <td>Continue</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.1.1">Sec. 10.1.1</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #SWITCHING_PROTOCOLS_101}</td>
+ * <td>101</td>
+ * <td>Switching Protocols</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.1.2">Sec. 10.1.2</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PROCESSING_102}</td>
+ * <td>102</td>
+ * <td>Processing</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.1">Sec. 10.1</a></td>
+ * </tr>
+ *
+ * <tr>
+ * <td><strong><code>Success - 2xx</code></strong></td>
+ * <td colspan="5">{@link #isSuccess(int)}</td>
+ * </tr>
+ *
+ * <tr>
+ * <td>{@link #OK_200}</td>
+ * <td>200</td>
+ * <td>OK</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.1">Sec. 10.2.1</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #CREATED_201}</td>
+ * <td>201</td>
+ * <td>Created</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.2">Sec. 10.2.2</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #ACCEPTED_202}</td>
+ * <td>202</td>
+ * <td>Accepted</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.3">Sec. 10.2.3</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NON_AUTHORITATIVE_INFORMATION_203}</td>
+ * <td>203</td>
+ * <td>Non Authoritative Information</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.4">Sec. 10.2.4</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NO_CONTENT_204}</td>
+ * <td>204</td>
+ * <td>No Content</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.2">Sec. 9.2</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.5">Sec. 10.2.5</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #RESET_CONTENT_205}</td>
+ * <td>205</td>
+ * <td>Reset Content</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.6">Sec. 10.2.6</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PARTIAL_CONTENT_206}</td>
+ * <td>206</td>
+ * <td>Partial Content</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.2.7">Sec. 10.2.7</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #MULTI_STATUS_207}</td>
+ * <td>207</td>
+ * <td>Multi-Status</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.2">Sec. 10.2</a></td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>207</strike></td>
+ * <td><strike>Partial Update OK</strike></td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-rev-01.txt"
+ * >draft/01</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ *
+ * <tr>
+ * <td><strong><code>Redirection - 3xx</code></strong></td>
+ * <td colspan="5">{@link #isRedirection(int)}</td>
+ * </tr>
+ *
+ * <tr>
+ * <td>{@link #MULTIPLE_CHOICES_300}</td>
+ * <td>300</td>
+ * <td>Multiple Choices</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.1">Sec. 10.3.1</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #MOVED_PERMANENTLY_301}</td>
+ * <td>301</td>
+ * <td>Moved Permanently</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.2">Sec. 10.3.2</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #MOVED_TEMPORARILY_302}</td>
+ * <td>302</td>
+ * <td>Moved Temporarily</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td>
+ * <td>(now "<code>302 Found</code>")</td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #FOUND_302}</td>
+ * <td>302</td>
+ * <td>Found</td>
+ * <td>(was "<code>302 Moved Temporarily</code>")</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.3">Sec. 10.3.3</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #SEE_OTHER_303}</td>
+ * <td>303</td>
+ * <td>See Other</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.4">Sec. 10.3.4</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NOT_MODIFIED_304}</td>
+ * <td>304</td>
+ * <td>Not Modified</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.3">Sec. 9.3</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.5">Sec. 10.3.5</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #USE_PROXY_305}</td>
+ * <td>305</td>
+ * <td>Use Proxy</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.6">Sec. 10.3.6</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td>306</td>
+ * <td><em>(Unused)</em></td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.7">Sec. 10.3.7</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #TEMPORARY_REDIRECT_307}</td>
+ * <td>307</td>
+ * <td>Temporary Redirect</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.3.8">Sec. 10.3.8</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ *
+ * <tr>
+ * <td><strong><code>Client Error - 4xx</code></strong></td>
+ * <td colspan="5">{@link #isClientError(int)}</td>
+ * </tr>
+ *
+ * <tr>
+ * <td>{@link #BAD_REQUEST_400}</td>
+ * <td>400</td>
+ * <td>Bad Request</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.1">Sec. 10.4.1</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #UNAUTHORIZED_401}</td>
+ * <td>401</td>
+ * <td>Unauthorized</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.2">Sec. 10.4.2</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PAYMENT_REQUIRED_402}</td>
+ * <td>402</td>
+ * <td>Payment Required</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.3">Sec. 10.4.3</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #FORBIDDEN_403}</td>
+ * <td>403</td>
+ * <td>Forbidden</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.4">Sec. 10.4.4</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NOT_FOUND_404}</td>
+ * <td>404</td>
+ * <td>Not Found</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.4">Sec. 9.4</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.5">Sec. 10.4.5</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #METHOD_NOT_ALLOWED_405}</td>
+ * <td>405</td>
+ * <td>Method Not Allowed</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.6">Sec. 10.4.6</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NOT_ACCEPTABLE_406}</td>
+ * <td>406</td>
+ * <td>Not Acceptable</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.7">Sec. 10.4.7</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PROXY_AUTHENTICATION_REQUIRED_407}</td>
+ * <td>407</td>
+ * <td>Proxy Authentication Required</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.8">Sec. 10.4.8</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #REQUEST_TIMEOUT_408}</td>
+ * <td>408</td>
+ * <td>Request Timeout</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.9">Sec. 10.4.9</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #CONFLICT_409}</td>
+ * <td>409</td>
+ * <td>Conflict</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.10">Sec. 10.4.10</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #GONE_410}</td>
+ * <td>410</td>
+ * <td>Gone</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.11">Sec. 10.4.11</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #LENGTH_REQUIRED_411}</td>
+ * <td>411</td>
+ * <td>Length Required</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.12">Sec. 10.4.12</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PRECONDITION_FAILED_412}</td>
+ * <td>412</td>
+ * <td>Precondition Failed</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.13">Sec. 10.4.13</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #REQUEST_ENTITY_TOO_LARGE_413}</td>
+ * <td>413</td>
+ * <td>Request Entity Too Large</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.14">Sec. 10.4.14</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #REQUEST_URI_TOO_LONG_414}</td>
+ * <td>414</td>
+ * <td>Request-URI Too Long</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.15">Sec. 10.4.15</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #UNSUPPORTED_MEDIA_TYPE_415}</td>
+ * <td>415</td>
+ * <td>Unsupported Media Type</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.16">Sec. 10.4.16</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #REQUESTED_RANGE_NOT_SATISFIABLE_416}</td>
+ * <td>416</td>
+ * <td>Requested Range Not Satisfiable</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.17">Sec. 10.4.17</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #EXPECTATION_FAILED_417}</td>
+ * <td>417</td>
+ * <td>Expectation Failed</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.4.18">Sec. 10.4.18</a>
+ * </td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>418</strike></td>
+ * <td><strike>Reauthentication Required</strike></td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://tools.ietf.org/html/draft-ietf-http-v11-spec-rev-01#section-10.4.19"
+ * >draft/01</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>418</strike></td>
+ * <td><strike>Unprocessable Entity</strike></td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.3"
+ * >draft/05</a></td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>419</strike></td>
+ * <td><strike>Proxy Reauthentication Required</stike></td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://tools.ietf.org/html/draft-ietf-http-v11-spec-rev-01#section-10.4.20"
+ * >draft/01</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>419</strike></td>
+ * <td><strike>Insufficient Space on Resource</stike></td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.4"
+ * >draft/05</a></td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td><strike>420</strike></td>
+ * <td><strike>Method Failure</strike></td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href=
+ * "http://tools.ietf.org/html/draft-ietf-webdav-protocol-05#section-10.5"
+ * >draft/05</a></td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td>421</td>
+ * <td><em>(Unused)</em></td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #UNPROCESSABLE_ENTITY_422}</td>
+ * <td>422</td>
+ * <td>Unprocessable Entity</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.3">Sec. 10.3</a></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #LOCKED_423}</td>
+ * <td>423</td>
+ * <td>Locked</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.4">Sec. 10.4</a></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #FAILED_DEPENDENCY_424}</td>
+ * <td>424</td>
+ * <td>Failed Dependency</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.5">Sec. 10.5</a></td>
+ * </tr>
+ *
+ * <tr>
+ * <td><strong><code>Server Error - 5xx</code></strong></td>
+ * <td colspan="5">{@link #isServerError(int)}</td>
+ * </tr>
+ *
+ * <tr>
+ * <td>{@link #INTERNAL_SERVER_ERROR_500}</td>
+ * <td>500</td>
+ * <td>Internal Server Error</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.1">Sec. 10.5.1</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #NOT_IMPLEMENTED_501}</td>
+ * <td>501</td>
+ * <td>Not Implemented</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.2">Sec. 10.5.2</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #BAD_GATEWAY_502}</td>
+ * <td>502</td>
+ * <td>Bad Gateway</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.3">Sec. 10.5.3</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #SERVICE_UNAVAILABLE_503}</td>
+ * <td>503</td>
+ * <td>Service Unavailable</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc1945#section-9.5">Sec. 9.5</a></td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.4">Sec. 10.5.4</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #GATEWAY_TIMEOUT_504}</td>
+ * <td>504</td>
+ * <td>Gateway Timeout</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.5">Sec. 10.5.5</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #HTTP_VERSION_NOT_SUPPORTED_505}</td>
+ * <td>505</td>
+ * <td>HTTP Version Not Supported</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2616#section-10.5.6">Sec. 10.5.6</a></td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>&nbsp;</td>
+ * <td>506</td>
+ * <td><em>(Unused)</em></td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #INSUFFICIENT_STORAGE_507}</td>
+ * <td>507</td>
+ * <td>Insufficient Storage</td>
+ * <td>&nbsp;</td>
+ * <td>&nbsp;</td>
+ * <td>
+ * <a href="http://tools.ietf.org/html/rfc2518#section-10.6">Sec. 10.6</a></td>
+ * </tr>
+ *
+ * </table>
+ *
+ * @version $Id$
+ */
+public class HttpStatus
+{
+    public final static int CONTINUE_100 = 100;
+    public final static int SWITCHING_PROTOCOLS_101 = 101;
+    public final static int PROCESSING_102 = 102;
+
+    public final static int OK_200 = 200;
+    public final static int CREATED_201 = 201;
+    public final static int ACCEPTED_202 = 202;
+    public final static int NON_AUTHORITATIVE_INFORMATION_203 = 203;
+    public final static int NO_CONTENT_204 = 204;
+    public final static int RESET_CONTENT_205 = 205;
+    public final static int PARTIAL_CONTENT_206 = 206;
+    public final static int MULTI_STATUS_207 = 207;
+
+    public final static int MULTIPLE_CHOICES_300 = 300;
+    public final static int MOVED_PERMANENTLY_301 = 301;
+    public final static int MOVED_TEMPORARILY_302 = 302;
+    public final static int FOUND_302 = 302;
+    public final static int SEE_OTHER_303 = 303;
+    public final static int NOT_MODIFIED_304 = 304;
+    public final static int USE_PROXY_305 = 305;
+    public final static int TEMPORARY_REDIRECT_307 = 307;
+
+    public final static int BAD_REQUEST_400 = 400;
+    public final static int UNAUTHORIZED_401 = 401;
+    public final static int PAYMENT_REQUIRED_402 = 402;
+    public final static int FORBIDDEN_403 = 403;
+    public final static int NOT_FOUND_404 = 404;
+    public final static int METHOD_NOT_ALLOWED_405 = 405;
+    public final static int NOT_ACCEPTABLE_406 = 406;
+    public final static int PROXY_AUTHENTICATION_REQUIRED_407 = 407;
+    public final static int REQUEST_TIMEOUT_408 = 408;
+    public final static int CONFLICT_409 = 409;
+    public final static int GONE_410 = 410;
+    public final static int LENGTH_REQUIRED_411 = 411;
+    public final static int PRECONDITION_FAILED_412 = 412;
+    public final static int REQUEST_ENTITY_TOO_LARGE_413 = 413;
+    public final static int REQUEST_URI_TOO_LONG_414 = 414;
+    public final static int UNSUPPORTED_MEDIA_TYPE_415 = 415;
+    public final static int REQUESTED_RANGE_NOT_SATISFIABLE_416 = 416;
+    public final static int EXPECTATION_FAILED_417 = 417;
+    public final static int UNPROCESSABLE_ENTITY_422 = 422;
+    public final static int LOCKED_423 = 423;
+    public final static int FAILED_DEPENDENCY_424 = 424;
+
+    public final static int INTERNAL_SERVER_ERROR_500 = 500;
+    public final static int NOT_IMPLEMENTED_501 = 501;
+    public final static int BAD_GATEWAY_502 = 502;
+    public final static int SERVICE_UNAVAILABLE_503 = 503;
+    public final static int GATEWAY_TIMEOUT_504 = 504;
+    public final static int HTTP_VERSION_NOT_SUPPORTED_505 = 505;
+    public final static int INSUFFICIENT_STORAGE_507 = 507;
+
+    public static final int MAX_CODE = 507;
+
+
+    private static final Code[] codeMap = new Code[MAX_CODE+1];
+
+    static
+    {
+        for (Code code : Code.values())
+        {
+            codeMap[code._code] = code;
+        }
+    }
+
+
+    public enum Code
+    {
+        /*
+         * --------------------------------------------------------------------
+         * Informational messages in 1xx series. As defined by ... RFC 1945 -
+         * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+         */
+
+        /** <code>100 Continue</code> */
+        CONTINUE(CONTINUE_100, "Continue"),
+        /** <code>101 Switching Protocols</code> */
+        SWITCHING_PROTOCOLS(SWITCHING_PROTOCOLS_101, "Switching Protocols"),
+        /** <code>102 Processing</code> */
+        PROCESSING(PROCESSING_102, "Processing"),
+
+        /*
+         * --------------------------------------------------------------------
+         * Success messages in 2xx series. As defined by ... RFC 1945 - HTTP/1.0
+         * RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+         */
+
+        /** <code>200 OK</code> */
+        OK(OK_200, "OK"),
+        /** <code>201 Created</code> */
+        CREATED(CREATED_201, "Created"),
+        /** <code>202 Accepted</code> */
+        ACCEPTED(ACCEPTED_202, "Accepted"),
+        /** <code>203 Non Authoritative Information</code> */
+        NON_AUTHORITATIVE_INFORMATION(NON_AUTHORITATIVE_INFORMATION_203, "Non Authoritative Information"),
+        /** <code>204 No Content</code> */
+        NO_CONTENT(NO_CONTENT_204, "No Content"),
+        /** <code>205 Reset Content</code> */
+        RESET_CONTENT(RESET_CONTENT_205, "Reset Content"),
+        /** <code>206 Partial Content</code> */
+        PARTIAL_CONTENT(PARTIAL_CONTENT_206, "Partial Content"),
+        /** <code>207 Multi-Status</code> */
+        MULTI_STATUS(MULTI_STATUS_207, "Multi-Status"),
+
+        /*
+         * --------------------------------------------------------------------
+         * Redirection messages in 3xx series. As defined by ... RFC 1945 -
+         * HTTP/1.0 RFC 2616 - HTTP/1.1
+         */
+
+        /** <code>300 Mutliple Choices</code> */
+        MULTIPLE_CHOICES(MULTIPLE_CHOICES_300, "Multiple Choices"),
+        /** <code>301 Moved Permanently</code> */
+        MOVED_PERMANENTLY(MOVED_PERMANENTLY_301, "Moved Permanently"),
+        /** <code>302 Moved Temporarily</code> */
+        MOVED_TEMPORARILY(MOVED_TEMPORARILY_302, "Moved Temporarily"),
+        /** <code>302 Found</code> */
+        FOUND(FOUND_302, "Found"),
+        /** <code>303 See Other</code> */
+        SEE_OTHER(SEE_OTHER_303, "See Other"),
+        /** <code>304 Not Modified</code> */
+        NOT_MODIFIED(NOT_MODIFIED_304, "Not Modified"),
+        /** <code>305 Use Proxy</code> */
+        USE_PROXY(USE_PROXY_305, "Use Proxy"),
+        /** <code>307 Temporary Redirect</code> */
+        TEMPORARY_REDIRECT(TEMPORARY_REDIRECT_307, "Temporary Redirect"),
+
+        /*
+         * --------------------------------------------------------------------
+         * Client Error messages in 4xx series. As defined by ... RFC 1945 -
+         * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+         */
+
+        /** <code>400 Bad Request</code> */
+        BAD_REQUEST(BAD_REQUEST_400, "Bad Request"),
+        /** <code>401 Unauthorized</code> */
+        UNAUTHORIZED(UNAUTHORIZED_401, "Unauthorized"),
+        /** <code>402 Payment Required</code> */
+        PAYMENT_REQUIRED(PAYMENT_REQUIRED_402, "Payment Required"),
+        /** <code>403 Forbidden</code> */
+        FORBIDDEN(FORBIDDEN_403, "Forbidden"),
+        /** <code>404 Not Found</code> */
+        NOT_FOUND(NOT_FOUND_404, "Not Found"),
+        /** <code>405 Method Not Allowed</code> */
+        METHOD_NOT_ALLOWED(METHOD_NOT_ALLOWED_405, "Method Not Allowed"),
+        /** <code>406 Not Acceptable</code> */
+        NOT_ACCEPTABLE(NOT_ACCEPTABLE_406, "Not Acceptable"),
+        /** <code>407 Proxy Authentication Required</code> */
+        PROXY_AUTHENTICATION_REQUIRED(PROXY_AUTHENTICATION_REQUIRED_407, "Proxy Authentication Required"),
+        /** <code>408 Request Timeout</code> */
+        REQUEST_TIMEOUT(REQUEST_TIMEOUT_408, "Request Timeout"),
+        /** <code>409 Conflict</code> */
+        CONFLICT(CONFLICT_409, "Conflict"),
+        /** <code>410 Gone</code> */
+        GONE(GONE_410, "Gone"),
+        /** <code>411 Length Required</code> */
+        LENGTH_REQUIRED(LENGTH_REQUIRED_411, "Length Required"),
+        /** <code>412 Precondition Failed</code> */
+        PRECONDITION_FAILED(PRECONDITION_FAILED_412, "Precondition Failed"),
+        /** <code>413 Request Entity Too Large</code> */
+        REQUEST_ENTITY_TOO_LARGE(REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large"),
+        /** <code>414 Request-URI Too Long</code> */
+        REQUEST_URI_TOO_LONG(REQUEST_URI_TOO_LONG_414, "Request-URI Too Long"),
+        /** <code>415 Unsupported Media Type</code> */
+        UNSUPPORTED_MEDIA_TYPE(UNSUPPORTED_MEDIA_TYPE_415, "Unsupported Media Type"),
+        /** <code>416 Requested Range Not Satisfiable</code> */
+        REQUESTED_RANGE_NOT_SATISFIABLE(REQUESTED_RANGE_NOT_SATISFIABLE_416, "Requested Range Not Satisfiable"),
+        /** <code>417 Expectation Failed</code> */
+        EXPECTATION_FAILED(EXPECTATION_FAILED_417, "Expectation Failed"),
+        /** <code>422 Unprocessable Entity</code> */
+        UNPROCESSABLE_ENTITY(UNPROCESSABLE_ENTITY_422, "Unprocessable Entity"),
+        /** <code>423 Locked</code> */
+        LOCKED(LOCKED_423, "Locked"),
+        /** <code>424 Failed Dependency</code> */
+        FAILED_DEPENDENCY(FAILED_DEPENDENCY_424, "Failed Dependency"),
+
+        /*
+         * --------------------------------------------------------------------
+         * Server Error messages in 5xx series. As defined by ... RFC 1945 -
+         * HTTP/1.0 RFC 2616 - HTTP/1.1 RFC 2518 - WebDAV
+         */
+
+        /** <code>500 Server Error</code> */
+        INTERNAL_SERVER_ERROR(INTERNAL_SERVER_ERROR_500, "Server Error"),
+        /** <code>501 Not Implemented</code> */
+        NOT_IMPLEMENTED(NOT_IMPLEMENTED_501, "Not Implemented"),
+        /** <code>502 Bad Gateway</code> */
+        BAD_GATEWAY(BAD_GATEWAY_502, "Bad Gateway"),
+        /** <code>503 Service Unavailable</code> */
+        SERVICE_UNAVAILABLE(SERVICE_UNAVAILABLE_503, "Service Unavailable"),
+        /** <code>504 Gateway Timeout</code> */
+        GATEWAY_TIMEOUT(GATEWAY_TIMEOUT_504, "Gateway Timeout"),
+        /** <code>505 HTTP Version Not Supported</code> */
+        HTTP_VERSION_NOT_SUPPORTED(HTTP_VERSION_NOT_SUPPORTED_505, "HTTP Version Not Supported"),
+        /** <code>507 Insufficient Storage</code> */
+        INSUFFICIENT_STORAGE(INSUFFICIENT_STORAGE_507, "Insufficient Storage");
+
+        private final int _code;
+        private final String _message;
+
+        private Code(int code, String message)
+        {
+            this._code = code;
+            _message=message;
+        }
+
+        public int getCode()
+        {
+            return _code;
+        }
+
+        public String getMessage()
+        {
+            return _message;
+        }
+
+
+        public boolean equals(int code)
+        {
+            return (this._code == code);
+        }
+
+        @Override
+        public String toString()
+        {
+            return String.format("[%03d %s]",this._code,this.getMessage());
+        }
+
+        /**
+         * Simple test against an code to determine if it falls into the
+         * <code>Informational</code> message category as defined in the <a
+         * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
+         * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
+         * HTTP/1.1</a>.
+         *
+         * @return true if within range of codes that belongs to
+         *         <code>Informational</code> messages.
+         */
+        public boolean isInformational()
+        {
+            return HttpStatus.isInformational(this._code);
+        }
+
+        /**
+         * Simple test against an code to determine if it falls into the
+         * <code>Success</code> message category as defined in the <a
+         * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
+         * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
+         * HTTP/1.1</a>.
+         *
+         * @return true if within range of codes that belongs to
+         *         <code>Success</code> messages.
+         */
+        public boolean isSuccess()
+        {
+            return HttpStatus.isSuccess(this._code);
+        }
+
+        /**
+         * Simple test against an code to determine if it falls into the
+         * <code>Redirection</code> message category as defined in the <a
+         * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
+         * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
+         * HTTP/1.1</a>.
+         *
+         * @return true if within range of codes that belongs to
+         *         <code>Redirection</code> messages.
+         */
+        public boolean isRedirection()
+        {
+            return HttpStatus.isRedirection(this._code);
+        }
+
+        /**
+         * Simple test against an code to determine if it falls into the
+         * <code>Client Error</code> message category as defined in the <a
+         * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
+         * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
+         * HTTP/1.1</a>.
+         *
+         * @return true if within range of codes that belongs to
+         *         <code>Client Error</code> messages.
+         */
+        public boolean isClientError()
+        {
+            return HttpStatus.isClientError(this._code);
+        }
+
+        /**
+         * Simple test against an code to determine if it falls into the
+         * <code>Server Error</code> message category as defined in the <a
+         * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>,
+         * and <a href="http://tools.ietf.org/html/rfc2616">RFC 2616 -
+         * HTTP/1.1</a>.
+         *
+         * @return true if within range of codes that belongs to
+         *         <code>Server Error</code> messages.
+         */
+        public boolean isServerError()
+        {
+            return HttpStatus.isServerError(this._code);
+        }
+    }
+
+
+    /**
+     * Get the HttpStatusCode for a specific code
+     *
+     * @param code
+     *            the code to lookup.
+     * @return the {@link HttpStatus} if found, or null if not found.
+     */
+    public static Code getCode(int code)
+    {
+        if (code <= MAX_CODE)
+        {
+            return codeMap[code];
+        }
+        return null;
+    }
+
+    /**
+     * Get the status message for a specific code.
+     *
+     * @param code
+     *            the code to look up
+     * @return the specific message, or the code number itself if code
+     *         does not match known list.
+     */
+    public static String getMessage(int code)
+    {
+        Code codeEnum = getCode(code);
+        if (codeEnum != null)
+        {
+            return codeEnum.getMessage();
+        }
+        else
+        {
+            return Integer.toString(code);
+        }
+    }
+
+    /**
+     * Simple test against an code to determine if it falls into the
+     * <code>Informational</code> message category as defined in the <a
+     * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
+     * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
+     *
+     * @param code
+     *            the code to test.
+     * @return true if within range of codes that belongs to
+     *         <code>Informational</code> messages.
+     */
+    public static boolean isInformational(int code)
+    {
+        return ((100 <= code) && (code <= 199));
+    }
+
+    /**
+     * Simple test against an code to determine if it falls into the
+     * <code>Success</code> message category as defined in the <a
+     * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
+     * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
+     *
+     * @param code
+     *            the code to test.
+     * @return true if within range of codes that belongs to
+     *         <code>Success</code> messages.
+     */
+    public static boolean isSuccess(int code)
+    {
+        return ((200 <= code) && (code <= 299));
+    }
+
+    /**
+     * Simple test against an code to determine if it falls into the
+     * <code>Redirection</code> message category as defined in the <a
+     * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
+     * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
+     *
+     * @param code
+     *            the code to test.
+     * @return true if within range of codes that belongs to
+     *         <code>Redirection</code> messages.
+     */
+    public static boolean isRedirection(int code)
+    {
+        return ((300 <= code) && (code <= 399));
+    }
+
+    /**
+     * Simple test against an code to determine if it falls into the
+     * <code>Client Error</code> message category as defined in the <a
+     * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
+     * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
+     *
+     * @param code
+     *            the code to test.
+     * @return true if within range of codes that belongs to
+     *         <code>Client Error</code> messages.
+     */
+    public static boolean isClientError(int code)
+    {
+        return ((400 <= code) && (code <= 499));
+    }
+
+    /**
+     * Simple test against an code to determine if it falls into the
+     * <code>Server Error</code> message category as defined in the <a
+     * href="http://tools.ietf.org/html/rfc1945">RFC 1945 - HTTP/1.0</a>, and <a
+     * href="http://tools.ietf.org/html/rfc2616">RFC 2616 - HTTP/1.1</a>.
+     *
+     * @param code
+     *            the code to test.
+     * @return true if within range of codes that belongs to
+     *         <code>Server Error</code> messages.
+     */
+    public static boolean isServerError(int code)
+    {
+        return ((500 <= code) && (code <= 599));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpTokens.java b/src/java/org/eclipse/jetty/http/HttpTokens.java
new file mode 100644
index 0000000..fce759c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpTokens.java
@@ -0,0 +1,42 @@
+//
+//  ========================================================================
+//  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.http;
+
+/**
+ * HTTP constants
+ */
+public interface HttpTokens
+{
+    // Terminal symbols.
+    static final byte COLON= (byte)':';
+    static final byte SPACE= 0x20;
+    static final byte CARRIAGE_RETURN= 0x0D;
+    static final byte LINE_FEED= 0x0A;
+    static final byte[] CRLF = {CARRIAGE_RETURN,LINE_FEED};
+    static final byte SEMI_COLON= (byte)';';
+    static final byte TAB= 0x09;
+
+    public static final int SELF_DEFINING_CONTENT= -4;
+    public static final int UNKNOWN_CONTENT= -3;
+    public static final int CHUNKED_CONTENT= -2;
+    public static final int EOF_CONTENT= -1;
+    public static final int NO_CONTENT= 0;
+
+    
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpURI.java b/src/java/org/eclipse/jetty/http/HttpURI.java
new file mode 100644
index 0000000..56cb82c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpURI.java
@@ -0,0 +1,771 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.eclipse.jetty.util.Utf8StringBuilder;
+
+
+/* ------------------------------------------------------------ */
+/** Http URI.
+ * Parse a HTTP URI from a string or byte array.  Given a URI
+ * <code>http://user@host:port/path/info;param?query#fragment</code>
+ * this class will split it into the following undecoded optional elements:<ul>
+ * <li>{@link #getScheme()} - http:</li>
+ * <li>{@link #getAuthority()} - //name@host:port</li>
+ * <li>{@link #getHost()} - host</li>
+ * <li>{@link #getPort()} - port</li>
+ * <li>{@link #getPath()} - /path/info</li>
+ * <li>{@link #getParam()} - param</li>
+ * <li>{@link #getQuery()} - query</li>
+ * <li>{@link #getFragment()} - fragment</li>
+ * </ul>
+ *
+ */
+public class HttpURI
+{
+    private static final byte[] __empty={};
+    private final static int
+    START=0,
+    AUTH_OR_PATH=1,
+    SCHEME_OR_PATH=2,
+    AUTH=4,
+    IPV6=5,
+    PORT=6,
+    PATH=7,
+    PARAM=8,
+    QUERY=9,
+    ASTERISK=10;
+
+    boolean _partial=false;
+    byte[] _raw=__empty;
+    String _rawString;
+    int _scheme;
+    int _authority;
+    int _host;
+    int _port;
+    int _portValue;
+    int _path;
+    int _param;
+    int _query;
+    int _fragment;
+    int _end;
+    boolean _encoded=false;
+
+    final Utf8StringBuilder _utf8b = new Utf8StringBuilder(64);
+
+    public HttpURI()
+    {
+
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param parsePartialAuth If True, parse auth without prior scheme, else treat all URIs starting with / as paths
+     */
+    public HttpURI(boolean parsePartialAuth)
+    {
+        _partial=parsePartialAuth;
+    }
+
+    public HttpURI(String raw)
+    {
+        _rawString=raw;
+        byte[] b;
+        try
+        {
+            b = raw.getBytes(StringUtil.__UTF8);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+           throw new RuntimeException(e.getMessage());
+        }
+        parse(b,0,b.length);
+    }
+
+    public HttpURI(byte[] raw,int offset, int length)
+    {
+        parse2(raw,offset,length);
+    }
+    
+    public HttpURI(URI uri)
+    {
+        parse(uri.toASCIIString());
+    }
+
+    public void parse(String raw)
+    {
+        byte[] b = raw.getBytes();
+        parse2(b,0,b.length);
+        _rawString=raw;
+    }
+
+    public void parse(byte[] raw,int offset, int length)
+    {
+        _rawString=null;
+        parse2(raw,offset,length);
+    }
+
+
+    public void parseConnect(byte[] raw,int offset, int length)
+    {
+        _rawString=null;
+        _encoded=false;
+        _raw=raw;
+        int i=offset;
+        int e=offset+length;
+        int state=AUTH;
+        _end=offset+length;
+        _scheme=offset;
+        _authority=offset;
+        _host=offset;
+        _port=_end;
+        _portValue=-1;
+        _path=_end;
+        _param=_end;
+        _query=_end;
+        _fragment=_end;
+
+        loop: while (i<e)
+        {
+            char c=(char)(0xff&_raw[i]);
+            int s=i++;
+
+            switch (state)
+            {
+                case AUTH:
+                {
+                    switch (c)
+                    {
+                        case ':':
+                        {
+                            _port = s;
+                            break loop;
+                        }
+                        case '[':
+                        {
+                            state = IPV6;
+                            break;
+                        }
+                    }
+                    continue;
+                }
+
+                case IPV6:
+                {
+                    switch (c)
+                    {
+                        case '/':
+                        {
+                            throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
+                        }
+                        case ']':
+                        {
+                            state = AUTH;
+                            break;
+                        }
+                    }
+
+                    continue;
+                }
+            }
+        }
+
+        if (_port<_path)
+            _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
+        else
+            throw new IllegalArgumentException("No port");
+        _path=offset;
+    }
+
+
+    private void parse2(byte[] raw,int offset, int length)
+    {
+        _encoded=false;
+        _raw=raw;
+        int i=offset;
+        int e=offset+length;
+        int state=START;
+        int m=offset;
+        _end=offset+length;
+        _scheme=offset;
+        _authority=offset;
+        _host=offset;
+        _port=offset;
+        _portValue=-1;
+        _path=offset;
+        _param=_end;
+        _query=_end;
+        _fragment=_end;
+        while (i<e)
+        {
+            char c=(char)(0xff&_raw[i]);
+            int s=i++;
+
+            state: switch (state)
+            {
+                case START:
+                {
+                    m=s;
+                    switch(c)
+                    {
+                        case '/':
+                            state=AUTH_OR_PATH;
+                            break;
+                        case ';':
+                            _param=s;
+                            state=PARAM;
+                            break;
+                        case '?':
+                            _param=s;
+                            _query=s;
+                            state=QUERY;
+                            break;
+                        case '#':
+                            _param=s;
+                            _query=s;
+                            _fragment=s;
+                            break;
+                        case '*':
+                            _path=s;
+                            state=ASTERISK;
+                            break;
+
+                        default:
+                            state=SCHEME_OR_PATH;
+                    }
+
+                    continue;
+                }
+
+                case AUTH_OR_PATH:
+                {
+                    if ((_partial||_scheme!=_authority) && c=='/')
+                    {
+                        _host=i;
+                        _port=_end;
+                        _path=_end;
+                        state=AUTH;
+                    }
+                    else if (c==';' || c=='?' || c=='#')
+                    {
+                        i--;
+                        state=PATH;
+                    }
+                    else
+                    {
+                        _host=m;
+                        _port=m;
+                        state=PATH;
+                    }
+                    continue;
+                }
+
+                case SCHEME_OR_PATH:
+                {
+                    // short cut for http and https
+                    if (length>6 && c=='t')
+                    {
+                        if (_raw[offset+3]==':')
+                        {
+                            s=offset+3;
+                            i=offset+4;
+                            c=':';
+                        }
+                        else if (_raw[offset+4]==':')
+                        {
+                            s=offset+4;
+                            i=offset+5;
+                            c=':';
+                        }
+                        else if (_raw[offset+5]==':')
+                        {
+                            s=offset+5;
+                            i=offset+6;
+                            c=':';
+                        }
+                    }
+
+                    switch (c)
+                    {
+                        case ':':
+                        {
+                            m = i++;
+                            _authority = m;
+                            _path = m;
+                            c = (char)(0xff & _raw[i]);
+                            if (c == '/')
+                                state = AUTH_OR_PATH;
+                            else
+                            {
+                                _host = m;
+                                _port = m;
+                                state = PATH;
+                            }
+                            break;
+                        }
+
+                        case '/':
+                        {
+                            state = PATH;
+                            break;
+                        }
+
+                        case ';':
+                        {
+                            _param = s;
+                            state = PARAM;
+                            break;
+                        }
+
+                        case '?':
+                        {
+                            _param = s;
+                            _query = s;
+                            state = QUERY;
+                            break;
+                        }
+
+                        case '#':
+                        {
+                            _param = s;
+                            _query = s;
+                            _fragment = s;
+                            break;
+                        }
+                    }
+                    continue;
+                }
+
+                case AUTH:
+                {
+                    switch (c)
+                    {
+
+                        case '/':
+                        {
+                            m = s;
+                            _path = m;
+                            _port = _path;
+                            state = PATH;
+                            break;
+                        }
+                        case '@':
+                        {
+                            _host = i;
+                            break;
+                        }
+                        case ':':
+                        {
+                            _port = s;
+                            state = PORT;
+                            break;
+                        }
+                        case '[':
+                        {
+                            state = IPV6;
+                            break;
+                        }
+                    }
+                    continue;
+                }
+
+                case IPV6:
+                {
+                    switch (c)
+                    {
+                        case '/':
+                        {
+                            throw new IllegalArgumentException("No closing ']' for " + StringUtil.toString(_raw,offset,length,URIUtil.__CHARSET));
+                        }
+                        case ']':
+                        {
+                            state = AUTH;
+                            break;
+                        }
+                    }
+
+                    continue;
+                }
+
+                case PORT:
+                {
+                    if (c=='/')
+                    {
+                        m=s;
+                        _path=m;
+                        if (_port<=_authority)
+                            _port=_path;
+                        state=PATH;
+                    }
+                    continue;
+                }
+
+                case PATH:
+                {
+                    switch (c)
+                    {
+                        case ';':
+                        {
+                            _param = s;
+                            state = PARAM;
+                            break;
+                        }
+                        case '?':
+                        {
+                            _param = s;
+                            _query = s;
+                            state = QUERY;
+                            break;
+                        }
+                        case '#':
+                        {
+                            _param = s;
+                            _query = s;
+                            _fragment = s;
+                            break state;
+                        }
+                        case '%':
+                        {
+                            _encoded=true;
+                        }
+                    }
+                    continue;
+                }
+
+                case PARAM:
+                {
+                    switch (c)
+                    {
+                        case '?':
+                        {
+                            _query = s;
+                            state = QUERY;
+                            break;
+                        }
+                        case '#':
+                        {
+                            _query = s;
+                            _fragment = s;
+                            break state;
+                        }
+                    }
+                    continue;
+                }
+
+                case QUERY:
+                {
+                    if (c=='#')
+                    {
+                        _fragment=s;
+                        break state;
+                    }
+                    continue;
+                }
+
+                case ASTERISK:
+                {
+                    throw new IllegalArgumentException("only '*'");
+                }
+            }
+        }
+
+        if (_port<_path)
+            _portValue=TypeUtil.parseInt(_raw, _port+1, _path-_port-1,10);
+    }
+
+    private String toUtf8String(int offset,int length)
+    {
+        _utf8b.reset();
+        _utf8b.append(_raw,offset,length);
+        return _utf8b.toString();
+    }
+
+    public String getScheme()
+    {
+        if (_scheme==_authority)
+            return null;
+        int l=_authority-_scheme;
+        if (l==5 &&
+            _raw[_scheme]=='h' &&
+            _raw[_scheme+1]=='t' &&
+            _raw[_scheme+2]=='t' &&
+            _raw[_scheme+3]=='p' )
+            return HttpSchemes.HTTP;
+        if (l==6 &&
+            _raw[_scheme]=='h' &&
+            _raw[_scheme+1]=='t' &&
+            _raw[_scheme+2]=='t' &&
+            _raw[_scheme+3]=='p' &&
+            _raw[_scheme+4]=='s' )
+            return HttpSchemes.HTTPS;
+
+        return toUtf8String(_scheme,_authority-_scheme-1);
+    }
+
+    public String getAuthority()
+    {
+        if (_authority==_path)
+            return null;
+        return toUtf8String(_authority,_path-_authority);
+    }
+
+    public String getHost()
+    {
+        if (_host==_port)
+            return null;
+        return toUtf8String(_host,_port-_host);
+    }
+
+    public int getPort()
+    {
+        return _portValue;
+    }
+
+    public String getPath()
+    {
+        if (_path==_param)
+            return null;
+        return toUtf8String(_path,_param-_path);
+    }
+
+    public String getDecodedPath()
+    {
+        if (_path==_param)
+            return null;
+
+        int length = _param-_path;
+        boolean decoding=false;
+
+        for (int i=_path;i<_param;i++)
+        {
+            byte b = _raw[i];
+
+            if (b=='%')
+            {
+                if (!decoding)
+                {
+                    _utf8b.reset();
+                    _utf8b.append(_raw,_path,i-_path);
+                    decoding=true;
+                }
+                
+                if ((i+2)>=_param)
+                    throw new IllegalArgumentException("Bad % encoding: "+this);
+                if (_raw[i+1]=='u')
+                {
+                    if ((i+5)>=_param)
+                        throw new IllegalArgumentException("Bad %u encoding: "+this);
+                    try
+                    {
+                        String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16)));
+                        _utf8b.getStringBuilder().append(unicode);
+                        i+=5;
+                    }
+                    catch(Exception e)
+                    {
+                        throw new RuntimeException(e);
+                    }
+                }
+                else
+                {
+                    b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16));
+                    _utf8b.append(b);
+                    i+=2;
+                }
+                continue;
+            }
+            else if (decoding)
+            {
+                _utf8b.append(b);
+            }
+        }
+
+        if (!decoding)
+            return toUtf8String(_path,length);
+        return _utf8b.toString();
+    }
+    
+    public String getDecodedPath(String encoding)
+    {
+        if (_path==_param)
+            return null;
+
+        int length = _param-_path;
+        byte[] bytes=null;
+        int n=0;
+
+        for (int i=_path;i<_param;i++)
+        {
+            byte b = _raw[i];
+
+            if (b=='%')
+            {
+                if (bytes==null)
+                {
+                    bytes=new byte[length];
+                    System.arraycopy(_raw,_path,bytes,0,n);
+                }
+                
+                if ((i+2)>=_param)
+                    throw new IllegalArgumentException("Bad % encoding: "+this);
+                if (_raw[i+1]=='u')
+                {
+                    if ((i+5)>=_param)
+                        throw new IllegalArgumentException("Bad %u encoding: "+this);
+
+                    try
+                    {
+                        String unicode = new String(Character.toChars(TypeUtil.parseInt(_raw,i+2,4,16)));
+                        byte[] encoded = unicode.getBytes(encoding);
+                        System.arraycopy(encoded,0,bytes,n,encoded.length);
+                        n+=encoded.length;
+                        i+=5;
+                    }
+                    catch(Exception e)
+                    {
+                        throw new RuntimeException(e);
+                    }
+                }
+                else
+                {
+                    b=(byte)(0xff&TypeUtil.parseInt(_raw,i+1,2,16));
+                    bytes[n++]=b;
+                    i+=2;
+                }
+                continue;
+            }
+            else if (bytes==null)
+            {
+                n++;
+                continue;
+            }
+
+            bytes[n++]=b;
+        }
+
+
+        if (bytes==null)
+            return StringUtil.toString(_raw,_path,_param-_path,encoding);
+
+        return StringUtil.toString(bytes,0,n,encoding);
+    }
+    
+    
+    
+    
+    
+
+
+    public String getPathAndParam()
+    {
+        if (_path==_query)
+            return null;
+        return toUtf8String(_path,_query-_path);
+    }
+
+    public String getCompletePath()
+    {
+        if (_path==_end)
+            return null;
+        return toUtf8String(_path,_end-_path);
+    }
+
+    public String getParam()
+    {
+        if (_param==_query)
+            return null;
+        return toUtf8String(_param+1,_query-_param-1);
+    }
+
+    public String getQuery()
+    {
+        if (_query==_fragment)
+            return null;
+        return toUtf8String(_query+1,_fragment-_query-1);
+    }
+
+    public String getQuery(String encoding)
+    {
+        if (_query==_fragment)
+            return null;
+        return StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding);
+    }
+
+    public boolean hasQuery()
+    {
+        return (_fragment>_query);
+    }
+
+    public String getFragment()
+    {
+        if (_fragment==_end)
+            return null;
+        return toUtf8String(_fragment+1,_end-_fragment-1);
+    }
+
+    public void decodeQueryTo(MultiMap parameters)
+    {
+        if (_query==_fragment)
+            return;
+        _utf8b.reset();
+        UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
+    }
+
+    public void decodeQueryTo(MultiMap parameters, String encoding)
+        throws UnsupportedEncodingException
+    {
+        if (_query==_fragment)
+            return;
+
+        if (encoding==null || StringUtil.isUTF8(encoding))
+            UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters);
+        else
+            UrlEncoded.decodeTo(StringUtil.toString(_raw,_query+1,_fragment-_query-1,encoding),parameters,encoding);
+    }
+
+    public void clear()
+    {
+        _scheme=_authority=_host=_port=_path=_param=_query=_fragment=_end=0;
+        _raw=__empty;
+        _rawString="";
+        _encoded=false;
+    }
+
+    @Override
+    public String toString()
+    {
+        if (_rawString==null)
+            _rawString=toUtf8String(_scheme,_end-_scheme);
+        return _rawString;
+    }
+
+    public void writeTo(Utf8StringBuilder buf)
+    {
+        buf.append(_raw,_scheme,_end-_scheme);
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/http/HttpVersions.java b/src/java/org/eclipse/jetty/http/HttpVersions.java
new file mode 100644
index 0000000..147a1a0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/HttpVersions.java
@@ -0,0 +1,47 @@
+//
+//  ========================================================================
+//  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.http;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * 
+ * 
+ */
+public class HttpVersions
+{
+	public final static String
+		HTTP_0_9 = "",
+		HTTP_1_0 = "HTTP/1.0",
+		HTTP_1_1 = "HTTP/1.1";
+		
+	public final static int
+		HTTP_0_9_ORDINAL=9,
+		HTTP_1_0_ORDINAL=10,
+		HTTP_1_1_ORDINAL=11;
+	
+	public final static BufferCache CACHE = new BufferCache();
+	
+    public final static Buffer 
+        HTTP_0_9_BUFFER=CACHE.add(HTTP_0_9,HTTP_0_9_ORDINAL),
+        HTTP_1_0_BUFFER=CACHE.add(HTTP_1_0,HTTP_1_0_ORDINAL),
+        HTTP_1_1_BUFFER=CACHE.add(HTTP_1_1,HTTP_1_1_ORDINAL);
+}
diff --git a/src/java/org/eclipse/jetty/http/MimeTypes.java b/src/java/org/eclipse/jetty/http/MimeTypes.java
new file mode 100644
index 0000000..7c13920
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/MimeTypes.java
@@ -0,0 +1,376 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** 
+ * 
+ */
+public class MimeTypes
+{
+    private static final Logger LOG = Log.getLogger(MimeTypes.class);
+
+    public final static String
+      FORM_ENCODED="application/x-www-form-urlencoded",
+      MESSAGE_HTTP="message/http",
+      MULTIPART_BYTERANGES="multipart/byteranges",
+      
+      TEXT_HTML="text/html",
+      TEXT_PLAIN="text/plain",
+      TEXT_XML="text/xml",
+      TEXT_JSON="text/json",
+      
+      TEXT_HTML_8859_1="text/html;charset=ISO-8859-1",
+      TEXT_PLAIN_8859_1="text/plain;charset=ISO-8859-1",
+      TEXT_XML_8859_1="text/xml;charset=ISO-8859-1",
+      
+      TEXT_HTML_UTF_8="text/html;charset=UTF-8",
+      TEXT_PLAIN_UTF_8="text/plain;charset=UTF-8",
+      TEXT_XML_UTF_8="text/xml;charset=UTF-8",
+      TEXT_JSON_UTF_8="text/json;charset=UTF-8";
+
+    private final static String
+      TEXT_HTML__8859_1="text/html; charset=ISO-8859-1",
+      TEXT_PLAIN__8859_1="text/plain; charset=ISO-8859-1",
+      TEXT_XML__8859_1="text/xml; charset=ISO-8859-1",
+      TEXT_HTML__UTF_8="text/html; charset=UTF-8",
+      TEXT_PLAIN__UTF_8="text/plain; charset=UTF-8",
+      TEXT_XML__UTF_8="text/xml; charset=UTF-8",
+      TEXT_JSON__UTF_8="text/json; charset=UTF-8";
+
+    private final static int
+	FORM_ENCODED_ORDINAL=1,
+    	MESSAGE_HTTP_ORDINAL=2,
+    	MULTIPART_BYTERANGES_ORDINAL=3,
+    	
+    	TEXT_HTML_ORDINAL=4,
+	TEXT_PLAIN_ORDINAL=5,
+	TEXT_XML_ORDINAL=6,
+        TEXT_JSON_ORDINAL=7,
+	
+        TEXT_HTML_8859_1_ORDINAL=8,
+        TEXT_PLAIN_8859_1_ORDINAL=9,
+        TEXT_XML_8859_1_ORDINAL=10,
+        
+        TEXT_HTML_UTF_8_ORDINAL=11,
+        TEXT_PLAIN_UTF_8_ORDINAL=12,
+        TEXT_XML_UTF_8_ORDINAL=13,
+        TEXT_JSON_UTF_8_ORDINAL=14;
+    
+    private static int __index=15;
+    
+    public final static BufferCache CACHE = new BufferCache(); 
+
+    public final static CachedBuffer
+    	FORM_ENCODED_BUFFER=CACHE.add(FORM_ENCODED,FORM_ENCODED_ORDINAL),
+    	MESSAGE_HTTP_BUFFER=CACHE.add(MESSAGE_HTTP, MESSAGE_HTTP_ORDINAL),
+    	MULTIPART_BYTERANGES_BUFFER=CACHE.add(MULTIPART_BYTERANGES,MULTIPART_BYTERANGES_ORDINAL),
+        
+        TEXT_HTML_BUFFER=CACHE.add(TEXT_HTML,TEXT_HTML_ORDINAL),
+        TEXT_PLAIN_BUFFER=CACHE.add(TEXT_PLAIN,TEXT_PLAIN_ORDINAL),
+        TEXT_XML_BUFFER=CACHE.add(TEXT_XML,TEXT_XML_ORDINAL),
+        TEXT_JSON_BUFFER=CACHE.add(TEXT_JSON,TEXT_JSON_ORDINAL),
+
+        TEXT_HTML_8859_1_BUFFER=CACHE.add(TEXT_HTML_8859_1,TEXT_HTML_8859_1_ORDINAL),
+        TEXT_PLAIN_8859_1_BUFFER=CACHE.add(TEXT_PLAIN_8859_1,TEXT_PLAIN_8859_1_ORDINAL),
+        TEXT_XML_8859_1_BUFFER=CACHE.add(TEXT_XML_8859_1,TEXT_XML_8859_1_ORDINAL),
+        
+        TEXT_HTML_UTF_8_BUFFER=CACHE.add(TEXT_HTML_UTF_8,TEXT_HTML_UTF_8_ORDINAL),
+        TEXT_PLAIN_UTF_8_BUFFER=CACHE.add(TEXT_PLAIN_UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
+        TEXT_XML_UTF_8_BUFFER=CACHE.add(TEXT_XML_UTF_8,TEXT_XML_UTF_8_ORDINAL),
+        TEXT_JSON_UTF_8_BUFFER=CACHE.add(TEXT_JSON_UTF_8,TEXT_JSON_UTF_8_ORDINAL),
+
+        TEXT_HTML__8859_1_BUFFER=CACHE.add(TEXT_HTML__8859_1,TEXT_HTML_8859_1_ORDINAL),
+        TEXT_PLAIN__8859_1_BUFFER=CACHE.add(TEXT_PLAIN__8859_1,TEXT_PLAIN_8859_1_ORDINAL),
+        TEXT_XML__8859_1_BUFFER=CACHE.add(TEXT_XML__8859_1,TEXT_XML_8859_1_ORDINAL),
+        
+        TEXT_HTML__UTF_8_BUFFER=CACHE.add(TEXT_HTML__UTF_8,TEXT_HTML_UTF_8_ORDINAL),
+        TEXT_PLAIN__UTF_8_BUFFER=CACHE.add(TEXT_PLAIN__UTF_8,TEXT_PLAIN_UTF_8_ORDINAL),
+        TEXT_XML__UTF_8_BUFFER=CACHE.add(TEXT_XML__UTF_8,TEXT_XML_UTF_8_ORDINAL),
+        TEXT_JSON__UTF_8_BUFFER=CACHE.add(TEXT_JSON__UTF_8,TEXT_JSON_UTF_8_ORDINAL);
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private final static Map __dftMimeMap = new HashMap();
+    private final static Map __encodings = new HashMap();
+    static
+    {
+        try
+        {
+            ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime");
+            Enumeration i = mime.getKeys();
+            while(i.hasMoreElements())
+            {
+                String ext = (String)i.nextElement();
+                String m = mime.getString(ext);
+                __dftMimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(m));
+            }
+        }
+        catch(MissingResourceException e)
+        {
+            LOG.warn(e.toString());
+            LOG.debug(e);
+        }
+
+        try
+        {
+            ResourceBundle encoding = ResourceBundle.getBundle("org/eclipse/jetty/http/encoding");
+            Enumeration i = encoding.getKeys();
+            while(i.hasMoreElements())
+            {
+                Buffer type = normalizeMimeType((String)i.nextElement());
+                __encodings.put(type,encoding.getString(type.toString()));
+            }
+        }
+        catch(MissingResourceException e)
+        {
+            LOG.warn(e.toString());
+            LOG.debug(e);
+        }
+
+        
+        TEXT_HTML_BUFFER.setAssociate("ISO-8859-1",TEXT_HTML_8859_1_BUFFER);
+        TEXT_HTML_BUFFER.setAssociate("ISO_8859_1",TEXT_HTML_8859_1_BUFFER);
+        TEXT_HTML_BUFFER.setAssociate("iso-8859-1",TEXT_HTML_8859_1_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("ISO-8859-1",TEXT_PLAIN_8859_1_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("ISO_8859_1",TEXT_PLAIN_8859_1_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("iso-8859-1",TEXT_PLAIN_8859_1_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("ISO-8859-1",TEXT_XML_8859_1_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("ISO_8859_1",TEXT_XML_8859_1_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("iso-8859-1",TEXT_XML_8859_1_BUFFER);
+
+        TEXT_HTML_BUFFER.setAssociate("UTF-8",TEXT_HTML_UTF_8_BUFFER);
+        TEXT_HTML_BUFFER.setAssociate("UTF8",TEXT_HTML_UTF_8_BUFFER);
+        TEXT_HTML_BUFFER.setAssociate("utf8",TEXT_HTML_UTF_8_BUFFER);
+        TEXT_HTML_BUFFER.setAssociate("utf-8",TEXT_HTML_UTF_8_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("UTF-8",TEXT_PLAIN_UTF_8_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("UTF8",TEXT_PLAIN_UTF_8_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("utf8",TEXT_PLAIN_UTF_8_BUFFER);
+        TEXT_PLAIN_BUFFER.setAssociate("utf-8",TEXT_PLAIN_UTF_8_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("UTF-8",TEXT_XML_UTF_8_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("UTF8",TEXT_XML_UTF_8_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("utf8",TEXT_XML_UTF_8_BUFFER);
+        TEXT_XML_BUFFER.setAssociate("utf-8",TEXT_XML_UTF_8_BUFFER);
+        TEXT_JSON_BUFFER.setAssociate("UTF-8",TEXT_JSON_UTF_8_BUFFER);
+        TEXT_JSON_BUFFER.setAssociate("UTF8",TEXT_JSON_UTF_8_BUFFER);
+        TEXT_JSON_BUFFER.setAssociate("utf8",TEXT_JSON_UTF_8_BUFFER);
+        TEXT_JSON_BUFFER.setAssociate("utf-8",TEXT_JSON_UTF_8_BUFFER);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private Map _mimeMap;
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     */
+    public MimeTypes()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized Map getMimeMap()
+    {
+        return _mimeMap;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param mimeMap A Map of file extension to mime-type.
+     */
+    public void setMimeMap(Map mimeMap)
+    {
+        if (mimeMap==null)
+        {
+            _mimeMap=null;
+            return;
+        }
+        
+        Map m=new HashMap();
+        Iterator i=mimeMap.entrySet().iterator();
+        while (i.hasNext())
+        {
+            Map.Entry entry = (Map.Entry)i.next();
+            m.put(entry.getKey(),normalizeMimeType(entry.getValue().toString()));
+        }
+        _mimeMap=m;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the MIME type by filename extension.
+     * @param filename A file name
+     * @return MIME type matching the longest dot extension of the
+     * file name.
+     */
+    public Buffer getMimeByExtension(String filename)
+    {
+        Buffer type=null;
+
+        if (filename!=null)
+        {
+            int i=-1;
+            while(type==null)
+            {
+                i=filename.indexOf(".",i+1);
+
+                if (i<0 || i>=filename.length())
+                    break;
+
+                String ext=StringUtil.asciiToLowerCase(filename.substring(i+1));
+                if (_mimeMap!=null)
+                    type = (Buffer)_mimeMap.get(ext);
+                if (type==null)
+                    type=(Buffer)__dftMimeMap.get(ext);
+            }
+        }
+
+        if (type==null)
+        {
+            if (_mimeMap!=null)
+                type=(Buffer)_mimeMap.get("*");
+             if (type==null)
+                 type=(Buffer)__dftMimeMap.get("*");
+        }
+
+        return type;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set a mime mapping
+     * @param extension
+     * @param type
+     */
+    public void addMimeMapping(String extension,String type)
+    {
+        if (_mimeMap==null)
+            _mimeMap=new HashMap();
+        
+        _mimeMap.put(StringUtil.asciiToLowerCase(extension),normalizeMimeType(type));
+    }
+
+    /* ------------------------------------------------------------ */
+    private static synchronized Buffer normalizeMimeType(String type)
+    {
+        Buffer b =CACHE.get(type);
+        if (b==null)
+            b=CACHE.add(type,__index++);
+        return b;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String getCharsetFromContentType(Buffer value)
+    {
+        if (value instanceof CachedBuffer)
+        {
+            switch(((CachedBuffer)value).getOrdinal())
+            {
+                case TEXT_HTML_8859_1_ORDINAL:
+                case TEXT_PLAIN_8859_1_ORDINAL:
+                case TEXT_XML_8859_1_ORDINAL:
+                    return StringUtil.__ISO_8859_1;
+
+                case TEXT_HTML_UTF_8_ORDINAL:
+                case TEXT_PLAIN_UTF_8_ORDINAL:
+                case TEXT_XML_UTF_8_ORDINAL:
+                case TEXT_JSON_UTF_8_ORDINAL:
+                    return StringUtil.__UTF8;
+            }
+        }
+        
+        int i=value.getIndex();
+        int end=value.putIndex();
+        int state=0;
+        int start=0;
+        boolean quote=false;
+        for (;i<end;i++)
+        {
+            byte b = value.peek(i);
+            
+            if (quote && state!=10)
+            {
+                if ('"'==b)
+                    quote=false;
+                continue;
+            }
+                
+            switch(state)
+            {
+                case 0:
+                    if ('"'==b)
+                    {
+                        quote=true;
+                        break;
+                    }
+                    if (';'==b)
+                        state=1;
+                    break;
+
+                case 1: if ('c'==b) state=2; else if (' '!=b) state=0; break;
+                case 2: if ('h'==b) state=3; else state=0;break;
+                case 3: if ('a'==b) state=4; else state=0;break;
+                case 4: if ('r'==b) state=5; else state=0;break;
+                case 5: if ('s'==b) state=6; else state=0;break;
+                case 6: if ('e'==b) state=7; else state=0;break;
+                case 7: if ('t'==b) state=8; else state=0;break;
+
+                case 8: if ('='==b) state=9; else if (' '!=b) state=0; break;
+                
+                case 9: 
+                    if (' '==b) 
+                        break;
+                    if ('"'==b) 
+                    {
+                        quote=true;
+                        start=i+1;
+                        state=10;
+                        break;
+                    }
+                    start=i;
+                    state=10;
+                    break;
+                    
+                case 10:
+                    if (!quote && (';'==b || ' '==b )||
+                        (quote && '"'==b ))
+                        return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
+            }
+        }    
+        
+        if (state==10)
+            return CACHE.lookup(value.peek(start,i-start)).toString(StringUtil.__UTF8);
+        
+        return (String)__encodings.get(value);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/Parser.java b/src/java/org/eclipse/jetty/http/Parser.java
new file mode 100644
index 0000000..0a045c3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/Parser.java
@@ -0,0 +1,47 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.IOException;
+
+/**
+ * Abstract interface for a connection Parser for use by Jetty.
+ */
+public interface Parser
+{
+    void returnBuffers();
+    void reset();
+
+    boolean isComplete();
+
+    /**
+     * @return True if progress made
+     * @throws IOException
+     */
+    boolean parseAvailable() throws IOException;
+
+    boolean isMoreInBuffer() throws IOException;
+
+    boolean isIdle();
+    
+    boolean isPersistent();
+    
+    void setPersistent(boolean persistent);
+
+}
diff --git a/src/java/org/eclipse/jetty/http/PathMap.java b/src/java/org/eclipse/jetty/http/PathMap.java
new file mode 100644
index 0000000..140bb16
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/PathMap.java
@@ -0,0 +1,589 @@
+//
+//  ========================================================================
+//  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.http;
+
+import java.io.Externalizable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.StringMap;
+import org.eclipse.jetty.util.URIUtil;
+
+/* ------------------------------------------------------------ */
+/** URI path map to Object.
+ * This mapping implements the path specification recommended
+ * in the 2.2 Servlet API.
+ *
+ * Path specifications can be of the following forms:<PRE>
+ * /foo/bar           - an exact path specification.
+ * /foo/*             - a prefix path specification (must end '/*').
+ * *.ext              - a suffix path specification.
+ * /                  - the default path specification.
+ * </PRE>
+ * Matching is performed in the following order <NL>
+ * <LI>Exact match.
+ * <LI>Longest prefix match.
+ * <LI>Longest suffix match.
+ * <LI>default.
+ * </NL>
+ * Multiple path specifications can be mapped by providing a list of
+ * specifications. By default this class uses characters ":," as path
+ * separators, unless configured differently by calling the static
+ * method @see PathMap#setPathSpecSeparators(String)
+ * <P>
+ * Special characters within paths such as '?� and ';' are not treated specially
+ * as it is assumed they would have been either encoded in the original URL or
+ * stripped from the path.
+ * <P>
+ * This class is not synchronized.  If concurrent modifications are
+ * possible then it should be synchronized at a higher level.
+ *
+ *
+ */
+public class PathMap extends HashMap implements Externalizable
+{
+    /* ------------------------------------------------------------ */
+    private static String __pathSpecSeparators = ":,";
+
+    /* ------------------------------------------------------------ */
+    /** Set the path spec separator.
+     * Multiple path specification may be included in a single string
+     * if they are separated by the characters set in this string.
+     * By default this class uses ":," characters as path separators.
+     * @param s separators
+     */
+    public static void setPathSpecSeparators(String s)
+    {
+        __pathSpecSeparators=s;
+    }
+
+    /* --------------------------------------------------------------- */
+    final StringMap _prefixMap=new StringMap();
+    final StringMap _suffixMap=new StringMap();
+    final StringMap _exactMap=new StringMap();
+
+    List _defaultSingletonList=null;
+    Entry _prefixDefault=null;
+    Entry _default=null;
+    final Set _entrySet;
+    boolean _nodefault=false;
+
+    /* --------------------------------------------------------------- */
+    /** Construct empty PathMap.
+     */
+    public PathMap()
+    {
+        super(11);
+        _entrySet=entrySet();
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Construct empty PathMap.
+     */
+    public PathMap(boolean nodefault)
+    {
+        super(11);
+        _entrySet=entrySet();
+        _nodefault=nodefault;
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Construct empty PathMap.
+     */
+    public PathMap(int capacity)
+    {
+        super (capacity);
+        _entrySet=entrySet();
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Construct from dictionary PathMap.
+     */
+    public PathMap(Map m)
+    {
+        putAll(m);
+        _entrySet=entrySet();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void writeExternal(java.io.ObjectOutput out)
+        throws java.io.IOException
+    {
+        HashMap map = new HashMap(this);
+        out.writeObject(map);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void readExternal(java.io.ObjectInput in)
+        throws java.io.IOException, ClassNotFoundException
+    {
+        HashMap map = (HashMap)in.readObject();
+        this.putAll(map);
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Add a single path match to the PathMap.
+     * @param pathSpec The path specification, or comma separated list of
+     * path specifications.
+     * @param object The object the path maps to
+     */
+    @Override
+    public Object put(Object pathSpec, Object object)
+    {
+        String str = pathSpec.toString();
+        if ("".equals(str.trim()))
+        {          
+            Entry entry = new Entry("",object);
+            entry.setMapped("");
+            _exactMap.put("", entry);
+            return super.put("", object);
+        }
+        
+        StringTokenizer tok = new StringTokenizer(str,__pathSpecSeparators);
+        Object old =null;
+
+        while (tok.hasMoreTokens())
+        {
+            String spec=tok.nextToken();
+
+            if (!spec.startsWith("/") && !spec.startsWith("*."))
+                throw new IllegalArgumentException("PathSpec "+spec+". must start with '/' or '*.'");
+
+            old = super.put(spec,object);
+
+            // Make entry that was just created.
+            Entry entry = new Entry(spec,object);
+
+            if (entry.getKey().equals(spec))
+            {
+                if (spec.equals("/*"))
+                    _prefixDefault=entry;
+                else if (spec.endsWith("/*"))
+                {
+                    String mapped=spec.substring(0,spec.length()-2);
+                    entry.setMapped(mapped);
+                    _prefixMap.put(mapped,entry);
+                    _exactMap.put(mapped,entry);
+                    _exactMap.put(spec.substring(0,spec.length()-1),entry);
+                }
+                else if (spec.startsWith("*."))
+                    _suffixMap.put(spec.substring(2),entry);
+                else if (spec.equals(URIUtil.SLASH))
+                {
+                    if (_nodefault)
+                        _exactMap.put(spec,entry);
+                    else
+                    {
+                        _default=entry;
+                        _defaultSingletonList=
+                            Collections.singletonList(_default);
+                    }
+                }
+                else
+                {
+                    entry.setMapped(spec);
+                    _exactMap.put(spec,entry);
+                }
+            }
+        }
+
+        return old;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get object matched by the path.
+     * @param path the path.
+     * @return Best matched object or null.
+     */
+    public Object match(String path)
+    {
+        Map.Entry entry = getMatch(path);
+        if (entry!=null)
+            return entry.getValue();
+        return null;
+    }
+
+
+    /* --------------------------------------------------------------- */
+    /** Get the entry mapped by the best specification.
+     * @param path the path.
+     * @return Map.Entry of the best matched  or null.
+     */
+    public Entry getMatch(String path)
+    {
+        Map.Entry entry=null;
+
+        if (path==null)
+            return null;
+
+        int l=path.length();
+        
+        //special case
+        if (l == 1 && path.charAt(0)=='/')
+        {
+            entry = (Map.Entry)_exactMap.get("");
+            if (entry != null)
+                return (Entry)entry;
+        }
+        
+        // try exact match
+        entry=_exactMap.getEntry(path,0,l);
+        if (entry!=null)
+            return (Entry) entry.getValue();
+
+        // prefix search
+        int i=l;
+        while((i=path.lastIndexOf('/',i-1))>=0)
+        {
+            entry=_prefixMap.getEntry(path,0,i);
+            if (entry!=null)
+                return (Entry) entry.getValue();
+        }
+
+        // Prefix Default
+        if (_prefixDefault!=null)
+            return _prefixDefault;
+
+        // Extension search
+        i=0;
+        while ((i=path.indexOf('.',i+1))>0)
+        {
+            entry=_suffixMap.getEntry(path,i+1,l-i-1);
+            if (entry!=null)
+                return (Entry) entry.getValue();
+        }
+
+        // Default
+        return _default;
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Get all entries matched by the path.
+     * Best match first.
+     * @param path Path to match
+     * @return LazyList of Map.Entry instances key=pathSpec
+     */
+    public Object getLazyMatches(String path)
+    {
+        Map.Entry entry;
+        Object entries=null;
+
+        if (path==null)
+            return LazyList.getList(entries);
+
+        int l=path.length();
+
+        // try exact match
+        entry=_exactMap.getEntry(path,0,l);
+        if (entry!=null)
+            entries=LazyList.add(entries,entry.getValue());
+
+        // prefix search
+        int i=l-1;
+        while((i=path.lastIndexOf('/',i-1))>=0)
+        {
+            entry=_prefixMap.getEntry(path,0,i);
+            if (entry!=null)
+                entries=LazyList.add(entries,entry.getValue());
+        }
+
+        // Prefix Default
+        if (_prefixDefault!=null)
+            entries=LazyList.add(entries,_prefixDefault);
+
+        // Extension search
+        i=0;
+        while ((i=path.indexOf('.',i+1))>0)
+        {
+            entry=_suffixMap.getEntry(path,i+1,l-i-1);
+            if (entry!=null)
+                entries=LazyList.add(entries,entry.getValue());
+        }
+
+        // Default
+        if (_default!=null)
+        {
+            // Optimization for just the default
+            if (entries==null)
+                return _defaultSingletonList;
+
+            entries=LazyList.add(entries,_default);
+        }
+
+        return entries;
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Get all entries matched by the path.
+     * Best match first.
+     * @param path Path to match
+     * @return List of Map.Entry instances key=pathSpec
+     */
+    public List getMatches(String path)
+    {
+        return LazyList.getList(getLazyMatches(path));
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Return whether the path matches any entries in the PathMap,
+     * excluding the default entry
+     * @param path Path to match
+     * @return Whether the PathMap contains any entries that match this
+     */
+    public boolean containsMatch(String path)
+    {
+    	Entry match = getMatch(path);
+    	return match!=null && !match.equals(_default);
+    }
+
+    /* --------------------------------------------------------------- */
+    @Override
+    public Object remove(Object pathSpec)
+    {
+        if (pathSpec!=null)
+        {
+            String spec=(String) pathSpec;
+            if (spec.equals("/*"))
+                _prefixDefault=null;
+            else if (spec.endsWith("/*"))
+            {
+                _prefixMap.remove(spec.substring(0,spec.length()-2));
+                _exactMap.remove(spec.substring(0,spec.length()-1));
+                _exactMap.remove(spec.substring(0,spec.length()-2));
+            }
+            else if (spec.startsWith("*."))
+                _suffixMap.remove(spec.substring(2));
+            else if (spec.equals(URIUtil.SLASH))
+            {
+                _default=null;
+                _defaultSingletonList=null;
+            }
+            else
+                _exactMap.remove(spec);
+        }
+        return super.remove(pathSpec);
+    }
+
+    /* --------------------------------------------------------------- */
+    @Override
+    public void clear()
+    {
+        _exactMap.clear();
+        _prefixMap.clear();
+        _suffixMap.clear();
+        _default=null;
+        _defaultSingletonList=null;
+        super.clear();
+    }
+
+    /* --------------------------------------------------------------- */
+    /**
+     * @return true if match.
+     */
+    public static boolean match(String pathSpec, String path)
+        throws IllegalArgumentException
+    {
+        return match(pathSpec, path, false);
+    }
+
+    /* --------------------------------------------------------------- */
+    /**
+     * @return true if match.
+     */
+    public static boolean match(String pathSpec, String path, boolean noDefault)
+    throws IllegalArgumentException
+    {
+        if (pathSpec.length()==0)
+            return "/".equals(path);
+            
+        char c = pathSpec.charAt(0);
+        if (c=='/')
+        {
+            if (!noDefault && pathSpec.length()==1 || pathSpec.equals(path))
+                return true;
+
+            if(isPathWildcardMatch(pathSpec, path))
+                return true;
+        }
+        else if (c=='*')
+            return path.regionMatches(path.length()-pathSpec.length()+1,
+                                      pathSpec,1,pathSpec.length()-1);
+        return false;
+    }
+
+    /* --------------------------------------------------------------- */
+    private static boolean isPathWildcardMatch(String pathSpec, String path)
+    {
+        // For a spec of "/foo/*" match "/foo" , "/foo/..." but not "/foobar"
+        int cpl=pathSpec.length()-2;
+        if (pathSpec.endsWith("/*") && path.regionMatches(0,pathSpec,0,cpl))
+        {
+            if (path.length()==cpl || '/'==path.charAt(cpl))
+                return true;
+        }
+        return false;
+    }
+
+
+    /* --------------------------------------------------------------- */
+    /** Return the portion of a path that matches a path spec.
+     * @return null if no match at all.
+     */
+    public static String pathMatch(String pathSpec, String path)
+    {
+        char c = pathSpec.charAt(0);
+
+        if (c=='/')
+        {
+            if (pathSpec.length()==1)
+                return path;
+
+            if (pathSpec.equals(path))
+                return path;
+
+            if (isPathWildcardMatch(pathSpec, path))
+                return path.substring(0,pathSpec.length()-2);
+        }
+        else if (c=='*')
+        {
+            if (path.regionMatches(path.length()-(pathSpec.length()-1),
+                                   pathSpec,1,pathSpec.length()-1))
+                return path;
+        }
+        return null;
+    }
+
+    /* --------------------------------------------------------------- */
+    /** Return the portion of a path that is after a path spec.
+     * @return The path info string
+     */
+    public static String pathInfo(String pathSpec, String path)
+    {
+        if ("".equals(pathSpec))
+            return path; //servlet 3 spec sec 12.2 will be '/'
+        
+        char c = pathSpec.charAt(0);
+
+        if (c=='/')
+        {
+            if (pathSpec.length()==1)
+                return null;
+
+            boolean wildcard = isPathWildcardMatch(pathSpec, path);
+
+            // handle the case where pathSpec uses a wildcard and path info is "/*"
+            if (pathSpec.equals(path) && !wildcard)
+                return null;
+
+            if (wildcard)
+            {
+                if (path.length()==pathSpec.length()-2)
+                    return null;
+                return path.substring(pathSpec.length()-2);
+            }
+        }
+        return null;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Relative path.
+     * @param base The base the path is relative to.
+     * @param pathSpec The spec of the path segment to ignore.
+     * @param path the additional path
+     * @return base plus path with pathspec removed
+     */
+    public static String relativePath(String base,
+                                      String pathSpec,
+                                      String path )
+    {
+        String info=pathInfo(pathSpec,path);
+        if (info==null)
+            info=path;
+
+        if( info.startsWith( "./"))
+            info = info.substring( 2);
+        if( base.endsWith( URIUtil.SLASH))
+            if( info.startsWith( URIUtil.SLASH))
+                path = base + info.substring(1);
+            else
+                path = base + info;
+        else
+            if( info.startsWith( URIUtil.SLASH))
+                path = base + info;
+            else
+                path = base + URIUtil.SLASH + info;
+        return path;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static class Entry implements Map.Entry
+    {
+        private final Object key;
+        private final Object value;
+        private String mapped;
+        private transient String string;
+
+        Entry(Object key, Object value)
+        {
+            this.key=key;
+            this.value=value;
+        }
+
+        public Object getKey()
+        {
+            return key;
+        }
+
+        public Object getValue()
+        {
+            return value;
+        }
+
+        public Object setValue(Object o)
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String toString()
+        {
+            if (string==null)
+                string=key+"="+value;
+            return string;
+        }
+
+        public String getMapped()
+        {
+            return mapped;
+        }
+
+        void setMapped(String mapped)
+        {
+            this.mapped = mapped;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java b/src/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java
new file mode 100644
index 0000000..29651c2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java
@@ -0,0 +1,388 @@
+//
+//  ========================================================================
+//  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.http.gzip;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.util.ByteArrayOutputStream2;
+
+/* ------------------------------------------------------------ */
+/**
+ * Skeletal implementation of a CompressedStream. This class adds compression features to a ServletOutputStream and takes care of setting response headers, etc.
+ * Major work and configuration is done here. Subclasses using different kinds of compression only have to implement the abstract methods doCompress() and
+ * setContentEncoding() using the desired compression and setting the appropriate Content-Encoding header string.
+ */
+public abstract class AbstractCompressedStream extends ServletOutputStream 
+{
+    private final String _encoding;
+    protected final String _vary;
+    protected final CompressedResponseWrapper _wrapper;
+    protected final HttpServletResponse _response;
+    protected OutputStream _out;
+    protected ByteArrayOutputStream2 _bOut;
+    protected DeflaterOutputStream _compressedOutputStream;
+    protected boolean _closed;
+    protected boolean _doNotCompress;
+
+    /**
+     * Instantiates a new compressed stream.
+     * 
+     */
+    public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper,String vary)
+            throws IOException
+    {
+        _encoding=encoding;
+        _wrapper = wrapper;
+        _response = (HttpServletResponse)wrapper.getResponse();
+        _vary=vary;
+        
+        if (_wrapper.getMinCompressSize()==0)
+            doCompress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Reset buffer.
+     */
+    public void resetBuffer()
+    {
+        if (_response.isCommitted() || _compressedOutputStream!=null )
+            throw new IllegalStateException("Committed");
+        _closed = false;
+        _out = null;
+        _bOut = null;
+        _doNotCompress = false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setBufferSize(int bufferSize)
+    {
+        if (_bOut!=null && _bOut.getBuf().length<bufferSize)
+        {
+            ByteArrayOutputStream2 b = new ByteArrayOutputStream2(bufferSize);
+            b.write(_bOut.getBuf(),0,_bOut.size());
+            _bOut=b;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setContentLength()
+    {
+        if (_doNotCompress)
+        {
+            long length=_wrapper.getContentLength();
+            if (length>=0)
+            {
+                if (length < Integer.MAX_VALUE)
+                    _response.setContentLength((int)length);
+                else
+                    _response.setHeader("Content-Length",Long.toString(length));
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.io.OutputStream#flush()
+     */
+    @Override
+    public void flush() throws IOException
+    {
+        if (_out == null || _bOut != null)
+        {
+            long length=_wrapper.getContentLength();
+            if (length > 0 && length < _wrapper.getMinCompressSize())
+                doNotCompress(false);
+            else
+                doCompress();
+        }
+
+        _out.flush();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.io.OutputStream#close()
+     */
+    @Override
+    public void close() throws IOException
+    {
+        if (_closed)
+            return;
+
+        if (_wrapper.getRequest().getAttribute("javax.servlet.include.request_uri") != null)
+            flush();
+        else
+        {
+            if (_bOut != null)
+            {
+                long length=_wrapper.getContentLength();
+                if (length < 0)
+                {
+                    length = _bOut.getCount();
+                    _wrapper.setContentLength(length);
+                }
+                if (length < _wrapper.getMinCompressSize())
+                    doNotCompress(false);
+                else
+                    doCompress();
+            }
+            else if (_out == null)
+            {
+                // No output
+                doNotCompress(false);
+            }
+
+            if (_compressedOutputStream != null)
+                _compressedOutputStream.close();
+            else
+                _out.close();
+            _closed = true;
+        }
+    }
+
+    /**
+     * Finish.
+     * 
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    public void finish() throws IOException
+    {
+        if (!_closed)
+        {
+            if (_out == null || _bOut != null)
+            {
+                long length=_wrapper.getContentLength();
+                if (length >= 0 && length < _wrapper.getMinCompressSize())
+                    doNotCompress(false);
+                else
+                    doCompress();
+            }
+
+            if (_compressedOutputStream != null && !_closed)
+            {
+                _closed = true;
+                _compressedOutputStream.close();
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.io.OutputStream#write(int)
+     */
+    @Override
+    public void write(int b) throws IOException
+    {
+        checkOut(1);
+        _out.write(b);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.io.OutputStream#write(byte[])
+     */
+    @Override
+    public void write(byte b[]) throws IOException
+    {
+        checkOut(b.length);
+        _out.write(b);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.io.OutputStream#write(byte[], int, int)
+     */
+    @Override
+    public void write(byte b[], int off, int len) throws IOException
+    {
+        checkOut(len);
+        _out.write(b,off,len);
+    }
+    
+    /**
+     * Do compress.
+     *
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void doCompress() throws IOException
+    {
+        if (_compressedOutputStream==null) 
+        {
+            if (_response.isCommitted())
+                throw new IllegalStateException();
+            
+            if (_encoding!=null)
+            {
+                setHeader("Content-Encoding", _encoding);            
+                if (_response.containsHeader("Content-Encoding"))
+                {
+                    addHeader("Vary",_vary);
+                    _out=_compressedOutputStream=createStream();
+                    if (_out!=null)
+                    {
+                        if (_bOut!=null)
+                        {
+                            _out.write(_bOut.getBuf(),0,_bOut.getCount());
+                            _bOut=null;
+                        }
+
+                        String etag=_wrapper.getETag();
+                        if (etag!=null)
+                            setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"');
+                        return;
+                    }
+                }
+            }
+            
+            doNotCompress(true); // Send vary as it could have been compressed if encoding was present
+        }
+    }
+
+    /**
+     * Do not compress.
+     * 
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    public void doNotCompress(boolean sendVary) throws IOException
+    {
+        if (_compressedOutputStream != null)
+            throw new IllegalStateException("Compressed output stream is already assigned.");
+        if (_out == null || _bOut != null)
+        {
+            if (sendVary)
+                addHeader("Vary",_vary);
+            if (_wrapper.getETag()!=null)
+                setHeader("ETag",_wrapper.getETag());
+                
+            _doNotCompress = true;
+
+            _out = _response.getOutputStream();
+            setContentLength();
+
+            if (_bOut != null)
+                _out.write(_bOut.getBuf(),0,_bOut.getCount());
+            _bOut = null;
+        }
+    }
+
+    /**
+     * Check out.
+     * 
+     * @param lengthToWrite
+     *            the length
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    private void checkOut(int lengthToWrite) throws IOException
+    {
+        if (_closed)
+            throw new IOException("CLOSED");
+
+        if (_out == null)
+        {            
+            // If this first write is larger than buffer size, then we are committing now
+            if (lengthToWrite>_wrapper.getBufferSize())
+            {
+                // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress
+                long length=_wrapper.getContentLength();
+                if (length>=0 && length<_wrapper.getMinCompressSize())
+                    doNotCompress(false);  // Not compressing by size, so no vary on request headers
+                else
+                    doCompress();
+            }
+            else
+            {
+                // start aggregating writes into a buffered output stream
+                _out = _bOut = new ByteArrayOutputStream2(_wrapper.getBufferSize());
+            }
+        }
+        // else are we aggregating writes?
+        else if (_bOut !=null)
+        {
+            // We are aggregating into the buffered output stream.  
+
+            // If this write fills the buffer, then we are committing
+            if (lengthToWrite>=(_bOut.getBuf().length - _bOut.getCount()))
+            {
+                // if we know this is all the content and it is less than minimum, then do not compress, otherwise do compress
+                long length=_wrapper.getContentLength();
+                if (length>=0 && length<_wrapper.getMinCompressSize())
+                    doNotCompress(false);  // Not compressing by size, so no vary on request headers
+                else
+                    doCompress();
+            }
+        }
+    }
+
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedStream#getOutputStream()
+     */
+    public OutputStream getOutputStream()
+    {
+        return _out;
+    }
+
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedStream#isClosed()
+     */
+    public boolean isClosed()
+    {
+        return _closed;
+    }
+    
+    /**
+     * Allows derived implementations to replace PrintWriter implementation.
+     */
+    protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
+    {
+        return encoding == null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+    }
+
+    protected void addHeader(String name,String value)
+    {
+        _response.addHeader(name, value);
+    }
+
+    protected void setHeader(String name,String value)
+    {
+        _response.setHeader(name, value);
+    }
+    
+    /**
+     * Create the stream fitting to the underlying compression type.
+     * 
+     * @throws IOException
+     *             Signals that an I/O exception has occurred.
+     */
+    protected abstract DeflaterOutputStream createStream() throws IOException;
+
+
+}
diff --git a/src/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java b/src/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java
new file mode 100644
index 0000000..790390c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java
@@ -0,0 +1,487 @@
+//
+//  ========================================================================
+//  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.http.gzip;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Set;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.eclipse.jetty.util.StringUtil;
+
+/*------------------------------------------------------------ */
+/**
+ */
+public abstract class CompressedResponseWrapper extends HttpServletResponseWrapper
+{
+    
+    public static final int DEFAULT_BUFFER_SIZE = 8192;
+    public static final int DEFAULT_MIN_COMPRESS_SIZE = 256;
+    
+    private Set<String> _mimeTypes;
+    private int _bufferSize=DEFAULT_BUFFER_SIZE;
+    private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE;
+    protected HttpServletRequest _request;
+
+    private PrintWriter _writer;
+    private AbstractCompressedStream _compressedStream;
+    private String _etag;
+    private long _contentLength=-1;
+    private boolean _noCompression;
+
+    /* ------------------------------------------------------------ */
+    public CompressedResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+    {
+        super(response);
+        _request = request;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public long getContentLength()
+    {
+        return _contentLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getBufferSize()
+    {
+        return _bufferSize;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int getMinCompressSize()
+    {
+        return _minCompressSize;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getETag()
+    {
+        return _etag;
+    }
+
+    /* ------------------------------------------------------------ */
+    public HttpServletRequest getRequest()
+    {
+        return _request;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set)
+     */
+    public void setMimeTypes(Set<String> mimeTypes)
+    {
+        _mimeTypes = mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setBufferSize(int)
+     */
+    @Override
+    public void setBufferSize(int bufferSize)
+    {
+        _bufferSize = bufferSize;
+        if (_compressedStream!=null)
+            _compressedStream.setBufferSize(bufferSize);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setMinCompressSize(int)
+     */
+    public void setMinCompressSize(int minCompressSize)
+    {
+        _minCompressSize = minCompressSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentType(java.lang.String)
+     */
+    @Override
+    public void setContentType(String ct)
+    {
+        super.setContentType(ct);
+    
+        if (!_noCompression)
+        {
+            if (ct!=null)
+            {
+                int colon=ct.indexOf(";");
+                if (colon>0)
+                    ct=ct.substring(0,colon);
+            }
+
+            if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && 
+                    (_mimeTypes==null && ct!=null && ct.contains("gzip") ||
+                    _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct)))))
+            {
+                noCompression();
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String)
+     */
+    @Override
+    public void setStatus(int sc, String sm)
+    {
+        super.setStatus(sc,sm);
+        if (sc<200 || sc==204 || sc==205 || sc>=300)
+            noCompression();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setStatus(int)
+     */
+    @Override
+    public void setStatus(int sc)
+    {
+        super.setStatus(sc);
+        if (sc<200 || sc==204 || sc==205 || sc>=300)
+            noCompression();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setContentLength(int)
+     */
+    @Override
+    public void setContentLength(int length)
+    {
+        if (_noCompression)
+            super.setContentLength(length);
+        else
+            setContentLength((long)length);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void setContentLength(long length)
+    {
+        _contentLength=length;
+        if (_compressedStream!=null)
+            _compressedStream.setContentLength();
+        else if (_noCompression && _contentLength>=0)
+        {
+            HttpServletResponse response = (HttpServletResponse)getResponse();
+            if(_contentLength<Integer.MAX_VALUE)
+            {
+                response.setContentLength((int)_contentLength);
+            }
+            else
+            {
+                response.setHeader("Content-Length", Long.toString(_contentLength));
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#addHeader(java.lang.String, java.lang.String)
+     */
+    @Override
+    public void addHeader(String name, String value)
+    {
+        if ("content-length".equalsIgnoreCase(name))
+        {
+            _contentLength=Long.parseLong(value);
+            if (_compressedStream!=null)
+                _compressedStream.setContentLength();
+        }
+        else if ("content-type".equalsIgnoreCase(name))
+        {   
+            setContentType(value);
+        }
+        else if ("content-encoding".equalsIgnoreCase(name))
+        {   
+            super.addHeader(name,value);
+            if (!isCommitted())
+            {
+                noCompression();
+            }
+        }
+        else if ("etag".equalsIgnoreCase(name))
+            _etag=value;
+        else
+            super.addHeader(name,value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#flushBuffer()
+     */
+    @Override
+    public void flushBuffer() throws IOException
+    {
+        if (_writer!=null)
+            _writer.flush();
+        if (_compressedStream!=null)
+            _compressedStream.flush();
+        else
+            getResponse().flushBuffer();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#reset()
+     */
+    @Override
+    public void reset()
+    {
+        super.reset();
+        if (_compressedStream!=null)
+            _compressedStream.resetBuffer();
+        _writer=null;
+        _compressedStream=null;
+        _noCompression=false;
+        _contentLength=-1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#resetBuffer()
+     */
+    @Override
+    public void resetBuffer()
+    {
+        super.resetBuffer();
+        if (_compressedStream!=null)
+            _compressedStream.resetBuffer();
+        _writer=null;
+        _compressedStream=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int, java.lang.String)
+     */
+    @Override
+    public void sendError(int sc, String msg) throws IOException
+    {
+        resetBuffer();
+        super.sendError(sc,msg);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendError(int)
+     */
+    @Override
+    public void sendError(int sc) throws IOException
+    {
+        resetBuffer();
+        super.sendError(sc);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#sendRedirect(java.lang.String)
+     */
+    @Override
+    public void sendRedirect(String location) throws IOException
+    {
+        resetBuffer();
+        super.sendRedirect(location);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#noCompression()
+     */
+    public void noCompression()
+    {
+        if (!_noCompression)
+            setDeferredHeaders();
+        _noCompression=true;
+        if (_compressedStream!=null)
+        {
+            try
+            {
+                _compressedStream.doNotCompress(false);
+            }
+            catch (IOException e)
+            {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#finish()
+     */
+    public void finish() throws IOException
+    {
+        if (_writer!=null && !_compressedStream.isClosed())
+            _writer.flush();
+        if (_compressedStream!=null)
+            _compressedStream.finish();
+        else 
+            setDeferredHeaders();
+    }
+
+    /* ------------------------------------------------------------ */
+    private void setDeferredHeaders()
+    {
+        if (!isCommitted())
+        {
+            if (_contentLength>=0)
+            {
+                if (_contentLength < Integer.MAX_VALUE)
+                    super.setContentLength((int)_contentLength);
+                else
+                    super.setHeader("Content-Length",Long.toString(_contentLength));
+            }
+            if(_etag!=null)
+                super.setHeader("ETag",_etag);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setHeader(java.lang.String, java.lang.String)
+     */
+    @Override
+    public void setHeader(String name, String value)
+    {
+        if (_noCompression)
+            super.setHeader(name,value);
+        else if ("content-length".equalsIgnoreCase(name))
+        {
+            setContentLength(Long.parseLong(value));
+        }
+        else if ("content-type".equalsIgnoreCase(name))
+        {   
+            setContentType(value);
+        }
+        else if ("content-encoding".equalsIgnoreCase(name))
+        {   
+            super.setHeader(name,value);
+            if (!isCommitted())
+            {
+                noCompression();
+            }
+        }
+        else if ("etag".equalsIgnoreCase(name))
+            _etag=value;
+        else
+            super.setHeader(name,value);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean containsHeader(String name)
+    {
+        if (!_noCompression && "etag".equalsIgnoreCase(name) && _etag!=null)
+            return true;
+        return super.containsHeader(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getOutputStream()
+     */
+    @Override
+    public ServletOutputStream getOutputStream() throws IOException
+    {
+        if (_compressedStream==null)
+        {
+            if (getResponse().isCommitted() || _noCompression)
+                return getResponse().getOutputStream();
+            
+            _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse());
+        }
+        else if (_writer!=null)
+            throw new IllegalStateException("getWriter() called");
+        
+        return _compressedStream;   
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#getWriter()
+     */
+    @Override
+    public PrintWriter getWriter() throws IOException
+    {
+        if (_writer==null)
+        { 
+            if (_compressedStream!=null)
+                throw new IllegalStateException("getOutputStream() called");
+            
+            if (getResponse().isCommitted() || _noCompression)
+                return getResponse().getWriter();
+            
+            _compressedStream=newCompressedStream(_request,(HttpServletResponse)getResponse());
+            _writer=newWriter(_compressedStream,getCharacterEncoding());
+        }
+        return _writer;   
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.http.gzip.CompressedResponseWrapper#setIntHeader(java.lang.String, int)
+     */
+    @Override
+    public void setIntHeader(String name, int value)
+    {
+        if ("content-length".equalsIgnoreCase(name))
+        {
+            _contentLength=value;
+            if (_compressedStream!=null)
+                _compressedStream.setContentLength();
+        }
+        else
+            super.setIntHeader(name,value);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Allows derived implementations to replace PrintWriter implementation.
+     *
+     * @param out the out
+     * @param encoding the encoding
+     * @return the prints the writer
+     * @throws UnsupportedEncodingException the unsupported encoding exception
+     */
+    protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+    {
+        return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     *@return the underlying CompressedStream implementation 
+     */
+    protected abstract AbstractCompressedStream newCompressedStream(HttpServletRequest _request, HttpServletResponse response) throws IOException;
+
+}
diff --git a/src/java/org/eclipse/jetty/http/ssl/SslContextFactory.java b/src/java/org/eclipse/jetty/http/ssl/SslContextFactory.java
new file mode 100644
index 0000000..b81d070
--- /dev/null
+++ b/src/java/org/eclipse/jetty/http/ssl/SslContextFactory.java
@@ -0,0 +1,41 @@
+//
+//  ========================================================================
+//  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.http.ssl;
+
+/* ------------------------------------------------------------ */
+/**
+ * @deprecated Use org.eclipse.jetty.util.ssl.SslContextFactory
+ */
+public class SslContextFactory extends org.eclipse.jetty.util.ssl.SslContextFactory
+{
+    public SslContextFactory()
+    {
+        super();
+    }
+
+    public SslContextFactory(boolean trustAll)
+    {
+        super(trustAll);
+    }
+
+    public SslContextFactory(String keyStorePath)
+    {
+        super(keyStorePath);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/AbstractBuffer.java b/src/java/org/eclipse/jetty/io/AbstractBuffer.java
new file mode 100644
index 0000000..19dd727
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/AbstractBuffer.java
@@ -0,0 +1,728 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * 
+ *  
+ */
+public abstract class AbstractBuffer implements Buffer
+{
+    private static final Logger LOG = Log.getLogger(AbstractBuffer.class);
+
+    private final static boolean __boundsChecking = Boolean.getBoolean("org.eclipse.jetty.io.AbstractBuffer.boundsChecking");
+    
+    protected final static String 
+    __IMMUTABLE = "IMMUTABLE", 
+    __READONLY = "READONLY",
+    __READWRITE = "READWRITE", 
+    __VOLATILE = "VOLATILE";
+    
+    protected int _access;
+    protected boolean _volatile;
+
+    protected int _get;
+    protected int _put;
+    protected int _hash;
+    protected int _hashGet;
+    protected int _hashPut;
+    protected int _mark;
+    protected String _string;
+    protected View _view;
+
+    /**
+     * Constructor for BufferView
+     * 
+     * @param access 0==IMMUTABLE, 1==READONLY, 2==READWRITE
+     */
+    public AbstractBuffer(int access, boolean isVolatile)
+    {
+        if (access == IMMUTABLE && isVolatile)
+                throw new IllegalArgumentException("IMMUTABLE && VOLATILE");
+        setMarkIndex(-1);
+        _access = access;
+        _volatile = isVolatile;
+    }
+
+    /*
+     * @see org.eclipse.io.Buffer#toArray()
+     */
+    public byte[] asArray()
+    {
+        byte[] bytes = new byte[length()];
+        byte[] array = array();
+        if (array != null)
+            System.arraycopy(array, getIndex(), bytes, 0, bytes.length);
+        else
+            peek(getIndex(), bytes, 0, length());
+        return bytes;
+    }
+
+    public ByteArrayBuffer duplicate(int access)
+    {
+        Buffer b=this.buffer();
+        if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve)
+            return new ByteArrayBuffer.CaseInsensitive(asArray(), 0, length(),access);
+        else
+            return new ByteArrayBuffer(asArray(), 0, length(), access);
+    }
+    
+    /*
+     * @see org.eclipse.io.Buffer#asNonVolatile()
+     */
+    public Buffer asNonVolatileBuffer()
+    {
+        if (!isVolatile()) return this;
+        return duplicate(_access);
+    }
+
+    public Buffer asImmutableBuffer()
+    {
+        if (isImmutable()) return this;
+        return duplicate(IMMUTABLE);
+    }
+
+    /*
+     * @see org.eclipse.util.Buffer#asReadOnlyBuffer()
+     */
+    public Buffer asReadOnlyBuffer()
+    {
+        if (isReadOnly()) return this;
+        return new View(this, markIndex(), getIndex(), putIndex(), READONLY);
+    }
+
+    public Buffer asMutableBuffer()
+    {
+        if (!isImmutable()) return this;
+        
+        Buffer b=this.buffer();
+        if (b.isReadOnly())
+        {
+            return duplicate(READWRITE);
+        }
+        return new View(b, markIndex(), getIndex(), putIndex(), _access);
+    }
+
+    public Buffer buffer()
+    {
+        return this;
+    }
+
+    public void clear()
+    {
+        setMarkIndex(-1);
+        setGetIndex(0);
+        setPutIndex(0);
+    }
+
+    public void compact()
+    {
+        if (isReadOnly()) throw new IllegalStateException(__READONLY);
+        int s = markIndex() >= 0 ? markIndex() : getIndex();
+        if (s > 0)
+        {
+            byte array[] = array();
+            int length = putIndex() - s;
+            if (length > 0)
+            {
+                if (array != null)
+                    System.arraycopy(array(), s, array(), 0, length);
+                else
+                    poke(0, peek(s, length));
+            }
+            if (markIndex() > 0) setMarkIndex(markIndex() - s);
+            setGetIndex(getIndex() - s);
+            setPutIndex(putIndex() - s);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj==this)
+            return true;
+        
+        // reject non buffers;
+        if (obj == null || !(obj instanceof Buffer)) return false;
+        Buffer b = (Buffer) obj;
+
+        if (this instanceof Buffer.CaseInsensitve ||  b instanceof Buffer.CaseInsensitve)
+            return equalsIgnoreCase(b);
+        
+        // reject different lengths
+        if (b.length() != length()) return false;
+
+        // reject AbstractBuffer with different hash value
+        if (_hash != 0 && obj instanceof AbstractBuffer)
+        {
+            AbstractBuffer ab = (AbstractBuffer) obj;
+            if (ab._hash != 0 && _hash != ab._hash) return false;
+        }
+
+        // Nothing for it but to do the hard grind.
+        int get=getIndex();
+        int bi=b.putIndex();
+        for (int i = putIndex(); i-->get;)
+        {
+            byte b1 = peek(i);
+            byte b2 = b.peek(--bi);
+            if (b1 != b2) return false;
+        }
+        return true;
+    }
+
+    public boolean equalsIgnoreCase(Buffer b)
+    {
+        if (b==this)
+            return true;
+        
+        // reject different lengths
+        if (b.length() != length()) return false;
+
+        // reject AbstractBuffer with different hash value
+        if (_hash != 0 && b instanceof AbstractBuffer)
+        {
+            AbstractBuffer ab = (AbstractBuffer) b;
+            if (ab._hash != 0 && _hash != ab._hash) return false;
+        }
+
+        // Nothing for it but to do the hard grind.
+        int get=getIndex();
+        int bi=b.putIndex();
+        
+        byte[] array = array();
+        byte[] barray= b.array();
+        if (array!=null && barray!=null)
+        {
+            for (int i = putIndex(); i-->get;)
+            {
+                byte b1 = array[i];
+                byte b2 = barray[--bi];
+                if (b1 != b2)
+                {
+                    if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
+                    if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
+                    if (b1 != b2) return false;
+                }
+            }
+        }
+        else
+        {
+            for (int i = putIndex(); i-->get;)
+            {
+                byte b1 = peek(i);
+                byte b2 = b.peek(--bi);
+                if (b1 != b2)
+                {
+                    if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
+                    if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
+                    if (b1 != b2) return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public byte get()
+    {
+        return peek(_get++);
+    }
+
+    public int get(byte[] b, int offset, int length)
+    {
+        int gi = getIndex();
+        int l=length();
+        if (l==0)
+            return -1;
+        
+        if (length>l)
+            length=l;
+        
+        length = peek(gi, b, offset, length);
+        if (length>0)
+            setGetIndex(gi + length);
+        return length;
+    }
+
+    public Buffer get(int length)
+    {
+        int gi = getIndex();
+        Buffer view = peek(gi, length);
+        setGetIndex(gi + length);
+        return view;
+    }
+
+    public final int getIndex()
+    {
+        return _get;
+    }
+
+    public boolean hasContent()
+    {
+        return _put > _get;
+    }
+    
+    @Override
+    public int hashCode()
+    {
+        if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) 
+        {
+            int get=getIndex();
+            byte[] array = array();
+            if (array==null)
+            {
+                for (int i = putIndex(); i-- >get;)
+                {
+                    byte b = peek(i);
+                    if ('a' <= b && b <= 'z') 
+                        b = (byte) (b - 'a' + 'A');
+                    _hash = 31 * _hash + b;
+                }
+            }
+            else
+            {
+                for (int i = putIndex(); i-- >get;)
+                {
+                    byte b = array[i];
+                    if ('a' <= b && b <= 'z') 
+                        b = (byte) (b - 'a' + 'A');
+                    _hash = 31 * _hash + b;
+                }
+            }
+            if (_hash == 0) 
+                _hash = -1;
+            _hashGet=_get;
+            _hashPut=_put;
+            
+        }
+        return _hash;
+    }
+
+    public boolean isImmutable()
+    {
+        return _access <= IMMUTABLE;
+    }
+
+    public boolean isReadOnly()
+    {
+        return _access <= READONLY;
+    }
+
+    public boolean isVolatile()
+    {
+        return _volatile;
+    }
+
+    public int length()
+    {
+        return _put - _get;
+    }
+
+    public void mark()
+    {
+        setMarkIndex(_get - 1);
+    }
+
+    public void mark(int offset)
+    {
+        setMarkIndex(_get + offset);
+    }
+
+    public int markIndex()
+    {
+        return _mark;
+    }
+
+    public byte peek()
+    {
+        return peek(_get);
+    }
+
+    public Buffer peek(int index, int length)
+    {
+        if (_view == null)
+        {
+            _view = new View(this, -1, index, index + length, isReadOnly() ? READONLY : READWRITE);
+        }
+        else
+        {
+            _view.update(this.buffer());
+            _view.setMarkIndex(-1);
+            _view.setGetIndex(0);
+            _view.setPutIndex(index + length);
+            _view.setGetIndex(index);
+            
+        }
+        return _view;
+    }
+
+    public int poke(int index, Buffer src)
+    {
+        _hash=0;
+        /* 
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        if (index < 0) 
+            throw new IllegalArgumentException("index<0: " + index + "<0");
+        */
+        
+        int length=src.length();
+        if (index + length > capacity())
+        {
+            length=capacity()-index;
+            /*
+            if (length<0)
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+            */
+        }
+        
+        byte[] src_array = src.array();
+        byte[] dst_array = array();
+        if (src_array != null && dst_array != null)
+            System.arraycopy(src_array, src.getIndex(), dst_array, index, length);
+        else if (src_array != null)
+        {
+            int s=src.getIndex();
+            for (int i=0;i<length;i++)
+                poke(index++,src_array[s++]);
+        }
+        else if (dst_array != null)
+        {
+            int s=src.getIndex();
+            for (int i=0;i<length;i++)
+                dst_array[index++]=src.peek(s++);
+        }
+        else
+        {
+            int s=src.getIndex();
+            for (int i=0;i<length;i++)
+                poke(index++,src.peek(s++));
+        }
+        
+        return length;
+    }
+    
+
+    public int poke(int index, byte[] b, int offset, int length)
+    {
+        _hash=0;
+        /*
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        if (index < 0) 
+            throw new IllegalArgumentException("index<0: " + index + "<0");
+        */
+        if (index + length > capacity())
+        {
+            length=capacity()-index;
+            /* if (length<0)
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+            */
+        }
+        
+        byte[] dst_array = array();
+        if (dst_array != null)
+            System.arraycopy(b, offset, dst_array, index, length);
+        else
+        {
+            int s=offset;
+            for (int i=0;i<length;i++)
+                poke(index++,b[s++]);
+        }
+        return length;
+    }
+
+    public int put(Buffer src)
+    {
+        int pi = putIndex();
+        int l=poke(pi, src);
+        setPutIndex(pi + l);
+        return l;
+    }
+
+    public void put(byte b)
+    {
+        int pi = putIndex();
+        poke(pi, b);
+        setPutIndex(pi + 1);
+    }
+
+    public int put(byte[] b, int offset, int length)
+    {
+        int pi = putIndex();
+        int l = poke(pi, b, offset, length);
+        setPutIndex(pi + l);
+        return l;
+    }
+    
+    public int put(byte[] b)
+    {
+        int pi = putIndex();
+        int l = poke(pi, b, 0, b.length);
+        setPutIndex(pi + l);
+        return l;
+    }
+
+    public final int putIndex()
+    {
+        return _put;
+    }
+
+    public void reset()
+    {
+        if (markIndex() >= 0) setGetIndex(markIndex());
+    }
+
+    public void rewind()
+    {
+        setGetIndex(0);
+        setMarkIndex(-1);
+    }
+
+    public void setGetIndex(int getIndex)
+    {
+        /* bounds checking
+        if (isImmutable()) 
+            throw new IllegalStateException(__IMMUTABLE);
+        if (getIndex < 0)
+            throw new IllegalArgumentException("getIndex<0: " + getIndex + "<0");
+        if (getIndex > putIndex())
+            throw new IllegalArgumentException("getIndex>putIndex: " + getIndex + ">" + putIndex());
+         */
+        _get = getIndex;
+        _hash=0;
+    }
+
+    public void setMarkIndex(int index)
+    {
+        /*
+        if (index>=0 && isImmutable()) 
+            throw new IllegalStateException(__IMMUTABLE);
+        */
+        _mark = index;
+    }
+
+    public void setPutIndex(int putIndex)
+    {
+        /* bounds checking
+        if (isImmutable()) 
+            throw new IllegalStateException(__IMMUTABLE);
+        if (putIndex > capacity())
+                throw new IllegalArgumentException("putIndex>capacity: " + putIndex + ">" + capacity());
+        if (getIndex() > putIndex)
+                throw new IllegalArgumentException("getIndex>putIndex: " + getIndex() + ">" + putIndex);
+         */
+        _put = putIndex;
+        _hash=0;
+    }
+
+    public int skip(int n)
+    {
+        if (length() < n) n = length();
+        setGetIndex(getIndex() + n);
+        return n;
+    }
+
+    public Buffer slice()
+    {
+        return peek(getIndex(), length());
+    }
+
+    public Buffer sliceFromMark()
+    {
+        return sliceFromMark(getIndex() - markIndex() - 1);
+    }
+
+    public Buffer sliceFromMark(int length)
+    {
+        if (markIndex() < 0) return null;
+        Buffer view = peek(markIndex(), length);
+        setMarkIndex(-1);
+        return view;
+    }
+
+    public int space()
+    {
+        return capacity() - _put;
+    }
+
+    public String toDetailString()
+    {
+        StringBuilder buf = new StringBuilder();
+        buf.append("[");
+        buf.append(super.hashCode());
+        buf.append(",");
+        buf.append(this.buffer().hashCode());
+        buf.append(",m=");
+        buf.append(markIndex());
+        buf.append(",g=");
+        buf.append(getIndex());
+        buf.append(",p=");
+        buf.append(putIndex());
+        buf.append(",c=");
+        buf.append(capacity());
+        buf.append("]={");
+        if (markIndex() >= 0)
+        {
+            for (int i = markIndex(); i < getIndex(); i++)
+            {
+                byte b =  peek(i);
+                TypeUtil.toHex(b,buf);
+            }
+            buf.append("}{");
+        }
+        int count = 0;
+        for (int i = getIndex(); i < putIndex(); i++)
+        {
+            byte b =  peek(i);
+            TypeUtil.toHex(b,buf);
+            if (count++ == 50)
+            {
+                if (putIndex() - i > 20)
+                {
+                    buf.append(" ... ");
+                    i = putIndex() - 20;
+                }
+            }
+        }
+        buf.append('}');
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        if (isImmutable())
+        {
+            if (_string == null) 
+                _string = new String(asArray(), 0, length());
+            return _string;
+        }
+        return new String(asArray(), 0, length());
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString(String charset)
+    {
+        try
+        {
+            byte[] bytes=array();
+            if (bytes!=null)
+                return new String(bytes,getIndex(),length(),charset);
+            return new String(asArray(), 0, length(),charset);
+            
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+            return new String(asArray(), 0, length());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString(Charset charset)
+    {
+        try
+        {
+            byte[] bytes=array();
+            if (bytes!=null)
+                return new String(bytes,getIndex(),length(),charset);
+            return new String(asArray(), 0, length(),charset);
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+            return new String(asArray(), 0, length());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toDebugString()
+    {
+        return getClass()+"@"+super.hashCode();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void writeTo(OutputStream out)
+    	throws IOException
+    {
+        byte[] array = array();
+        
+        if (array!=null)
+        {
+            out.write(array,getIndex(),length());
+        }
+        else
+        {
+            int len = this.length();
+            byte[] buf=new byte[len>1024?1024:len];
+            int offset=_get;
+            while (len>0)
+            {
+                int l=peek(offset,buf,0,len>buf.length?buf.length:len);
+                out.write(buf,0,l);
+                offset+=l;
+                len-=l;
+            }
+        } 
+        clear();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int readFrom(InputStream in,int max) throws IOException
+    {
+        byte[] array = array();
+        int s=space();
+        if (s>max)
+            s=max;
+
+        if (array!=null)
+        {
+            int l=in.read(array,_put,s);
+            if (l>0)
+                _put+=l;
+            return l;
+        }
+        else
+        {
+            byte[] buf=new byte[s>1024?1024:s];
+            int total=0;
+            while (s>0)
+            {
+                int l=in.read(buf,0,buf.length);
+                if (l<0)
+                    return total>0?total:-1;
+                int p=put(buf,0,l);
+                assert l==p;
+                s-=l;
+            }
+            return total; 
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/AbstractBuffers.java b/src/java/org/eclipse/jetty/io/AbstractBuffers.java
new file mode 100644
index 0000000..aa7aa8c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/AbstractBuffers.java
@@ -0,0 +1,168 @@
+//
+//  ========================================================================
+//  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.io;
+
+import org.eclipse.jetty.io.nio.DirectNIOBuffer;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+
+public abstract class AbstractBuffers implements Buffers
+{
+    protected final Buffers.Type _headerType;
+    protected final int _headerSize;
+    protected final Buffers.Type _bufferType;
+    protected final int _bufferSize;
+    protected final Buffers.Type _otherType;
+
+    /* ------------------------------------------------------------ */
+    public AbstractBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType)
+    {
+        _headerType=headerType;
+        _headerSize=headerSize;
+        _bufferType=bufferType;
+        _bufferSize=bufferSize;
+        _otherType=otherType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the buffer size in bytes.
+     */
+    public int getBufferSize()
+    {
+        return _bufferSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the header size in bytes.
+     */
+    public int getHeaderSize()
+    {
+        return _headerSize;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new header Buffer
+     * @return new Buffer
+     */
+    final protected Buffer newHeader()
+    {
+        switch(_headerType)
+        {
+            case BYTE_ARRAY:
+                return new ByteArrayBuffer(_headerSize);
+            case DIRECT:
+                return new DirectNIOBuffer(_headerSize);
+            case INDIRECT:
+                return new IndirectNIOBuffer(_headerSize);
+        }
+        throw new IllegalStateException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new content Buffer
+     * @return new Buffer
+     */
+    final protected Buffer newBuffer()
+    {
+       switch(_bufferType)
+       {
+           case BYTE_ARRAY:
+               return new ByteArrayBuffer(_bufferSize);
+           case DIRECT:
+               return new DirectNIOBuffer(_bufferSize);
+           case INDIRECT:
+               return new IndirectNIOBuffer(_bufferSize);
+       }
+       throw new IllegalStateException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new content Buffer
+     * @param size
+     * @return new Buffer
+     */
+    final protected Buffer newBuffer(int size)
+    {
+       switch(_otherType)
+       {
+           case BYTE_ARRAY:
+               return new ByteArrayBuffer(size);
+           case DIRECT:
+               return new DirectNIOBuffer(size);
+           case INDIRECT:
+               return new IndirectNIOBuffer(size);
+       }
+       throw new IllegalStateException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffer
+     * @return True if the buffer is the correct type to be a Header buffer
+     */
+    public final boolean isHeader(Buffer buffer)
+    {
+        if (buffer.capacity()==_headerSize)
+        {
+            switch(_headerType)
+            {
+                case BYTE_ARRAY:
+                    return buffer instanceof ByteArrayBuffer && !(buffer instanceof  IndirectNIOBuffer);
+                case DIRECT:
+                    return buffer instanceof  DirectNIOBuffer;
+                case INDIRECT:
+                    return buffer instanceof  IndirectNIOBuffer;
+            }
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffer
+     * @return True if the buffer is the correct type to be a Header buffer
+     */
+    public final boolean isBuffer(Buffer buffer)
+    {
+        if (buffer.capacity()==_bufferSize)
+        {
+            switch(_bufferType)
+            {
+                case BYTE_ARRAY:
+                    return buffer instanceof ByteArrayBuffer && !(buffer instanceof  IndirectNIOBuffer);
+                case DIRECT:
+                    return buffer instanceof  DirectNIOBuffer;
+                case INDIRECT:
+                    return buffer instanceof  IndirectNIOBuffer;
+            }
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return String.format("%s [%d,%d]", getClass().getSimpleName(), _headerSize, _bufferSize);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/AbstractConnection.java b/src/java/org/eclipse/jetty/io/AbstractConnection.java
new file mode 100644
index 0000000..7aa846c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/AbstractConnection.java
@@ -0,0 +1,85 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+public abstract class AbstractConnection implements Connection
+{
+    private static final Logger LOG = Log.getLogger(AbstractConnection.class);
+
+    private final long _timeStamp;
+    protected final EndPoint _endp;
+
+    public AbstractConnection(EndPoint endp)
+    {
+        _endp=(EndPoint)endp;
+        _timeStamp = System.currentTimeMillis();
+    }
+
+    public AbstractConnection(EndPoint endp,long timestamp)
+    {
+        _endp=(EndPoint)endp;
+        _timeStamp = timestamp;
+    }
+
+    public long getTimeStamp()
+    {
+        return _timeStamp;
+    }
+
+    public EndPoint getEndPoint()
+    {
+        return _endp;
+    }
+
+    public void onIdleExpired(long idleForMs)
+    {
+        try
+        {
+            LOG.debug("onIdleExpired {}ms {} {}",idleForMs,this,_endp);
+            if (_endp.isInputShutdown() || _endp.isOutputShutdown())
+                _endp.close();
+            else
+                _endp.shutdownOutput();
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+
+            try
+            {
+                _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+        }
+    }
+
+    public String toString()
+    {
+        return String.format("%s@%x", getClass().getSimpleName(), hashCode());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/AsyncEndPoint.java b/src/java/org/eclipse/jetty/io/AsyncEndPoint.java
new file mode 100644
index 0000000..42ec421
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/AsyncEndPoint.java
@@ -0,0 +1,83 @@
+//
+//  ========================================================================
+//  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.io;
+
+import org.eclipse.jetty.util.thread.Timeout;
+
+public interface AsyncEndPoint extends ConnectedEndPoint
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * Dispatch the endpoint if it is not already dispatched
+     * 
+     */
+    public void dispatch();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Dispatch the endpoint. If it is already dispatched, schedule a redispatch
+     * 
+     */
+    public void asyncDispatch();
+    
+    /* ------------------------------------------------------------ */
+    /** Schedule a write dispatch.
+     * Set the endpoint to not be writable and schedule a dispatch when
+     * it becomes writable.
+     */
+    public void scheduleWrite();  
+
+    /* ------------------------------------------------------------ */
+    /** Callback when idle.
+     * <p>An endpoint is idle if there has been no IO activity for 
+     * {@link #getMaxIdleTime()} and {@link #isCheckForIdle()} is true.
+     * @param idleForMs TODO
+     */
+    public void onIdleExpired(long idleForMs);
+
+    /* ------------------------------------------------------------ */
+    /** Set if the endpoint should be checked for idleness
+     */
+    public void setCheckForIdle(boolean check);
+
+    /* ------------------------------------------------------------ */
+    /** Get if the endpoint should be checked for idleness
+     */
+    public boolean isCheckForIdle();
+
+    
+    /* ------------------------------------------------------------ */
+    public boolean isWritable();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if IO has been successfully performed since the last call to {@link #hasProgressed()}
+     */
+    public boolean hasProgressed();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void scheduleTimeout(Timeout.Task task, long timeoutMs);
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void cancelTimeout(Timeout.Task task);
+}
diff --git a/src/java/org/eclipse/jetty/io/Buffer.java b/src/java/org/eclipse/jetty/io/Buffer.java
new file mode 100644
index 0000000..fb79bf2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/Buffer.java
@@ -0,0 +1,380 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+
+/**
+ * Byte Buffer interface.
+ * 
+ * This is a byte buffer that is designed to work like a FIFO for bytes. Puts and Gets operate on different
+ * pointers into the buffer and the valid _content of the buffer is always between the getIndex and the putIndex.
+ * 
+ * This buffer interface is designed to be similar, but not dependent on the java.nio buffers, which may
+ * be used to back an implementation of this Buffer. The main difference is that NIO buffer after a put have 
+ * their valid _content before the position and a flip is required to access that data.
+ *
+ * For this buffer it is always true that:
+ *  markValue <= getIndex <= putIndex <= capacity
+ *  
+ *
+ * @version 1.0
+ */
+public interface Buffer extends Cloneable
+{
+    public final static int 
+      IMMUTABLE=0,  // neither indexes or contexts can be changed
+      READONLY=1,   // indexes may be changed, but not content
+      READWRITE=2;  // anything can be changed
+    public final boolean VOLATILE=true;     // The buffer may change outside of current scope.
+    public final boolean NON_VOLATILE=false;
+
+    /**
+     *  Get the underlying array, if one exists.
+     * @return a <code>byte[]</code> backing this buffer or null if none exists.
+     */
+    byte[] array();
+    
+    /**
+     * 
+     * @return a <code>byte[]</code> value of the bytes from the getIndex to the putIndex.
+     */
+    byte[] asArray();
+    
+    /** 
+     * Get the underlying buffer. If this buffer wraps a backing buffer.
+     * @return The root backing buffer or this if there is no backing buffer;
+     */
+    Buffer buffer();
+    
+    /**
+     * 
+     * @return a non volatile version of this <code>Buffer</code> value
+     */
+    Buffer asNonVolatileBuffer();
+
+    /**
+     *
+     * @return a readonly version of this <code>Buffer</code>.
+     */
+    Buffer asReadOnlyBuffer();
+
+    /**
+     *
+     * @return an immutable version of this <code>Buffer</code>.
+     */
+    Buffer asImmutableBuffer();
+
+    /**
+     *
+     * @return an immutable version of this <code>Buffer</code>.
+     */
+    Buffer asMutableBuffer();
+    
+    /**
+     * 
+     * The capacity of the buffer. This is the maximum putIndex that may be set.
+     * @return an <code>int</code> value
+     */
+    int capacity();
+    
+    /**
+     * the space remaining in the buffer.
+     * @return capacity - putIndex
+     */
+    int space();
+    
+    /**
+     * Clear the buffer. getIndex=0, putIndex=0.
+     */
+    void clear();
+
+    /**
+     * Compact the buffer by discarding bytes before the postion (or mark if set).
+     * Bytes from the getIndex (or mark) to the putIndex are moved to the beginning of 
+     * the buffer and the values adjusted accordingly.
+     */
+    void compact();
+    
+    /**
+     * Get the byte at the current getIndex and increment it.
+     * @return The <code>byte</code> value from the current getIndex.
+     */
+    byte get();
+    
+    /**
+     * Get bytes from the current postion and put them into the passed byte array.
+     * The getIndex is incremented by the number of bytes copied into the array.
+     * @param b The byte array to fill.
+     * @param offset Offset in the array.
+     * @param length The max number of bytes to read.
+     * @return The number of bytes actually read.
+     */
+    int get(byte[] b, int offset, int length);
+
+    /**
+     * 
+     * @param length an <code>int</code> value
+     * @return a <code>Buffer</code> value
+     */
+    Buffer get(int length);
+
+    /**
+     * The index within the buffer that will next be read or written.
+     * @return an <code>int</code> value >=0 <= putIndex()
+     */
+    int getIndex();
+    
+    /**
+     * @return true of putIndex > getIndex
+     */
+    boolean hasContent();
+    
+    /**
+     * 
+     * @return a <code>boolean</code> value true if case sensitive comparison on this buffer
+     */
+    boolean equalsIgnoreCase(Buffer buffer);
+
+
+    /**
+     * 
+     * @return a <code>boolean</code> value true if the buffer is immutable and that neither
+     * the buffer contents nor the indexes may be changed.
+     */
+    boolean isImmutable();
+    
+    /**
+     * 
+     * @return a <code>boolean</code> value true if the buffer is readonly. The buffer indexes may
+     * be modified, but the buffer contents may not. For example a View onto an immutable Buffer will be
+     * read only.
+     */
+    boolean isReadOnly();
+    
+    /**
+     * 
+     * @return a <code>boolean</code> value true if the buffer contents may change 
+     * via alternate paths than this buffer.  If the contents of this buffer are to be used outside of the
+     * current context, then a copy must be made.
+     */
+    boolean isVolatile();
+
+    /**
+     * The number of bytes from the getIndex to the putIndex
+     * @return an <code>int</code> == putIndex()-getIndex()
+     */
+    int length();
+    
+    /**
+     * Set the mark to the current getIndex.
+     */
+    void mark();
+    
+    /**
+     * Set the mark relative to the current getIndex
+     * @param offset an <code>int</code> value to add to the current getIndex to obtain the mark value.
+     */
+    void mark(int offset);
+
+    /**
+     * The current index of the mark.
+     * @return an <code>int</code> index in the buffer or -1 if the mark is not set.
+     */
+    int markIndex();
+
+    /**
+     * Get the byte at the current getIndex without incrementing the getIndex.
+     * @return The <code>byte</code> value from the current getIndex.
+     */
+    byte peek();
+  
+    /**
+     * Get the byte at a specific index in the buffer.
+     * @param index an <code>int</code> value
+     * @return a <code>byte</code> value
+     */
+    byte peek(int index);
+
+    /**
+     * 
+     * @param index an <code>int</code> value
+     * @param length an <code>int</code> value
+     * @return The <code>Buffer</code> value from the requested getIndex.
+     */
+    Buffer peek(int index, int length);
+
+    /**
+     * 
+     * @param index an <code>int</code> value
+     * @param b The byte array to peek into
+     * @param offset The offset into the array to start peeking
+     * @param length an <code>int</code> value
+     * @return The number of bytes actually peeked
+     */
+    int peek(int index, byte[] b, int offset, int length);
+    
+    /**
+     * Put the contents of the buffer at the specific index.
+     * @param index an <code>int</code> value
+     * @param src a <code>Buffer</code>. If the source buffer is not modified
+    
+     * @return The number of bytes actually poked
+     */
+    int poke(int index, Buffer src);
+    
+    /**
+     * Put a specific byte to a specific getIndex.
+     * @param index an <code>int</code> value
+     * @param b a <code>byte</code> value
+     */
+    void poke(int index, byte b);
+    
+    /**
+     * Put a specific byte to a specific getIndex.
+     * @param index an <code>int</code> value
+     * @param b a <code>byte array</code> value
+     * @return The number of bytes actually poked
+     */
+    int poke(int index, byte b[], int offset, int length);
+    
+    /**
+     * Write the bytes from the source buffer to the current getIndex.
+     * @param src The source <code>Buffer</code> it is not modified.
+     * @return The number of bytes actually poked
+     */
+    int put(Buffer src);
+
+    /**
+     * Put a byte to the current getIndex and increment the getIndex.
+     * @param b a <code>byte</code> value
+     */
+    void put(byte b);
+    
+    /**
+     * Put a byte to the current getIndex and increment the getIndex.
+     * @param b a <code>byte</code> value
+     * @return The number of bytes actually poked
+     */
+    int put(byte[] b,int offset, int length);
+
+    /**
+     * Put a byte to the current getIndex and increment the getIndex.
+     * @param b a <code>byte</code> value
+     * @return The number of bytes actually poked
+     */
+    int put(byte[] b);
+
+    /**
+     * The index of the first element that should not be read.
+     * @return an <code>int</code> value >= getIndex() 
+     */
+    int putIndex();
+    
+    /**
+     * Reset the current getIndex to the mark 
+     */
+    void reset();
+    
+    /**
+     * Set the buffers start getIndex.
+     * @param newStart an <code>int</code> value
+     */
+    void setGetIndex(int newStart);
+    
+    /**
+     * Set a specific value for the mark.
+     * @param newMark an <code>int</code> value
+     */
+    void setMarkIndex(int newMark);
+    
+    /**
+     * 
+     * @param newLimit an <code>int</code> value
+     */
+    void setPutIndex(int newLimit);
+    
+    /**
+     * Skip _content. The getIndex is updated by min(remaining(), n)
+     * @param n The number of bytes to skip
+     * @return the number of bytes skipped.
+     */
+    int skip(int n);
+
+    /**
+     * 
+     * @return a volitile <code>Buffer</code> from the postion to the putIndex.
+     */
+    Buffer slice();
+    
+    /**
+     * 
+     *
+     * @return a volitile <code>Buffer</code> value from the mark to the putIndex
+     */
+    Buffer sliceFromMark();
+    
+    /**
+     * 
+     *
+     * @param length an <code>int</code> value
+     * @return a valitile <code>Buffer</code> value from the mark of the length requested.
+     */
+    Buffer sliceFromMark(int length);
+    
+    /**
+     * 
+     * @return a <code>String</code> value describing the state and contents of the buffer.
+     */
+    String toDetailString();
+
+    /* ------------------------------------------------------------ */
+    /** Write the buffer's contents to the output stream
+     * @param out
+     */
+    void writeTo(OutputStream out) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    /** Read the buffer's contents from the input stream
+     * @param in input stream
+     * @param max maximum number of bytes that may be read
+     * @return actual number of bytes read or -1 for EOF
+     */
+    int readFrom(InputStream in, int max) throws IOException;
+    
+
+    /* ------------------------------------------------------------ */
+    String toString(String charset);
+    
+    /* ------------------------------------------------------------ */
+    String toString(Charset charset);
+
+    /*
+     * Buffers implementing this interface should be compared with case insensitive equals
+     *
+     */
+    public interface CaseInsensitve
+    {}
+
+    
+}
diff --git a/src/java/org/eclipse/jetty/io/BufferCache.java b/src/java/org/eclipse/jetty/io/BufferCache.java
new file mode 100644
index 0000000..f61857a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/BufferCache.java
@@ -0,0 +1,169 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+import org.eclipse.jetty.util.StringMap;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * Stores a collection of {@link Buffer} objects.
+ * Buffers are stored in an ordered collection and can retreived by index or value
+ * 
+ */
+public class BufferCache
+{
+    private final HashMap _bufferMap=new HashMap();
+    private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE);
+    private final ArrayList _index= new ArrayList();
+
+    /* ------------------------------------------------------------------------------- */
+    /** Add a buffer to the cache at the specified index.
+     * @param value The content of the buffer.
+     */
+    public CachedBuffer add(String value, int ordinal)
+    {
+        CachedBuffer buffer= new CachedBuffer(value, ordinal);
+        _bufferMap.put(buffer, buffer);
+        _stringMap.put(value, buffer);
+        while ((ordinal - _index.size()) >= 0)
+            _index.add(null);
+        if (_index.get(ordinal)==null)
+            _index.add(ordinal, buffer);
+        return buffer;
+    }
+
+    public CachedBuffer get(int ordinal)
+    {
+        if (ordinal < 0 || ordinal >= _index.size())
+            return null;
+        return (CachedBuffer)_index.get(ordinal);
+    }
+
+    public CachedBuffer get(Buffer buffer)
+    {
+        return (CachedBuffer)_bufferMap.get(buffer);
+    }
+
+    public CachedBuffer get(String value)
+    {
+        return (CachedBuffer)_stringMap.get(value);
+    }
+
+    public Buffer lookup(Buffer buffer)
+    {
+        if (buffer instanceof CachedBuffer)
+            return buffer;
+        
+        Buffer b= get(buffer);
+        if (b == null)
+        {
+            if (buffer instanceof Buffer.CaseInsensitve)
+                return buffer;
+            return new ByteArrayBuffer.CaseInsensitive(buffer.asArray(),0,buffer.length(),Buffer.IMMUTABLE);
+        }
+
+        return b;
+    }
+    
+    public CachedBuffer getBest(byte[] value, int offset, int maxLength)
+    {
+        Entry entry = _stringMap.getBestEntry(value, offset, maxLength);
+        if (entry!=null)
+            return (CachedBuffer)entry.getValue();
+        return null;
+    }
+
+    public Buffer lookup(String value)
+    {
+        Buffer b= get(value);
+        if (b == null)
+        {
+            return new CachedBuffer(value,-1);
+        }
+        return b;
+    }
+
+    public String toString(Buffer buffer)
+    {
+        return lookup(buffer).toString();
+    }
+
+    public int getOrdinal(String value)
+    {
+        CachedBuffer buffer = (CachedBuffer)_stringMap.get(value);
+        return buffer==null?-1:buffer.getOrdinal();
+    }
+    
+    public int getOrdinal(Buffer buffer)
+    {
+        if (buffer instanceof CachedBuffer)
+            return ((CachedBuffer)buffer).getOrdinal();
+        buffer=lookup(buffer);
+        if (buffer!=null && buffer instanceof CachedBuffer)
+            return ((CachedBuffer)buffer).getOrdinal();
+        return -1;
+    }
+    
+    public static class CachedBuffer extends ByteArrayBuffer.CaseInsensitive
+    {
+        private final int _ordinal;
+        private HashMap _associateMap=null;
+        
+        public CachedBuffer(String value, int ordinal)
+        {
+            super(value);
+            _ordinal= ordinal;
+        }
+
+        public int getOrdinal()
+        {
+            return _ordinal;
+        }
+
+        public CachedBuffer getAssociate(Object key)
+        {
+            if (_associateMap==null)
+                return null;
+            return (CachedBuffer)_associateMap.get(key);
+        }
+
+        // TODO Replace Associate with a mime encoding specific solution
+        public void setAssociate(Object key, CachedBuffer associate)
+        {
+            if (_associateMap==null)
+                _associateMap=new HashMap();
+            _associateMap.put(key,associate);
+        }
+    }
+    
+    
+    @Override
+    public String toString()
+    {
+        return "CACHE["+
+        	"bufferMap="+_bufferMap+
+        	",stringMap="+_stringMap+
+        	",index="+_index+
+        	"]";
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/BufferDateCache.java b/src/java/org/eclipse/jetty/io/BufferDateCache.java
new file mode 100644
index 0000000..d92d57f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/BufferDateCache.java
@@ -0,0 +1,61 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.text.DateFormatSymbols;
+import java.util.Locale;
+
+import org.eclipse.jetty.util.DateCache;
+
+public class BufferDateCache extends DateCache
+{
+    Buffer _buffer;
+    String _last;
+    
+    public BufferDateCache()
+    {
+        super();
+    }
+
+    public BufferDateCache(String format, DateFormatSymbols s)
+    {
+        super(format,s);
+    }
+
+    public BufferDateCache(String format, Locale l)
+    {
+        super(format,l);
+    }
+
+    public BufferDateCache(String format)
+    {
+        super(format);
+    }
+
+    public synchronized Buffer formatBuffer(long date)
+    {
+        String d = super.format(date);
+        if (d==_last)
+            return _buffer;
+        _last=d;
+        _buffer=new ByteArrayBuffer(d);
+        
+        return _buffer;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/BufferUtil.java b/src/java/org/eclipse/jetty/io/BufferUtil.java
new file mode 100644
index 0000000..828d813
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/BufferUtil.java
@@ -0,0 +1,359 @@
+//
+//  ========================================================================
+//  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.io;
+
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.util.StringUtil;
+
+/* ------------------------------------------------------------------------------- */
+/** Buffer utility methods.
+ * 
+ * 
+ */
+public class BufferUtil
+{
+    static final byte SPACE= 0x20;
+    static final byte MINUS= '-';
+    static final byte[] DIGIT=
+    {(byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7',(byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F'};
+
+    /**
+     * Convert buffer to an integer.
+     * Parses up to the first non-numeric character. If no number is found an
+     * IllegalArgumentException is thrown
+     * @param buffer A buffer containing an integer. The position is not changed.
+     * @return an int 
+     */
+    public static int toInt(Buffer buffer)
+    {
+        int val= 0;
+        boolean started= false;
+        boolean minus= false;
+        for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
+        {
+            byte b= buffer.peek(i);
+            if (b <= SPACE)
+            {
+                if (started)
+                    break;
+            }
+            else if (b >= '0' && b <= '9')
+            {
+                val= val * 10 + (b - '0');
+                started= true;
+            }
+            else if (b == MINUS && !started)
+            {
+                minus= true;
+            }
+            else
+                break;
+        }
+
+        if (started)
+            return minus ? (-val) : val;
+        throw new NumberFormatException(buffer.toString());
+    }
+    
+    /**
+     * Convert buffer to an long.
+     * Parses up to the first non-numeric character. If no number is found an
+     * IllegalArgumentException is thrown
+     * @param buffer A buffer containing an integer. The position is not changed.
+     * @return an int 
+     */
+    public static long toLong(Buffer buffer)
+    {
+        long val= 0;
+        boolean started= false;
+        boolean minus= false;
+        for (int i= buffer.getIndex(); i < buffer.putIndex(); i++)
+        {
+            byte b= buffer.peek(i);
+            if (b <= SPACE)
+            {
+                if (started)
+                    break;
+            }
+            else if (b >= '0' && b <= '9')
+            {
+                val= val * 10L + (b - '0');
+                started= true;
+            }
+            else if (b == MINUS && !started)
+            {
+                minus= true;
+            }
+            else
+                break;
+        }
+
+        if (started)
+            return minus ? (-val) : val;
+        throw new NumberFormatException(buffer.toString());
+    }
+
+    public static void putHexInt(Buffer buffer, int n)
+    {
+
+        if (n < 0)
+        {
+            buffer.put((byte)'-');
+
+            if (n == Integer.MIN_VALUE)
+            {
+                buffer.put((byte)(0x7f&'8'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                buffer.put((byte)(0x7f&'0'));
+                
+                return;
+            }
+            n= -n;
+        }
+
+        if (n < 0x10)
+        {
+            buffer.put(DIGIT[n]);
+        }
+        else
+        {
+            boolean started= false;
+            // This assumes constant time int arithmatic
+            for (int i= 0; i < hexDivisors.length; i++)
+            {
+                if (n < hexDivisors[i])
+                {
+                    if (started)
+                        buffer.put((byte)'0');
+                    continue;
+                }
+
+                started= true;
+                int d= n / hexDivisors[i];
+                buffer.put(DIGIT[d]);
+                n= n - d * hexDivisors[i];
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add hex integer BEFORE current getIndex.
+     * @param buffer
+     * @param n
+     */
+    public static void prependHexInt(Buffer buffer, int n)
+    {
+        if (n==0)
+        {
+            int gi=buffer.getIndex();
+            buffer.poke(--gi,(byte)'0');
+            buffer.setGetIndex(gi);
+        }
+        else
+        {
+            boolean minus=false;
+            if (n<0)
+            {
+                minus=true;
+                n=-n;
+            }
+
+            int gi=buffer.getIndex();
+            while(n>0)
+            {
+                int d = 0xf&n;
+                n=n>>4;
+                buffer.poke(--gi,DIGIT[d]);
+            }
+            
+            if (minus)
+                buffer.poke(--gi,(byte)'-');
+            buffer.setGetIndex(gi);
+        }
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    public static void putDecInt(Buffer buffer, int n)
+    {
+        if (n < 0)
+        {
+            buffer.put((byte)'-');
+
+            if (n == Integer.MIN_VALUE)
+            {
+                buffer.put((byte)'2');
+                n= 147483648;
+            }
+            else
+                n= -n;
+        }
+
+        if (n < 10)
+        {
+            buffer.put(DIGIT[n]);
+        }
+        else
+        {
+            boolean started= false;
+            // This assumes constant time int arithmatic
+            for (int i= 0; i < decDivisors.length; i++)
+            {
+                if (n < decDivisors[i])
+                {
+                    if (started)
+                        buffer.put((byte)'0');
+                    continue;
+                }
+
+                started= true;
+                int d= n / decDivisors[i];
+                buffer.put(DIGIT[d]);
+                n= n - d * decDivisors[i];
+            }
+        }
+    }
+    
+    public static void putDecLong(Buffer buffer, long n)
+    {
+        if (n < 0)
+        {
+            buffer.put((byte)'-');
+
+            if (n == Long.MIN_VALUE)
+            {
+                buffer.put((byte)'9');
+                n= 223372036854775808L;
+            }
+            else
+                n= -n;
+        }
+
+        if (n < 10)
+        {
+            buffer.put(DIGIT[(int)n]);
+        }
+        else
+        {
+            boolean started= false;
+            // This assumes constant time int arithmatic
+            for (int i= 0; i < decDivisorsL.length; i++)
+            {
+                if (n < decDivisorsL[i])
+                {
+                    if (started)
+                        buffer.put((byte)'0');
+                    continue;
+                }
+
+                started= true;
+                long d= n / decDivisorsL[i];
+                buffer.put(DIGIT[(int)d]);
+                n= n - d * decDivisorsL[i];
+            }
+        }
+    }
+    
+    public static Buffer toBuffer(long value)
+    {
+        ByteArrayBuffer buf=new ByteArrayBuffer(32);
+        putDecLong(buf, value);
+        return buf;
+    }
+
+    private final static int[] decDivisors=
+    { 
+        1000000000,
+        100000000,
+        10000000,
+        1000000,
+        100000,
+        10000,
+        1000,
+        100,
+        10,
+        1 
+    };
+
+    private final static int[] hexDivisors=
+    {
+        0x10000000,
+        0x1000000, 
+        0x100000, 
+        0x10000, 
+        0x1000, 
+        0x100, 
+        0x10, 
+        0x1 
+    };
+
+    private final static long[] decDivisorsL=
+    { 
+        1000000000000000000L,
+        100000000000000000L,
+        10000000000000000L,
+        1000000000000000L,
+        100000000000000L,
+        10000000000000L,
+        1000000000000L,
+        100000000000L,
+        10000000000L,
+        1000000000L,
+        100000000L,
+        10000000L,
+        1000000L,
+        100000L,
+        10000L,
+        1000L,
+        100L,
+        10L,
+        1L 
+    };
+
+
+    public static void putCRLF(Buffer buffer)
+    {
+        buffer.put((byte)13);
+        buffer.put((byte)10);
+    }
+    
+    public static boolean isPrefix(Buffer prefix,Buffer buffer)
+    {
+        if (prefix.length()>buffer.length())
+            return false;
+        int bi=buffer.getIndex();
+        for (int i=prefix.getIndex(); i<prefix.putIndex();i++)
+            if (prefix.peek(i)!=buffer.peek(bi++))
+                return false;
+        return true;
+    }
+
+    public static String to8859_1_String(Buffer buffer)
+    {
+        if (buffer instanceof CachedBuffer)
+            return buffer.toString();
+        return buffer.toString(StringUtil.__ISO_8859_1_CHARSET);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/Buffers.java b/src/java/org/eclipse/jetty/io/Buffers.java
new file mode 100644
index 0000000..5c0fb9d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/Buffers.java
@@ -0,0 +1,38 @@
+//
+//  ========================================================================
+//  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.io;
+
+
+/* ------------------------------------------------------------ */
+/** BufferSource.
+ * Represents a pool or other source of buffers and abstracts the creation
+ * of specific types of buffers (eg NIO).   The concept of big and little buffers
+ * is supported, but these terms have no absolute meaning and must be determined by context.
+ * 
+ */
+public interface Buffers
+{
+    enum Type { BYTE_ARRAY, DIRECT, INDIRECT } ;
+    
+    Buffer getHeader();
+    Buffer getBuffer();
+    Buffer getBuffer(int size);
+    
+    void returnBuffer(Buffer buffer);
+}
diff --git a/src/java/org/eclipse/jetty/io/BuffersFactory.java b/src/java/org/eclipse/jetty/io/BuffersFactory.java
new file mode 100644
index 0000000..2fc2818
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/BuffersFactory.java
@@ -0,0 +1,29 @@
+//
+//  ========================================================================
+//  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.io;
+
+public class BuffersFactory
+{
+    public static Buffers newBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType,int maxSize)
+    {
+        if (maxSize>=0)
+            return new PooledBuffers(headerType,headerSize,bufferType,bufferSize,otherType,maxSize);
+        return new ThreadLocalBuffers(headerType,headerSize,bufferType,bufferSize,otherType);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/ByteArrayBuffer.java b/src/java/org/eclipse/jetty/io/ByteArrayBuffer.java
new file mode 100644
index 0000000..1df36cd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/ByteArrayBuffer.java
@@ -0,0 +1,439 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.jetty.util.StringUtil;
+
+/* ------------------------------------------------------------------------------- */
+/**
+ * 
+ */
+public class ByteArrayBuffer extends AbstractBuffer
+{
+    // Set a maximum size to a write for the writeTo method, to ensure that very large content is not
+    // written as a single write (which may fall foul to write timeouts if consumed slowly).
+    final static int MAX_WRITE=Integer.getInteger("org.eclipse.jetty.io.ByteArrayBuffer.MAX_WRITE",128*1024);
+    final protected byte[] _bytes;
+
+    protected ByteArrayBuffer(int size, int access, boolean isVolatile)
+    {
+        this(new byte[size],0,0,access, isVolatile);
+    }
+    
+    public ByteArrayBuffer(byte[] bytes)
+    {
+        this(bytes, 0, bytes.length, READWRITE);
+    }
+
+    public ByteArrayBuffer(byte[] bytes, int index, int length)
+    {
+        this(bytes, index, length, READWRITE);
+    }
+
+    public ByteArrayBuffer(byte[] bytes, int index, int length, int access)
+    {
+        super(READWRITE, NON_VOLATILE);
+        _bytes = bytes;
+        setPutIndex(index + length);
+        setGetIndex(index);
+        _access = access;
+    }
+
+    public ByteArrayBuffer(byte[] bytes, int index, int length, int access, boolean isVolatile)
+    {
+        super(READWRITE, isVolatile);
+        _bytes = bytes;
+        setPutIndex(index + length);
+        setGetIndex(index);
+        _access = access;
+    }
+
+    public ByteArrayBuffer(int size)
+    {
+        this(new byte[size], 0, 0, READWRITE);
+        setPutIndex(0);
+    }
+
+    public ByteArrayBuffer(String value)
+    {
+        super(READWRITE,NON_VOLATILE);
+        _bytes = StringUtil.getBytes(value);
+        setGetIndex(0);
+        setPutIndex(_bytes.length);
+        _access=IMMUTABLE;
+        _string = value;
+    }
+    
+    public ByteArrayBuffer(String value,boolean immutable)
+    {
+        super(READWRITE,NON_VOLATILE);
+        _bytes = StringUtil.getBytes(value);
+        setGetIndex(0);
+        setPutIndex(_bytes.length);
+        if (immutable)
+        {
+            _access=IMMUTABLE;
+            _string = value;
+        }
+    }
+
+    public ByteArrayBuffer(String value,String encoding) throws UnsupportedEncodingException
+    {
+        super(READWRITE,NON_VOLATILE);
+        _bytes = value.getBytes(encoding);
+        setGetIndex(0);
+        setPutIndex(_bytes.length);
+        _access=IMMUTABLE;
+        _string = value;
+    }
+
+    public byte[] array()
+    {
+        return _bytes;
+    }
+
+    public int capacity()
+    {
+        return _bytes.length;
+    }
+    
+    @Override
+    public void compact()
+    {
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        int s = markIndex() >= 0 ? markIndex() : getIndex();
+        if (s > 0)
+        {
+            int length = putIndex() - s;
+            if (length > 0)
+            {
+                System.arraycopy(_bytes, s,_bytes, 0, length);
+            }
+            if (markIndex() > 0) setMarkIndex(markIndex() - s);
+            setGetIndex(getIndex() - s);
+            setPutIndex(putIndex() - s);
+        }
+    }
+
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj==this)
+            return true;
+
+        if (obj == null || !(obj instanceof Buffer)) 
+            return false;
+        
+        if (obj instanceof Buffer.CaseInsensitve)
+            return equalsIgnoreCase((Buffer)obj);
+        
+
+        Buffer b = (Buffer) obj;
+        
+        // reject different lengths
+        if (b.length() != length()) 
+            return false;
+
+        // reject AbstractBuffer with different hash value
+        if (_hash != 0 && obj instanceof AbstractBuffer)
+        {
+            AbstractBuffer ab = (AbstractBuffer) obj;
+            if (ab._hash != 0 && _hash != ab._hash) 
+                return false;
+        }
+
+        // Nothing for it but to do the hard grind.
+        int get=getIndex();
+        int bi=b.putIndex();
+        for (int i = putIndex(); i-->get;)
+        {
+            byte b1 = _bytes[i];
+            byte b2 = b.peek(--bi);
+            if (b1 != b2) return false;
+        }
+        return true;
+    }
+
+
+    @Override
+    public boolean equalsIgnoreCase(Buffer b)
+    {
+        if (b==this)
+            return true;
+        
+        // reject different lengths
+        if (b==null || b.length() != length()) 
+            return false;
+
+        // reject AbstractBuffer with different hash value
+        if (_hash != 0 && b instanceof AbstractBuffer)
+        {
+            AbstractBuffer ab = (AbstractBuffer) b;
+            if (ab._hash != 0 && _hash != ab._hash) return false;
+        }
+
+        // Nothing for it but to do the hard grind.
+        int get=getIndex();
+        int bi=b.putIndex();
+        byte[] barray=b.array();
+        if (barray==null)
+        {
+            for (int i = putIndex(); i-->get;)
+            {
+                byte b1 = _bytes[i];
+                byte b2 = b.peek(--bi);
+                if (b1 != b2)
+                {
+                    if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
+                    if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
+                    if (b1 != b2) return false;
+                }
+            }
+        }
+        else
+        {
+            for (int i = putIndex(); i-->get;)
+            {
+                byte b1 = _bytes[i];
+                byte b2 = barray[--bi];
+                if (b1 != b2)
+                {
+                    if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A');
+                    if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A');
+                    if (b1 != b2) return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public byte get()
+    {
+        return _bytes[_get++];
+    }
+
+    @Override
+    public int hashCode()
+    {
+        if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) 
+        {
+            int get=getIndex();
+            for (int i = putIndex(); i-- >get;)
+            {
+                byte b = _bytes[i];
+                if ('a' <= b && b <= 'z') 
+                    b = (byte) (b - 'a' + 'A');
+                _hash = 31 * _hash + b;
+            }
+            if (_hash == 0) 
+                _hash = -1;
+            _hashGet=_get;
+            _hashPut=_put;
+        }
+        return _hash;
+    }
+    
+    
+    public byte peek(int index)
+    {
+        return _bytes[index];
+    }
+    
+    public int peek(int index, byte[] b, int offset, int length)
+    {
+        int l = length;
+        if (index + l > capacity())
+        {
+            l = capacity() - index;
+            if (l==0)
+                return -1;
+        }
+        
+        if (l < 0) 
+            return -1;
+        
+        System.arraycopy(_bytes, index, b, offset, l);
+        return l;
+    }
+
+    public void poke(int index, byte b)
+    {
+        /* 
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        
+        if (index < 0) 
+            throw new IllegalArgumentException("index<0: " + index + "<0");
+        if (index > capacity())
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+        */
+        _bytes[index] = b;
+    }
+    
+    @Override
+    public int poke(int index, Buffer src)
+    {
+        _hash=0;
+        
+        /* 
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        if (index < 0) 
+            throw new IllegalArgumentException("index<0: " + index + "<0");
+        */
+        
+        int length=src.length();
+        if (index + length > capacity())
+        {
+            length=capacity()-index;
+            /*
+            if (length<0)
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+            */
+        }
+        
+        byte[] src_array = src.array();
+        if (src_array != null)
+            System.arraycopy(src_array, src.getIndex(), _bytes, index, length);
+        else 
+        {
+            int s=src.getIndex();
+            for (int i=0;i<length;i++)
+                _bytes[index++]=src.peek(s++);
+        }
+        
+        return length;
+    }
+    
+
+    @Override
+    public int poke(int index, byte[] b, int offset, int length)
+    {
+        _hash=0;
+        /*
+        if (isReadOnly()) 
+            throw new IllegalStateException(__READONLY);
+        if (index < 0) 
+            throw new IllegalArgumentException("index<0: " + index + "<0");
+        */
+        
+        if (index + length > capacity())
+        {
+            length=capacity()-index;
+            /* if (length<0)
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+            */
+        }
+        
+        System.arraycopy(b, offset, _bytes, index, length);
+        
+        return length;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void writeTo(OutputStream out)
+        throws IOException
+    {
+        int len=length();
+        if (MAX_WRITE>0 && len>MAX_WRITE)
+        {
+            int off=getIndex();
+            while(len>0)
+            {
+                int c=len>MAX_WRITE?MAX_WRITE:len;
+                out.write(_bytes,off,c);
+                off+=c;
+                len-=c;
+            }
+        }
+        else
+            out.write(_bytes,getIndex(),len);
+        if (!isImmutable())
+            clear();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public int readFrom(InputStream in,int max) throws IOException
+    {
+        if (max<0||max>space())
+            max=space();
+        int p = putIndex();
+        
+        int len=0, total=0, available=max;
+        while (total<max) 
+        {
+            len=in.read(_bytes,p,available);
+            if (len<0)
+                break;
+            else if (len>0)
+            {
+                p += len;
+                total += len;
+                available -= len;
+                setPutIndex(p);
+            }
+            if (in.available()<=0)
+                break;
+        }
+        if (len<0 && total==0)
+            return -1;
+        return total;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int space()
+    {
+        return _bytes.length - _put;
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static class CaseInsensitive extends ByteArrayBuffer implements Buffer.CaseInsensitve
+    {
+        public CaseInsensitive(String s)
+        {
+            super(s);
+        }
+        
+        public CaseInsensitive(byte[] b, int o, int l, int rw)
+        {
+            super(b,o,l,rw);
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            return obj instanceof Buffer && equalsIgnoreCase((Buffer)obj);
+        }
+        
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/ByteArrayEndPoint.java b/src/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
new file mode 100644
index 0000000..49bdfda
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/ByteArrayEndPoint.java
@@ -0,0 +1,408 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+
+
+
+/* ------------------------------------------------------------ */
+/** ByteArrayEndPoint.
+ *
+ *
+ */
+public class ByteArrayEndPoint implements ConnectedEndPoint
+{
+    protected byte[] _inBytes;
+    protected ByteArrayBuffer _in;
+    protected ByteArrayBuffer _out;
+    protected boolean _closed;
+    protected boolean _nonBlocking;
+    protected boolean _growOutput;
+    protected Connection _connection;
+    protected int _maxIdleTime;
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public ByteArrayEndPoint()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.ConnectedEndPoint#getConnection()
+     */
+    public Connection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.ConnectedEndPoint#setConnection(org.eclipse.jetty.io.Connection)
+     */
+    public void setConnection(Connection connection)
+    {
+        _connection=connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the nonBlocking
+     */
+    public boolean isNonBlocking()
+    {
+        return _nonBlocking;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param nonBlocking the nonBlocking to set
+     */
+    public void setNonBlocking(boolean nonBlocking)
+    {
+        _nonBlocking=nonBlocking;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public ByteArrayEndPoint(byte[] input, int outputSize)
+    {
+        _inBytes=input;
+        _in=new ByteArrayBuffer(input);
+        _out=new ByteArrayBuffer(outputSize);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the in.
+     */
+    public ByteArrayBuffer getIn()
+    {
+        return _in;
+    }
+    /* ------------------------------------------------------------ */
+    /**
+     * @param in The in to set.
+     */
+    public void setIn(ByteArrayBuffer in)
+    {
+        _in = in;
+    }
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the out.
+     */
+    public ByteArrayBuffer getOut()
+    {
+        return _out;
+    }
+    /* ------------------------------------------------------------ */
+    /**
+     * @param out The out to set.
+     */
+    public void setOut(ByteArrayBuffer out)
+    {
+        _out = out;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#isOpen()
+     */
+    public boolean isOpen()
+    {
+        return !_closed;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     *  @see org.eclipse.jetty.io.EndPoint#isInputShutdown()
+     */
+    public boolean isInputShutdown()
+    {
+        return _closed;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     *  @see org.eclipse.jetty.io.EndPoint#isOutputShutdown()
+     */
+    public boolean isOutputShutdown()
+    {
+        return _closed;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#isBlocking()
+     */
+    public boolean isBlocking()
+    {
+        return !_nonBlocking;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean blockReadable(long millisecs)
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean blockWritable(long millisecs)
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#shutdownOutput()
+     */
+    public void shutdownOutput() throws IOException
+    {
+        close();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#shutdownInput()
+     */
+    public void shutdownInput() throws IOException
+    {
+        close();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void close() throws IOException
+    {
+        _closed=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
+     */
+    public int fill(Buffer buffer) throws IOException
+    {
+        if (_closed)
+            throw new IOException("CLOSED");
+
+        if (_in!=null && _in.length()>0)
+        {
+            int len = buffer.put(_in);
+            _in.skip(len);
+            return len;
+        }
+
+        if (_in!=null && _in.length()==0 && _nonBlocking)
+            return 0;
+
+        close();
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer buffer) throws IOException
+    {
+        if (_closed)
+            throw new IOException("CLOSED");
+        if (_growOutput && buffer.length()>_out.space())
+        {
+            _out.compact();
+
+            if (buffer.length()>_out.space())
+            {
+                ByteArrayBuffer n = new ByteArrayBuffer(_out.putIndex()+buffer.length());
+
+                n.put(_out.peek(0,_out.putIndex()));
+                if (_out.getIndex()>0)
+                {
+                    n.mark();
+                    n.setGetIndex(_out.getIndex());
+                }
+                _out=n;
+            }
+        }
+        int len = _out.put(buffer);
+        if (!buffer.isImmutable())
+            buffer.skip(len);
+        return len;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+    {
+        if (_closed)
+            throw new IOException("CLOSED");
+
+        int flushed=0;
+
+        if (header!=null && header.length()>0)
+            flushed=flush(header);
+
+        if (header==null || header.length()==0)
+        {
+            if (buffer!=null && buffer.length()>0)
+                flushed+=flush(buffer);
+
+            if (buffer==null || buffer.length()==0)
+            {
+                if (trailer!=null && trailer.length()>0)
+                {
+                    flushed+=flush(trailer);
+                }
+            }
+        }
+
+        return flushed;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public void reset()
+    {
+        _closed=false;
+        _in.clear();
+        _out.clear();
+        if (_inBytes!=null)
+            _in.setPutIndex(_inBytes.length);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalAddr()
+     */
+    public String getLocalAddr()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalHost()
+     */
+    public String getLocalHost()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalPort()
+     */
+    public int getLocalPort()
+    {
+        return 0;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteAddr()
+     */
+    public String getRemoteAddr()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteHost()
+     */
+    public String getRemoteHost()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemotePort()
+     */
+    public int getRemotePort()
+    {
+        return 0;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getConnection()
+     */
+    public Object getTransport()
+    {
+        return _inBytes;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void flush() throws IOException
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the growOutput
+     */
+    public boolean isGrowOutput()
+    {
+        return _growOutput;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param growOutput the growOutput to set
+     */
+    public void setGrowOutput(boolean growOutput)
+    {
+        _growOutput=growOutput;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.EndPoint#getMaxIdleTime()
+     */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.EndPoint#setMaxIdleTime(int)
+     */
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        _maxIdleTime=timeMs;
+    }
+
+
+}
diff --git a/src/java/org/eclipse/jetty/io/ConnectedEndPoint.java b/src/java/org/eclipse/jetty/io/ConnectedEndPoint.java
new file mode 100644
index 0000000..b3f9324
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/ConnectedEndPoint.java
@@ -0,0 +1,25 @@
+//
+//  ========================================================================
+//  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.io;
+
+public interface ConnectedEndPoint extends EndPoint
+{
+    Connection getConnection();
+    void setConnection(Connection connection);
+}
diff --git a/src/java/org/eclipse/jetty/io/Connection.java b/src/java/org/eclipse/jetty/io/Connection.java
new file mode 100644
index 0000000..b0c5349
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/Connection.java
@@ -0,0 +1,77 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+
+/* ------------------------------------------------------------ */
+/** Abstract Connection used by Jetty Connectors.
+ * <p>
+ * Jetty will call the handle method of a connection when there is work
+ * to be done on the connection.  For blocking connections, this is soon
+ * as the connection is open and handle will keep being called until the
+ * connection is closed.   For non-blocking connections, handle will only
+ * be called if there are bytes to be read or the connection becomes writable
+ * after being write blocked.
+ *
+ * @see org.eclipse.jetty.io.nio.SelectorManager
+ */
+public interface Connection
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * Handle the connection.
+     * @return The Connection to use for the next handling of the connection.
+     * This allows protocol upgrades and support for CONNECT.
+     * @throws IOException if the handling of I/O operations fail
+     */
+    Connection handle() throws IOException;
+
+    /**
+     * @return the timestamp at which the connection was created
+     */
+    long getTimeStamp();
+
+    /**
+     * @return whether this connection is idle, that is not parsing and not generating
+     * @see #onIdleExpired(long)
+     */
+    boolean isIdle();
+
+    /**
+     * <p>The semantic of this method is to return true to indicate interest in further reads,
+     * or false otherwise, but it is misnamed and should be really called <code>isReadInterested()</code>.</p>
+     *
+     * @return true to indicate interest in further reads, false otherwise
+     */
+    // TODO: rename to isReadInterested() in the next release
+    boolean isSuspended();
+
+    /**
+     * Called after the connection is closed
+     */
+    void onClose();
+
+    /**
+     * Called when the connection idle timeout expires
+     * @param idleForMs how long the connection has been idle
+     * @see #isIdle()
+     */
+    void onIdleExpired(long idleForMs);
+}
diff --git a/src/java/org/eclipse/jetty/io/EndPoint.java b/src/java/org/eclipse/jetty/io/EndPoint.java
new file mode 100644
index 0000000..c264587
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/EndPoint.java
@@ -0,0 +1,175 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+
+
+/**
+ *
+ * A transport EndPoint
+ */
+public interface EndPoint
+{
+    /**
+     * Shutdown any backing output stream associated with the endpoint
+     */
+    void shutdownOutput() throws IOException;
+
+    boolean isOutputShutdown();
+
+    /**
+     * Shutdown any backing input stream associated with the endpoint
+     */
+    void shutdownInput() throws IOException;
+
+    boolean isInputShutdown();
+
+    /**
+     * Close any backing stream associated with the endpoint
+     */
+    void close() throws IOException;
+
+    /**
+     * Fill the buffer from the current putIndex to it's capacity from whatever
+     * byte source is backing the buffer. The putIndex is increased if bytes filled.
+     * The buffer may chose to do a compact before filling.
+     * @return an <code>int</code> value indicating the number of bytes
+     * filled or -1 if EOF is reached.
+     * @throws EofException If input is shutdown or the endpoint is closed.
+     */
+    int fill(Buffer buffer) throws IOException;
+
+
+    /**
+     * Flush the buffer from the current getIndex to it's putIndex using whatever byte
+     * sink is backing the buffer. The getIndex is updated with the number of bytes flushed.
+     * Any mark set is cleared.
+     * If the entire contents of the buffer are flushed, then an implicit empty() is done.
+     *
+     * @param buffer The buffer to flush. This buffers getIndex is updated.
+     * @return  the number of bytes written
+     * @throws EofException If the endpoint is closed or output is shutdown.
+     */
+    int flush(Buffer buffer) throws IOException;
+
+    /**
+     * Flush the buffer from the current getIndex to it's putIndex using whatever byte
+     * sink is backing the buffer. The getIndex is updated with the number of bytes flushed.
+     * Any mark set is cleared.
+     * If the entire contents of the buffer are flushed, then an implicit empty() is done.
+     * The passed header/trailer buffers are written before/after the contents of this buffer. This may be done
+     * either as gather writes, as a poke into this buffer or as several writes. The implementation is free to
+     * select the optimal mechanism.
+     * @param header A buffer to write before flushing this buffer. This buffers getIndex is updated.
+     * @param buffer The buffer to flush. This buffers getIndex is updated.
+     * @param trailer A buffer to write after flushing this buffer. This buffers getIndex is updated.
+     * @return the total number of bytes written.
+     */
+    int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException;
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The local IP address to which this <code>EndPoint</code> is bound, or <code>null</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public String getLocalAddr();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The local host name to which this <code>EndPoint</code> is bound, or <code>null</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public String getLocalHost();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The local port number on which this <code>EndPoint</code> is listening, or <code>0</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public int getLocalPort();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The remote IP address to which this <code>EndPoint</code> is connected, or <code>null</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public String getRemoteAddr();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The host name of the remote machine to which this <code>EndPoint</code> is connected, or <code>null</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public String getRemoteHost();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The remote port number to which this <code>EndPoint</code> is connected, or <code>0</code>
+     * if this <code>EndPoint</code> does not represent a network connection.
+     */
+    public int getRemotePort();
+
+    /* ------------------------------------------------------------ */
+    public boolean isBlocking();
+
+    /* ------------------------------------------------------------ */
+    public boolean blockReadable(long millisecs) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    public boolean blockWritable(long millisecs) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    public boolean isOpen();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The underlying transport object (socket, channel, etc.)
+     */
+    public Object getTransport();
+
+    /* ------------------------------------------------------------ */
+    /** Flush any buffered output.
+     * May fail to write all data if endpoint is non-blocking
+     * @throws EofException If the endpoint is closed or output is shutdown.
+     */
+    public void flush() throws IOException;
+
+    /* ------------------------------------------------------------ */
+    /** Get the max idle time in ms.
+     * <p>The max idle time is the time the endpoint can be idle before
+     * extraordinary handling takes place.  This loosely corresponds to
+     * the {@link java.net.Socket#getSoTimeout()} for blocking connections,
+     * but {@link AsyncEndPoint} implementations must use other mechanisms
+     * to implement the max idle time.
+     * @return the max idle time in ms or if ms <= 0 implies an infinite timeout
+     */
+    public int getMaxIdleTime();
+
+    /* ------------------------------------------------------------ */
+    /** Set the max idle time.
+     * @param timeMs the max idle time in MS. Timeout <= 0 implies an infinite timeout
+     * @throws IOException if the timeout cannot be set.
+     */
+    public void setMaxIdleTime(int timeMs) throws IOException;
+
+
+
+}
diff --git a/src/java/org/eclipse/jetty/io/EofException.java b/src/java/org/eclipse/jetty/io/EofException.java
new file mode 100644
index 0000000..72042f4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/EofException.java
@@ -0,0 +1,46 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.EOFException;
+
+
+/* ------------------------------------------------------------ */
+/** A Jetty specialization of EOFException.
+ * <p> This is thrown by Jetty to distinguish between EOF received from 
+ * the connection, vs and EOF thrown by some application talking to some other file/socket etc.
+ * The only difference in handling is that Jetty EOFs are logged less verbosely.
+ */
+public class EofException extends EOFException
+{
+    public EofException()
+    {
+    }
+    
+    public EofException(String reason)
+    {
+        super(reason);
+    }
+    
+    public EofException(Throwable th)
+    {
+        if (th!=null)
+            initCause(th);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/NetworkTrafficListener.java b/src/java/org/eclipse/jetty/io/NetworkTrafficListener.java
new file mode 100644
index 0000000..200574d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/NetworkTrafficListener.java
@@ -0,0 +1,99 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.net.Socket;
+
+/**
+ * <p>A listener for raw network traffic within Jetty.</p>
+ * <p>{@link NetworkTrafficListener}s can be installed in a
+ * <code>org.eclipse.jetty.server.nio.NetworkTrafficSelectChannelConnector</code>,
+ * and are notified of the following network traffic events:</p>
+ * <ul>
+ * <li>Connection opened, when the server has accepted the connection from a remote client</li>
+ * <li>Incoming bytes, when the server receives bytes sent from a remote client</li>
+ * <li>Outgoing bytes, when the server sends bytes to a remote client</li>
+ * <li>Connection closed, when the server has closed the connection to a remote client</li>
+ * </ul>
+ * <p>{@link NetworkTrafficListener}s can be used to log the network traffic viewed by
+ * a Jetty server (for example logging to filesystem) for activities such as debugging
+ * or request/response cycles or for replaying request/response cycles to other servers.</p>
+ */
+public interface NetworkTrafficListener
+{
+    /**
+     * <p>Callback method invoked when a connection from a remote client has been accepted.</p>
+     * <p>The {@code socket} parameter can be used to extract socket address information of
+     * the remote client.</p>
+     *
+     * @param socket the socket associated with the remote client
+     */
+    public void opened(Socket socket);
+
+    /**
+     * <p>Callback method invoked when bytes sent by a remote client arrived on the server.</p>
+     *
+     * @param socket the socket associated with the remote client
+     * @param bytes  the read-only buffer containing the incoming bytes
+     */
+    public void incoming(Socket socket, Buffer bytes);
+
+    /**
+     * <p>Callback method invoked when bytes are sent to a remote client from the server.</p>
+     * <p>This method is invoked after the bytes have been actually written to the remote client.</p>
+     *
+     * @param socket the socket associated with the remote client
+     * @param bytes  the read-only buffer containing the outgoing bytes
+     */
+    public void outgoing(Socket socket, Buffer bytes);
+
+    /**
+     * <p>Callback method invoked when a connection to a remote client has been closed.</p>
+     * <p>The {@code socket} parameter is already closed when this method is called, so it
+     * cannot be queried for socket address information of the remote client.<br />
+     * However, the {@code socket} parameter is the same object passed to {@link #opened(Socket)},
+     * so it is possible to map socket information in {@link #opened(Socket)} and retrieve it
+     * in this method.
+     *
+     * @param socket the (closed) socket associated with the remote client
+     */
+    public void closed(Socket socket);
+
+    /**
+     * <p>A commodity class that implements {@link NetworkTrafficListener} with empty methods.</p>
+     */
+    public static class Empty implements NetworkTrafficListener
+    {
+        public void opened(Socket socket)
+        {
+        }
+
+        public void incoming(Socket socket, Buffer bytes)
+        {
+        }
+
+        public void outgoing(Socket socket, Buffer bytes)
+        {
+        }
+
+        public void closed(Socket socket)
+        {
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/PooledBuffers.java b/src/java/org/eclipse/jetty/io/PooledBuffers.java
new file mode 100644
index 0000000..590b026
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/PooledBuffers.java
@@ -0,0 +1,122 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class PooledBuffers extends AbstractBuffers
+{
+    private final Queue<Buffer> _headers;
+    private final Queue<Buffer> _buffers;
+    private final Queue<Buffer> _others;
+    private final AtomicInteger _size = new AtomicInteger();
+    private final int _maxSize;
+    private final boolean _otherHeaders;
+    private final boolean _otherBuffers;
+
+    /* ------------------------------------------------------------ */
+    public PooledBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType,int maxSize)
+    {
+        super(headerType,headerSize,bufferType,bufferSize,otherType);
+        _headers=new ConcurrentLinkedQueue<Buffer>();
+        _buffers=new ConcurrentLinkedQueue<Buffer>();
+        _others=new ConcurrentLinkedQueue<Buffer>();
+        _otherHeaders=headerType==otherType;
+        _otherBuffers=bufferType==otherType;
+        _maxSize=maxSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getHeader()
+    {
+        Buffer buffer = _headers.poll();
+        if (buffer==null)
+            buffer=newHeader();
+        else
+            _size.decrementAndGet();
+        return buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        Buffer buffer = _buffers.poll();
+        if (buffer==null)
+            buffer=newBuffer();
+        else
+            _size.decrementAndGet();
+        return buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer(int size)
+    {
+        if (_otherHeaders && size==getHeaderSize())
+            return getHeader();
+        if (_otherBuffers && size==getBufferSize())
+            return getBuffer();
+
+        // Look for an other buffer
+        Buffer buffer = _others.poll();
+
+        // consume all other buffers until one of the right size is found
+        while (buffer!=null && buffer.capacity()!=size)
+        {
+            _size.decrementAndGet();
+            buffer = _others.poll();
+        }
+
+        if (buffer==null)
+            buffer=newBuffer(size);
+        else
+            _size.decrementAndGet();
+        return buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void returnBuffer(Buffer buffer)
+    {
+        buffer.clear();
+        if (buffer.isVolatile() || buffer.isImmutable())
+            return;
+
+        if (_size.incrementAndGet() > _maxSize)
+            _size.decrementAndGet();
+        else
+        {
+            if (isHeader(buffer))
+                _headers.add(buffer);
+            else if (isBuffer(buffer))
+                _buffers.add(buffer);
+            else
+                _others.add(buffer);
+        }
+    }
+
+    public String toString()
+    {
+        return String.format("%s [%d/%d@%d,%d/%d@%d,%d/%d@-]",
+                getClass().getSimpleName(),
+                _headers.size(),_maxSize,_headerSize,
+                _buffers.size(),_maxSize,_bufferSize,
+                _others.size(),_maxSize);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/RuntimeIOException.java b/src/java/org/eclipse/jetty/io/RuntimeIOException.java
new file mode 100644
index 0000000..88c33f7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/RuntimeIOException.java
@@ -0,0 +1,48 @@
+//
+//  ========================================================================
+//  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.io;
+
+/* ------------------------------------------------------------ */
+/**
+ * Subclass of {@link java.lang.RuntimeException} used to signal that there
+ * was an {@link java.io.IOException} thrown by underlying {@link java.io.Writer}
+ */
+public class RuntimeIOException extends RuntimeException
+{
+    public RuntimeIOException()
+    {
+        super();
+    }
+
+    public RuntimeIOException(String message)
+    {
+        super(message);
+    }
+
+    public RuntimeIOException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    public RuntimeIOException(String message, Throwable cause)
+    {
+        super(message,cause);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/SimpleBuffers.java b/src/java/org/eclipse/jetty/io/SimpleBuffers.java
new file mode 100644
index 0000000..6371c04
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/SimpleBuffers.java
@@ -0,0 +1,117 @@
+//
+//  ========================================================================
+//  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.io;
+
+/* ------------------------------------------------------------ */
+/** SimpleBuffers.
+ * Simple implementation of Buffers holder.
+ * 
+ *
+ */
+public class SimpleBuffers implements Buffers
+{   
+    final Buffer _header;
+    final Buffer _buffer;
+    boolean _headerOut;
+    boolean _bufferOut;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     */
+    public SimpleBuffers(Buffer header, Buffer buffer)
+    {
+        _header=header;
+        _buffer=buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        synchronized(this)
+        {
+            if (_buffer!=null && !_bufferOut)
+            {
+                _bufferOut=true;
+                return _buffer;
+            }
+            
+            if (_buffer!=null && _header!=null && _header.capacity()==_buffer.capacity() && !_headerOut)
+            {
+                _headerOut=true;
+                return _header;
+            }
+            
+            if (_buffer!=null)
+                return new ByteArrayBuffer(_buffer.capacity());
+            return new ByteArrayBuffer(4096);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getHeader()
+    {
+        synchronized(this)
+        {
+            if (_header!=null && !_headerOut)
+            {
+                _headerOut=true;
+                return _header;
+            }
+            
+            if (_buffer!=null && _header!=null && _header.capacity()==_buffer.capacity() && !_bufferOut)
+            {
+                _bufferOut=true;
+                return _buffer;
+            }
+            
+            if (_header!=null)
+                return new ByteArrayBuffer(_header.capacity());
+            return new ByteArrayBuffer(4096);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer(int size)
+    {
+        synchronized(this)
+        {
+            if (_header!=null && _header.capacity()==size)
+                return getHeader();
+            if (_buffer!=null && _buffer.capacity()==size)
+                return getBuffer();
+            return null;            
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void returnBuffer(Buffer buffer)
+    {
+        synchronized(this)
+        {
+            buffer.clear();
+            if (buffer==_header)
+                _headerOut=false;
+            if (buffer==_buffer)
+                _bufferOut=false;
+        }
+    }
+
+
+}
diff --git a/src/java/org/eclipse/jetty/io/ThreadLocalBuffers.java b/src/java/org/eclipse/jetty/io/ThreadLocalBuffers.java
new file mode 100644
index 0000000..065193c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/ThreadLocalBuffers.java
@@ -0,0 +1,135 @@
+//
+//  ========================================================================
+//  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.io;
+
+
+
+/* ------------------------------------------------------------ */
+/** Abstract Buffer pool.
+ * simple unbounded pool of buffers for header, request and response sizes.
+ *
+ */
+public class ThreadLocalBuffers extends AbstractBuffers 
+{
+    /* ------------------------------------------------------------ */
+    private final ThreadLocal<ThreadBuffers> _buffers=new ThreadLocal<ThreadBuffers>()
+    {
+        @Override
+        protected ThreadBuffers initialValue()
+        {
+            return new ThreadBuffers();
+        }
+    };
+
+    /* ------------------------------------------------------------ */
+    public ThreadLocalBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType)
+    {
+        super(headerType,headerSize,bufferType,bufferSize,otherType);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        ThreadBuffers buffers = _buffers.get();
+        if (buffers._buffer!=null)
+        {
+            Buffer b=buffers._buffer;
+            buffers._buffer=null;
+            return b;
+        }
+
+        if (buffers._other!=null && isBuffer(buffers._other))
+        {
+            Buffer b=buffers._other;
+            buffers._other=null;
+            return b;
+        }
+
+        return newBuffer();
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getHeader()
+    {
+        ThreadBuffers buffers = _buffers.get();
+        if (buffers._header!=null)
+        {
+            Buffer b=buffers._header;
+            buffers._header=null;
+            return b;
+        }
+
+        if (buffers._other!=null && isHeader(buffers._other))
+        {
+            Buffer b=buffers._other;
+            buffers._other=null;
+            return b;
+        }
+
+        return newHeader();
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer(int size)
+    {
+        ThreadBuffers buffers = _buffers.get();
+        if (buffers._other!=null && buffers._other.capacity()==size)
+        {
+            Buffer b=buffers._other;
+            buffers._other=null;
+            return b;
+        }
+
+        return newBuffer(size);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void returnBuffer(Buffer buffer)
+    {
+        buffer.clear();
+        if (buffer.isVolatile() || buffer.isImmutable())
+            return;
+        
+        ThreadBuffers buffers = _buffers.get();
+        
+        if (buffers._header==null && isHeader(buffer))
+            buffers._header=buffer;
+        else if (buffers._buffer==null && isBuffer(buffer))
+            buffers._buffer=buffer;
+        else
+            buffers._other=buffer;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return "{{"+getHeaderSize()+","+getBufferSize()+"}}";
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected static class ThreadBuffers
+    {
+        Buffer _buffer;
+        Buffer _header;
+        Buffer _other;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/UncheckedIOException.java b/src/java/org/eclipse/jetty/io/UncheckedIOException.java
new file mode 100644
index 0000000..0d8e791
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/UncheckedIOException.java
@@ -0,0 +1,48 @@
+//
+//  ========================================================================
+//  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.io;
+
+/* ------------------------------------------------------------ */
+/**
+ * Subclass of {@link java.lang.RuntimeException} used to signal that there
+ * was an {@link java.io.IOException} thrown by underlying {@link UncheckedPrintWriter}
+ */
+public class UncheckedIOException extends RuntimeException
+{
+    public UncheckedIOException()
+    {
+        super();
+    }
+
+    public UncheckedIOException(String message)
+    {
+        super(message);
+    }
+
+    public UncheckedIOException(Throwable cause)
+    {
+        super(cause);
+    }
+
+    public UncheckedIOException(String message, Throwable cause)
+    {
+        super(message,cause);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/UncheckedPrintWriter.java b/src/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
new file mode 100644
index 0000000..6898ddf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/UncheckedPrintWriter.java
@@ -0,0 +1,682 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * A wrapper for the {@link java.io.PrintWriter} that re-throws the instances of
+ * {@link java.io.IOException} thrown by the underlying implementation of
+ * {@link java.io.Writer} as {@link RuntimeIOException} instances.
+ */
+public class UncheckedPrintWriter extends PrintWriter
+{
+    private static final Logger LOG = Log.getLogger(UncheckedPrintWriter.class);
+
+    private boolean _autoFlush = false;
+    private IOException _ioException;
+    private boolean _isClosed = false;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Line separator string. This is the value of the line.separator property
+     * at the moment that the stream was created.
+     */
+    private String _lineSeparator;
+
+    public UncheckedPrintWriter(Writer out)
+    {
+        this(out,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new PrintWriter.
+     * 
+     * @param out
+     *            A character-output stream
+     * @param autoFlush
+     *            A boolean; if true, the println() methods will flush the
+     *            output buffer
+     */
+    public UncheckedPrintWriter(Writer out, boolean autoFlush)
+    {
+        super(out,autoFlush);
+        this._autoFlush = autoFlush;
+        this._lineSeparator = System.getProperty("line.separator");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new PrintWriter, without automatic line flushing, from an
+     * existing OutputStream. This convenience constructor creates the necessary
+     * intermediate OutputStreamWriter, which will convert characters into bytes
+     * using the default character encoding.
+     * 
+     * @param out
+     *            An output stream
+     * 
+     * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+     */
+    public UncheckedPrintWriter(OutputStream out)
+    {
+        this(out,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new PrintWriter from an existing OutputStream. This convenience
+     * constructor creates the necessary intermediate OutputStreamWriter, which
+     * will convert characters into bytes using the default character encoding.
+     * 
+     * @param out
+     *            An output stream
+     * @param autoFlush
+     *            A boolean; if true, the println() methods will flush the
+     *            output buffer
+     * 
+     * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+     */
+    public UncheckedPrintWriter(OutputStream out, boolean autoFlush)
+    {
+        this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public boolean checkError()
+    {
+        return _ioException!=null || super.checkError();
+    }
+    
+    /* ------------------------------------------------------------ */
+    private void setError(Throwable th)
+    {
+      
+        super.setError();
+
+        if (th instanceof IOException)
+            _ioException=(IOException)th;
+        else
+        {
+            _ioException=new IOException(String.valueOf(th));
+            _ioException.initCause(th);
+        }
+
+        LOG.debug(th);
+    }
+
+
+    @Override
+    protected void setError()
+    {
+        setError(new IOException());
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Check to make sure that the stream has not been closed */
+    private void isOpen() throws IOException
+    {       
+        if (_ioException!=null)
+            throw new RuntimeIOException(_ioException); 
+        
+        if (_isClosed)
+            throw new IOException("Stream closed");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Flush the stream.
+     */
+    @Override
+    public void flush()
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                isOpen();
+                out.flush();
+            }
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Close the stream.
+     */
+    @Override
+    public void close()
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                out.close();
+                _isClosed = true;
+            }
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Write a single character.
+     * 
+     * @param c
+     *            int specifying a character to be written.
+     */
+    @Override
+    public void write(int c)
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                isOpen();
+                out.write(c);
+            }
+        }
+        catch (InterruptedIOException x)
+        {
+            Thread.currentThread().interrupt();
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Write a portion of an array of characters.
+     * 
+     * @param buf
+     *            Array of characters
+     * @param off
+     *            Offset from which to start writing characters
+     * @param len
+     *            Number of characters to write
+     */
+    @Override
+    public void write(char buf[], int off, int len)
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                isOpen();
+                out.write(buf,off,len);
+            }
+        }
+        catch (InterruptedIOException x)
+        {
+            Thread.currentThread().interrupt();
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Write an array of characters. This method cannot be inherited from the
+     * Writer class because it must suppress I/O exceptions.
+     * 
+     * @param buf
+     *            Array of characters to be written
+     */
+    @Override
+    public void write(char buf[])
+    { 
+        this.write(buf,0,buf.length);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Write a portion of a string.
+     * 
+     * @param s
+     *            A String
+     * @param off
+     *            Offset from which to start writing characters
+     * @param len
+     *            Number of characters to write
+     */
+    @Override
+    public void write(String s, int off, int len)
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                isOpen();
+                out.write(s,off,len);
+            }
+        }
+        catch (InterruptedIOException x)
+        {
+            Thread.currentThread().interrupt();
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Write a string. This method cannot be inherited from the Writer class
+     * because it must suppress I/O exceptions.
+     * 
+     * @param s
+     *            String to be written
+     */
+    @Override
+    public void write(String s)
+    {
+        this.write(s,0,s.length());
+    }
+
+    private void newLine()
+    {
+        try
+        {
+            synchronized (lock)
+            {
+                isOpen();
+                out.write(_lineSeparator);
+                if (_autoFlush)
+                    out.flush();
+            }
+        }
+        catch (InterruptedIOException x)
+        {
+            Thread.currentThread().interrupt();
+        }
+        catch (IOException ex)
+        {
+            setError(ex);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a boolean value. The string produced by <code>{@link
+     * java.lang.String#valueOf(boolean)}</code> is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     * 
+     * @param b
+     *            The <code>boolean</code> to be printed
+     */
+    @Override
+    public void print(boolean b)
+    {
+        this.write(b?"true":"false");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a character. The character is translated into one or more bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     * 
+     * @param c
+     *            The <code>char</code> to be printed
+     */
+    @Override
+    public void print(char c)
+    {
+        this.write(c);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an integer. The string produced by <code>{@link
+     * java.lang.String#valueOf(int)}</code> is translated into bytes according
+     * to the platform's default character encoding, and these bytes are written
+     * in exactly the manner of the <code>{@link #write(int)}</code> method.
+     * 
+     * @param i
+     *            The <code>int</code> to be printed
+     * @see java.lang.Integer#toString(int)
+     */
+    @Override
+    public void print(int i)
+    {
+        this.write(String.valueOf(i));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a long integer. The string produced by <code>{@link
+     * java.lang.String#valueOf(long)}</code> is translated into bytes according
+     * to the platform's default character encoding, and these bytes are written
+     * in exactly the manner of the <code>{@link #write(int)}</code> method.
+     * 
+     * @param l
+     *            The <code>long</code> to be printed
+     * @see java.lang.Long#toString(long)
+     */
+    @Override
+    public void print(long l)
+    {
+        this.write(String.valueOf(l));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a floating-point number. The string produced by <code>{@link
+     * java.lang.String#valueOf(float)}</code> is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link #write(int)}</code>
+     * method.
+     * 
+     * @param f
+     *            The <code>float</code> to be printed
+     * @see java.lang.Float#toString(float)
+     */
+    @Override
+    public void print(float f)
+    {
+        this.write(String.valueOf(f));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a double-precision floating-point number. The string produced by
+     * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
+     * bytes according to the platform's default character encoding, and these
+     * bytes are written in exactly the manner of the <code>{@link
+     * #write(int)}</code> method.
+     * 
+     * @param d
+     *            The <code>double</code> to be printed
+     * @see java.lang.Double#toString(double)
+     */
+    @Override
+    public void print(double d)
+    {
+        this.write(String.valueOf(d));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an array of characters. The characters are converted into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link #write(int)}</code>
+     * method.
+     * 
+     * @param s
+     *            The array of chars to be printed
+     * 
+     * @throws NullPointerException
+     *             If <code>s</code> is <code>null</code>
+     */
+    @Override
+    public void print(char s[])
+    {
+        this.write(s);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a string. If the argument is <code>null</code> then the string
+     * <code>"null"</code> is printed. Otherwise, the string's characters are
+     * converted into bytes according to the platform's default character
+     * encoding, and these bytes are written in exactly the manner of the
+     * <code>{@link #write(int)}</code> method.
+     * 
+     * @param s
+     *            The <code>String</code> to be printed
+     */
+    @Override
+    public void print(String s)
+    {
+        if (s == null)
+        {
+            s = "null";
+        }
+        this.write(s);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an object. The string produced by the <code>{@link
+     * java.lang.String#valueOf(Object)}</code> method is translated into bytes
+     * according to the platform's default character encoding, and these bytes
+     * are written in exactly the manner of the <code>{@link #write(int)}</code>
+     * method.
+     * 
+     * @param obj
+     *            The <code>Object</code> to be printed
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public void print(Object obj)
+    {
+        this.write(String.valueOf(obj));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Terminate the current line by writing the line separator string. The line
+     * separator string is defined by the system property
+     * <code>line.separator</code>, and is not necessarily a single newline
+     * character (<code>'\n'</code>).
+     */
+    @Override
+    public void println()
+    {
+        this.newLine();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a boolean value and then terminate the line. This method behaves as
+     * though it invokes <code>{@link #print(boolean)}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>boolean</code> value to be printed
+     */
+    @Override
+    public void println(boolean x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a character and then terminate the line. This method behaves as
+     * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
+     * #println()}</code>.
+     * 
+     * @param x
+     *            the <code>char</code> value to be printed
+     */
+    @Override
+    public void println(char x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an integer and then terminate the line. This method behaves as
+     * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
+     * #println()}</code>.
+     * 
+     * @param x
+     *            the <code>int</code> value to be printed
+     */
+    @Override
+    public void println(int x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a long integer and then terminate the line. This method behaves as
+     * though it invokes <code>{@link #print(long)}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>long</code> value to be printed
+     */
+    @Override
+    public void println(long x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a floating-point number and then terminate the line. This method
+     * behaves as though it invokes <code>{@link #print(float)}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>float</code> value to be printed
+     */
+    @Override
+    public void println(float x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a double-precision floating-point number and then terminate the
+     * line. This method behaves as though it invokes <code>{@link
+     * #print(double)}</code> and then <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>double</code> value to be printed
+     */
+    /* ------------------------------------------------------------ */
+    @Override
+    public void println(double x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an array of characters and then terminate the line. This method
+     * behaves as though it invokes <code>{@link #print(char[])}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the array of <code>char</code> values to be printed
+     */
+    @Override
+    public void println(char x[])
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print a String and then terminate the line. This method behaves as though
+     * it invokes <code>{@link #print(String)}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>String</code> value to be printed
+     */
+    @Override
+    public void println(String x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Print an Object and then terminate the line. This method behaves as
+     * though it invokes <code>{@link #print(Object)}</code> and then
+     * <code>{@link #println()}</code>.
+     * 
+     * @param x
+     *            the <code>Object</code> value to be printed
+     */
+    @Override
+    public void println(Object x)
+    {
+        synchronized (lock)
+        {
+            this.print(x);
+            this.println();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/View.java b/src/java/org/eclipse/jetty/io/View.java
new file mode 100644
index 0000000..47a1b57
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/View.java
@@ -0,0 +1,251 @@
+//
+//  ========================================================================
+//  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.io;
+
+/**
+ * A View on another buffer.  Allows operations that do not change the _content or
+ * indexes of the backing buffer.
+ * 
+ * 
+ * 
+ */
+public class View extends AbstractBuffer
+{
+    Buffer _buffer;
+
+    /**
+     * @param buffer The <code>Buffer</code> on which we are presenting a <code>View</code>.
+     * @param mark The initial value of the {@link Buffer#markIndex mark index}
+     * @param get The initial value of the {@link Buffer#getIndex get index}
+     * @param put The initial value of the {@link Buffer#putIndex put index}
+     * @param access The access level - one of the constants from {@link Buffer}.
+     */
+    public View(Buffer buffer, int mark, int get, int put,int access)
+    {
+        super(READWRITE,!buffer.isImmutable());
+        _buffer=buffer.buffer();
+        setPutIndex(put);
+        setGetIndex(get);
+        setMarkIndex(mark);
+        _access=access;
+    }
+    
+    public View(Buffer buffer)
+    {
+        super(READWRITE,!buffer.isImmutable());
+        _buffer=buffer.buffer();
+        setPutIndex(buffer.putIndex());
+        setGetIndex(buffer.getIndex());
+        setMarkIndex(buffer.markIndex());
+        _access=buffer.isReadOnly()?READONLY:READWRITE;
+    }
+
+    public View()
+    {
+        super(READWRITE,true);
+    }
+    
+    /**
+     * Update view to buffer
+     */
+    public void update(Buffer buffer)
+    {
+        _access=READWRITE;
+        _buffer=buffer.buffer();
+        setGetIndex(0);
+        setPutIndex(buffer.putIndex());
+        setGetIndex(buffer.getIndex());
+        setMarkIndex(buffer.markIndex());
+        _access=buffer.isReadOnly()?READONLY:READWRITE;
+    }
+
+    public void update(int get, int put)
+    {
+        int a=_access;
+        _access=READWRITE;
+        setGetIndex(0);
+        setPutIndex(put);
+        setGetIndex(get);
+        setMarkIndex(-1);
+        _access=a;
+    }
+
+    /**
+     * @return The {@link Buffer#array()} from the underlying buffer.
+     */
+    public byte[] array()
+    {
+        return _buffer.array();
+    }
+
+    /**
+     * @return The {@link Buffer#buffer()} from the underlying buffer.
+     */
+    @Override
+    public Buffer buffer()
+    {
+        return _buffer.buffer();
+    }
+
+    /**
+     * @return The {@link Buffer#capacity} of the underlying buffer.
+     */
+    public int capacity()
+    {
+        return _buffer.capacity();
+    }
+
+    /**
+     *  
+     */
+    @Override
+    public void clear()
+    {
+        setMarkIndex(-1);
+        setGetIndex(0);
+        setPutIndex(_buffer.getIndex());
+        setGetIndex(_buffer.getIndex());
+    }
+
+    /**
+     *  
+     */
+    @Override
+    public void compact()
+    {
+        // TODO
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj)
+    {
+        return  this==obj ||((obj instanceof Buffer)&& obj.equals(this)) || super.equals(obj);
+    }
+
+    /**
+     * @return Whether the underlying buffer is {@link Buffer#isReadOnly read only}
+     */
+    @Override
+    public boolean isReadOnly()
+    {
+        return _buffer.isReadOnly();
+    }
+
+    /**
+     * @return Whether the underlying buffer is {@link Buffer#isVolatile volatile}
+     */
+    @Override
+    public boolean isVolatile()
+    {
+        return true;
+    }
+
+    /**
+     * @return The result of calling {@link Buffer#peek(int)} on the underlying buffer
+     */
+    public byte peek(int index)
+    {
+        return _buffer.peek(index);
+    }
+
+    /**
+     * @return The result of calling {@link Buffer#peek(int, byte[], int, int)} on the underlying buffer
+     */
+    public int peek(int index, byte[] b, int offset, int length)
+    {
+        return _buffer.peek(index,b,offset,length);
+    }
+
+    /**
+     * @return The result of calling {@link Buffer#peek(int, int)} on the underlying buffer
+     */
+    @Override
+    public Buffer peek(int index, int length)
+    {
+        return _buffer.peek(index, length);
+    }
+    
+    /**
+     * @param index
+     * @param src
+     */
+    @Override
+    public int poke(int index, Buffer src)
+    {
+        return _buffer.poke(index,src); 
+    }
+
+    /**
+     * @param index
+     * @param b
+     */
+    public void poke(int index, byte b)
+    {
+        _buffer.poke(index,b);
+    }
+
+    /**
+     * @param index
+     * @param b
+     * @param offset
+     * @param length
+     */
+    @Override
+    public int poke(int index, byte[] b, int offset, int length)
+    {
+        return _buffer.poke(index,b,offset,length);
+    }
+    
+    @Override
+    public String toString()
+    {
+        if (_buffer==null)
+            return "INVALID";
+        return super.toString();
+    }
+    
+    public static class CaseInsensitive extends View implements Buffer.CaseInsensitve
+    {
+        public CaseInsensitive()
+        {
+            super();
+        }
+
+        public CaseInsensitive(Buffer buffer, int mark, int get, int put, int access)
+        {
+            super(buffer,mark,get,put,access);
+        }
+
+        public CaseInsensitive(Buffer buffer)
+        {
+            super(buffer);
+        }
+        
+        @Override
+        public boolean equals(Object obj)
+        {
+            return  this==obj ||((obj instanceof Buffer)&&((Buffer)obj).equalsIgnoreCase(this)) || super.equals(obj);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/WriterOutputStream.java b/src/java/org/eclipse/jetty/io/WriterOutputStream.java
new file mode 100644
index 0000000..620bbf8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/WriterOutputStream.java
@@ -0,0 +1,100 @@
+//
+//  ========================================================================
+//  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.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+
+/* ------------------------------------------------------------ */
+/** Wrap a Writer as an OutputStream.
+ * When all you have is a Writer and only an OutputStream will do.
+ * Try not to use this as it indicates that your design is a dogs
+ * breakfast (JSP made me write it).
+ * 
+ */
+public class WriterOutputStream extends OutputStream
+{
+    protected final Writer _writer;
+    protected final String _encoding;
+    private final byte[] _buf=new byte[1];
+    
+    /* ------------------------------------------------------------ */
+    public WriterOutputStream(Writer writer, String encoding)
+    {
+        _writer=writer;
+        _encoding=encoding;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public WriterOutputStream(Writer writer)
+    {
+        _writer=writer;
+        _encoding=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void close()
+        throws IOException
+    {
+        _writer.close();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void flush()
+        throws IOException
+    {
+        _writer.flush();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(byte[] b) 
+        throws IOException
+    {
+        if (_encoding==null)
+            _writer.write(new String(b));
+        else
+            _writer.write(new String(b,_encoding));
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(byte[] b, int off, int len)
+        throws IOException
+    {
+        if (_encoding==null)
+            _writer.write(new String(b,off,len));
+        else
+            _writer.write(new String(b,off,len,_encoding));
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public synchronized void write(int b)
+        throws IOException
+    {
+        _buf[0]=(byte)b;
+        write(_buf);
+    }
+}
+
diff --git a/src/java/org/eclipse/jetty/io/bio/SocketEndPoint.java b/src/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
new file mode 100644
index 0000000..333ff9e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/bio/SocketEndPoint.java
@@ -0,0 +1,286 @@
+//
+//  ========================================================================
+//  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.io.bio;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class SocketEndPoint extends StreamEndPoint
+{
+    private static final Logger LOG = Log.getLogger(SocketEndPoint.class);
+
+    final Socket _socket;
+    final InetSocketAddress _local;
+    final InetSocketAddress _remote;
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public SocketEndPoint(Socket socket)
+    	throws IOException
+    {
+        super(socket.getInputStream(),socket.getOutputStream());
+        _socket=socket;
+        _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+        _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+        super.setMaxIdleTime(_socket.getSoTimeout());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    protected SocketEndPoint(Socket socket, int maxIdleTime)
+        throws IOException
+    {
+        super(socket.getInputStream(),socket.getOutputStream());
+        _socket=socket;
+        _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+        _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+        _socket.setSoTimeout(maxIdleTime>0?maxIdleTime:0);
+        super.setMaxIdleTime(maxIdleTime);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see org.eclipse.io.BufferIO#isClosed()
+     */
+    @Override
+    public boolean isOpen()
+    {
+        return super.isOpen() && _socket!=null && !_socket.isClosed();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isInputShutdown()
+    {
+        if (_socket instanceof SSLSocket)
+            return super.isInputShutdown();
+        return _socket.isClosed() || _socket.isInputShutdown();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isOutputShutdown()
+    {
+        if (_socket instanceof SSLSocket)
+            return super.isOutputShutdown();
+
+        return _socket.isClosed() || _socket.isOutputShutdown();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    protected final void shutdownSocketOutput() throws IOException
+    {
+        if (!_socket.isClosed())
+        {
+            if (!_socket.isOutputShutdown())
+                _socket.shutdownOutput();
+            if (_socket.isInputShutdown())
+                _socket.close();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
+     */
+    @Override
+    public void shutdownOutput() throws IOException
+    {
+        if (_socket instanceof SSLSocket)
+            super.shutdownOutput();
+        else
+            shutdownSocketOutput();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public void shutdownSocketInput() throws IOException
+    {
+        if (!_socket.isClosed())
+        {
+            if (!_socket.isInputShutdown())
+                _socket.shutdownInput();
+            if (_socket.isOutputShutdown())
+                _socket.close();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.io.bio.StreamEndPoint#shutdownOutput()
+     */
+    @Override
+    public void shutdownInput() throws IOException
+    {
+        if (_socket instanceof SSLSocket)
+            super.shutdownInput();
+        else
+            shutdownSocketInput();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see org.eclipse.io.BufferIO#close()
+     */
+    @Override
+    public void close() throws IOException
+    {
+        _socket.close();
+        _in=null;
+        _out=null;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalAddr()
+     */
+    @Override
+    public String getLocalAddr()
+    {
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+
+        return _local.getAddress().getHostAddress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalHost()
+     */
+    @Override
+    public String getLocalHost()
+    {
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+
+        return _local.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalPort()
+     */
+    @Override
+    public int getLocalPort()
+    {
+        if (_local==null)
+            return -1;
+        return _local.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteAddr()
+     */
+    @Override
+    public String getRemoteAddr()
+    {
+        if (_remote==null)
+            return null;
+        InetAddress addr = _remote.getAddress();
+        return ( addr == null ? null : addr.getHostAddress() );
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteHost()
+     */
+    @Override
+    public String getRemoteHost()
+    {
+        if (_remote==null)
+            return null;
+        return _remote.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemotePort()
+     */
+    @Override
+    public int getRemotePort()
+    {
+        if (_remote==null)
+            return -1;
+        return _remote.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getConnection()
+     */
+    @Override
+    public Object getTransport()
+    {
+        return _socket;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
+     */
+    @Override
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        if (timeMs!=getMaxIdleTime())
+            _socket.setSoTimeout(timeMs>0?timeMs:0);
+        super.setMaxIdleTime(timeMs);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void idleExpired() throws IOException
+    {
+        try
+        {
+            if (!isInputShutdown())
+                shutdownInput();
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+            _socket.close();
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return _local + " <--> " + _remote;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/bio/StreamEndPoint.java b/src/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
new file mode 100644
index 0000000..b43ca5c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/bio/StreamEndPoint.java
@@ -0,0 +1,325 @@
+//
+//  ========================================================================
+//  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.io.bio;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketTimeoutException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+
+public class StreamEndPoint implements EndPoint
+{
+    InputStream _in;
+    OutputStream _out;
+    int _maxIdleTime;
+    boolean _ishut;
+    boolean _oshut;
+
+    /**
+     *
+     */
+    public StreamEndPoint(InputStream in, OutputStream out)
+    {
+        _in=in;
+        _out=out;
+    }
+
+    public boolean isBlocking()
+    {
+        return true;
+    }
+
+    public boolean blockReadable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    public boolean blockWritable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    /*
+     * @see org.eclipse.io.BufferIO#isOpen()
+     */
+    public boolean isOpen()
+    {
+        return _in!=null;
+    }
+
+    /*
+     * @see org.eclipse.io.BufferIO#isOpen()
+     */
+    public final boolean isClosed()
+    {
+        return !isOpen();
+    }
+
+    public void shutdownOutput() throws IOException
+    {
+        _oshut = true;
+        if (_ishut && _out!=null)
+            _out.close();
+    }
+
+    public boolean isInputShutdown()
+    {
+        return _ishut;
+    }
+
+    public void shutdownInput() throws IOException
+    {
+        _ishut = true;
+        if (_oshut&&_in!=null)
+            _in.close();
+    }
+
+    public boolean isOutputShutdown()
+    {
+        return _oshut;
+    }
+
+    /*
+     * @see org.eclipse.io.BufferIO#close()
+     */
+    public void close() throws IOException
+    {
+        if (_in!=null)
+            _in.close();
+        _in=null;
+        if (_out!=null)
+            _out.close();
+        _out=null;
+    }
+
+    protected void idleExpired() throws IOException
+    {
+        if (_in!=null)
+            _in.close();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.BufferIO#fill(org.eclipse.io.Buffer)
+     */
+    public int fill(Buffer buffer) throws IOException
+    {
+        if (_ishut)
+            return -1;
+        if (_in==null)
+            return 0;
+
+        int space=buffer.space();
+        if (space<=0)
+        {
+            if (buffer.hasContent())
+                return 0;
+            throw new IOException("FULL");
+        }
+
+        try
+        {
+            int filled=buffer.readFrom(_in, space);
+            if (filled<0)
+                shutdownInput();
+            return filled;
+        }
+        catch(SocketTimeoutException e)
+        {
+            idleExpired();
+            return -1;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.BufferIO#flush(org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer buffer) throws IOException
+    {
+        if (_oshut)
+            return -1;
+        if (_out==null)
+            return 0;
+        int length=buffer.length();
+        if (length>0)
+            buffer.writeTo(_out);
+        if (!buffer.isImmutable())
+            buffer.clear();
+        return length;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.BufferIO#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+    {
+        int len=0;
+
+        if (header!=null)
+        {
+            int tw=header.length();
+            if (tw>0)
+            {
+                int f=flush(header);
+                len=f;
+                if (f<tw)
+                    return len;
+            }
+        }
+
+        if (buffer!=null)
+        {
+            int tw=buffer.length();
+            if (tw>0)
+            {
+                int f=flush(buffer);
+                if (f<0)
+                    return len>0?len:f;
+                len+=f;
+                if (f<tw)
+                    return len;
+            }
+        }
+
+        if (trailer!=null)
+        {
+            int tw=trailer.length();
+            if (tw>0)
+            {
+                int f=flush(trailer);
+                if (f<0)
+                    return len>0?len:f;
+                len+=f;
+            }
+        }
+        return len;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalAddr()
+     */
+    public String getLocalAddr()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalHost()
+     */
+    public String getLocalHost()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalPort()
+     */
+    public int getLocalPort()
+    {
+        return 0;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteAddr()
+     */
+    public String getRemoteAddr()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteHost()
+     */
+    public String getRemoteHost()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemotePort()
+     */
+    public int getRemotePort()
+    {
+        return 0;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getConnection()
+     */
+    public Object getTransport()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public InputStream getInputStream()
+    {
+        return _in;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setInputStream(InputStream in)
+    {
+        _in=in;
+    }
+
+    /* ------------------------------------------------------------ */
+    public OutputStream getOutputStream()
+    {
+        return _out;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setOutputStream(OutputStream out)
+    {
+        _out=out;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void flush()
+        throws IOException
+    {
+        if (_out != null)
+            _out.flush();
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        _maxIdleTime=timeMs;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/io/bio/StringEndPoint.java b/src/java/org/eclipse/jetty/io/bio/StringEndPoint.java
new file mode 100644
index 0000000..a74768a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/bio/StringEndPoint.java
@@ -0,0 +1,94 @@
+//
+//  ========================================================================
+//  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.io.bio;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.eclipse.jetty.util.StringUtil;
+
+/**
+ * 
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class StringEndPoint extends StreamEndPoint
+{
+    String _encoding=StringUtil.__UTF8;
+    ByteArrayInputStream _bin = new ByteArrayInputStream(new byte[0]);
+    ByteArrayOutputStream _bout = new ByteArrayOutputStream();
+    
+    public StringEndPoint()
+    {
+        super(null,null);
+        _in=_bin;
+        _out=_bout;
+    }
+    
+    public StringEndPoint(String encoding)
+    {
+        this();
+        if (encoding!=null)
+            _encoding=encoding;
+    }
+    
+    public void setInput(String s) 
+    {
+        try
+        {
+            byte[] bytes = s.getBytes(_encoding);
+            _bin=new ByteArrayInputStream(bytes);
+            _in=_bin;
+            _bout = new ByteArrayOutputStream();
+            _out=_bout;
+            _ishut=false;
+            _oshut=false;
+        }
+        catch(Exception e)
+        {
+            throw new IllegalStateException(e.toString());
+        }
+    }
+    
+    public String getOutput() 
+    {
+        try
+        {
+            String s = new String(_bout.toByteArray(),_encoding);
+            _bout.reset();
+      	  return s;
+        }
+        catch(final Exception e)
+        {
+            throw new IllegalStateException(_encoding)
+            {
+                {initCause(e);}
+            };
+        }
+    }
+
+    /**
+     * @return <code>true</code> if there are bytes remaining to be read from the encoded input
+     */
+    public boolean hasMore()
+    {
+        return _bin.available()>0;
+    }   
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/AsyncConnection.java b/src/java/org/eclipse/jetty/io/nio/AsyncConnection.java
new file mode 100644
index 0000000..deab21b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/AsyncConnection.java
@@ -0,0 +1,28 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Connection;
+
+public interface AsyncConnection extends Connection
+{
+    void onInputShutdown() throws IOException;
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/src/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
new file mode 100644
index 0000000..0ee1c1e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/ChannelEndPoint.java
@@ -0,0 +1,509 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.GatheringByteChannel;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SocketChannel;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Channel End Point.
+ * <p>Holds the channel and socket for an NIO endpoint.
+ *
+ */
+public class ChannelEndPoint implements EndPoint
+{
+    private static final Logger LOG = Log.getLogger(ChannelEndPoint.class);
+
+    protected final ByteChannel _channel;
+    protected final ByteBuffer[] _gather2=new ByteBuffer[2];
+    protected final Socket _socket;
+    protected final InetSocketAddress _local;
+    protected final InetSocketAddress _remote;
+    protected volatile int _maxIdleTime;
+    private volatile boolean _ishut;
+    private volatile boolean _oshut;
+
+    public ChannelEndPoint(ByteChannel channel) throws IOException
+    {
+        super();
+        this._channel = channel;
+        _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+        if (_socket!=null)
+        {
+            _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+            _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+            _maxIdleTime=_socket.getSoTimeout();
+        }
+        else
+        {
+            _local=_remote=null;
+        }
+    }
+
+    protected ChannelEndPoint(ByteChannel channel, int maxIdleTime) throws IOException
+    {
+        this._channel = channel;
+        _maxIdleTime=maxIdleTime;
+        _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+        if (_socket!=null)
+        {
+            _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+            _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+            _socket.setSoTimeout(_maxIdleTime);
+        }
+        else
+        {
+            _local=_remote=null;
+        }
+    }
+
+    public boolean isBlocking()
+    {
+        return  !(_channel instanceof SelectableChannel) || ((SelectableChannel)_channel).isBlocking();
+    }
+
+    public boolean blockReadable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    public boolean blockWritable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    /*
+     * @see org.eclipse.io.EndPoint#isOpen()
+     */
+    public boolean isOpen()
+    {
+        return _channel.isOpen();
+    }
+
+    /** Shutdown the channel Input.
+     * Cannot be overridden. To override, see {@link #shutdownInput()}
+     * @throws IOException
+     */
+    protected final void shutdownChannelInput() throws IOException
+    {
+        LOG.debug("ishut {}", this);
+        _ishut = true;
+        if (_channel.isOpen())
+        {
+            if (_socket != null)
+            {
+                try
+                {
+                    if (!_socket.isInputShutdown())
+                    {
+                        _socket.shutdownInput();
+                    }
+                }
+                catch (SocketException e)
+                {
+                    LOG.debug(e.toString());
+                    LOG.ignore(e);
+                }
+                finally
+                {
+                    if (_oshut)
+                    {
+                        close();
+                    }
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void shutdownInput() throws IOException
+    {
+        shutdownChannelInput();
+    }
+
+    protected final void shutdownChannelOutput() throws IOException
+    {
+        LOG.debug("oshut {}",this);
+        _oshut = true;
+        if (_channel.isOpen())
+        {
+            if (_socket != null)
+            {
+                try
+                {
+                    if (!_socket.isOutputShutdown())
+                    {
+                        _socket.shutdownOutput();
+                    }
+                }
+                catch (SocketException e)
+                {
+                    LOG.debug(e.toString());
+                    LOG.ignore(e);
+                }
+                finally
+                {
+                    if (_ishut)
+                    {
+                        close();
+                    }
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void shutdownOutput() throws IOException
+    {
+        shutdownChannelOutput();
+    }
+
+    public boolean isOutputShutdown()
+    {
+        return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown();
+    }
+
+    public boolean isInputShutdown()
+    {
+        return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void close() throws IOException
+    {
+        LOG.debug("close {}",this);
+        _channel.close();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
+     */
+    public int fill(Buffer buffer) throws IOException
+    {
+        if (_ishut)
+            return -1;
+        Buffer buf = buffer.buffer();
+        int len=0;
+        if (buf instanceof NIOBuffer)
+        {
+            final NIOBuffer nbuf = (NIOBuffer)buf;
+            final ByteBuffer bbuf=nbuf.getByteBuffer();
+
+            //noinspection SynchronizationOnLocalVariableOrMethodParameter
+            try
+            {
+                synchronized(bbuf)
+                {
+                    try
+                    {
+                        bbuf.position(buffer.putIndex());
+                        len=_channel.read(bbuf);
+                    }
+                    finally
+                    {
+                        buffer.setPutIndex(bbuf.position());
+                        bbuf.position(0);
+                    }
+                }
+
+                if (len<0 && isOpen())
+                {
+                    if (!isInputShutdown())
+                        shutdownInput();
+                    if (isOutputShutdown())
+                        _channel.close();
+                }
+            }
+            catch (IOException x)
+            {
+                LOG.debug("Exception while filling", x);
+                try
+                {
+                    if (_channel.isOpen())
+                        _channel.close();
+                }
+                catch (Exception xx)
+                {
+                    LOG.ignore(xx);
+                }
+
+                if (len>0)
+                    throw x;
+                len=-1;
+            }
+        }
+        else
+        {
+            throw new IOException("Not Implemented");
+        }
+
+        return len;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer buffer) throws IOException
+    {
+        Buffer buf = buffer.buffer();
+        int len=0;
+        if (buf instanceof NIOBuffer)
+        {
+            final NIOBuffer nbuf = (NIOBuffer)buf;
+            final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer();
+            try
+            {
+                bbuf.position(buffer.getIndex());
+                bbuf.limit(buffer.putIndex());
+                len=_channel.write(bbuf);
+            }
+            finally
+            {
+                if (len>0)
+                    buffer.skip(len);
+            }
+        }
+        else if (buf instanceof RandomAccessFileBuffer)
+        {
+            len = ((RandomAccessFileBuffer)buf).writeTo(_channel,buffer.getIndex(),buffer.length());
+            if (len>0)
+                buffer.skip(len);
+        }
+        else if (buffer.array()!=null)
+        {
+            ByteBuffer b = ByteBuffer.wrap(buffer.array(), buffer.getIndex(), buffer.length());
+            len=_channel.write(b);
+            if (len>0)
+                buffer.skip(len);
+        }
+        else
+        {
+            throw new IOException("Not Implemented");
+        }
+        return len;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+    {
+        int length=0;
+
+        Buffer buf0 = header==null?null:header.buffer();
+        Buffer buf1 = buffer==null?null:buffer.buffer();
+
+        if (_channel instanceof GatheringByteChannel &&
+            header!=null && header.length()!=0 && buf0 instanceof NIOBuffer &&
+            buffer!=null && buffer.length()!=0 && buf1 instanceof NIOBuffer)
+        {
+            length = gatheringFlush(header,((NIOBuffer)buf0).getByteBuffer(),buffer,((NIOBuffer)buf1).getByteBuffer());
+        }
+        else
+        {
+            // flush header
+            if (header!=null && header.length()>0)
+                length=flush(header);
+
+            // flush buffer
+            if ((header==null || header.length()==0) &&
+                 buffer!=null && buffer.length()>0)
+                length+=flush(buffer);
+
+            // flush trailer
+            if ((header==null || header.length()==0) &&
+                (buffer==null || buffer.length()==0) &&
+                 trailer!=null && trailer.length()>0)
+                length+=flush(trailer);
+        }
+
+        return length;
+    }
+
+    protected int gatheringFlush(Buffer header, ByteBuffer bbuf0, Buffer buffer, ByteBuffer bbuf1) throws IOException
+    {
+        int length;
+
+        synchronized(this)
+        {
+            // Adjust position indexs of buf0 and buf1
+            bbuf0=bbuf0.asReadOnlyBuffer();
+            bbuf0.position(header.getIndex());
+            bbuf0.limit(header.putIndex());
+            bbuf1=bbuf1.asReadOnlyBuffer();
+            bbuf1.position(buffer.getIndex());
+            bbuf1.limit(buffer.putIndex());
+
+            _gather2[0]=bbuf0;
+            _gather2[1]=bbuf1;
+
+            // do the gathering write.
+            length=(int)((GatheringByteChannel)_channel).write(_gather2);
+
+            int hl=header.length();
+            if (length>hl)
+            {
+                header.clear();
+                buffer.skip(length-hl);
+            }
+            else if (length>0)
+            {
+                header.skip(length);
+            }
+        }
+        return length;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the channel.
+     */
+    public ByteChannel getChannel()
+    {
+        return _channel;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalAddr()
+     */
+    public String getLocalAddr()
+    {
+        if (_socket==null)
+            return null;
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+        return _local.getAddress().getHostAddress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalHost()
+     */
+    public String getLocalHost()
+    {
+        if (_socket==null)
+            return null;
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+        return _local.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalPort()
+     */
+    public int getLocalPort()
+    {
+        if (_socket==null)
+            return 0;
+        if (_local==null)
+            return -1;
+        return _local.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteAddr()
+     */
+    public String getRemoteAddr()
+    {
+        if (_socket==null)
+            return null;
+        if (_remote==null)
+            return null;
+        return _remote.getAddress().getHostAddress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteHost()
+     */
+    public String getRemoteHost()
+    {
+        if (_socket==null)
+            return null;
+        if (_remote==null)
+            return null;
+        return _remote.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemotePort()
+     */
+    public int getRemotePort()
+    {
+        if (_socket==null)
+            return 0;
+        return _remote==null?-1:_remote.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getConnection()
+     */
+    public Object getTransport()
+    {
+        return _channel;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void flush()
+        throws IOException
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
+     */
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        if (_socket!=null && timeMs!=_maxIdleTime)
+            _socket.setSoTimeout(timeMs>0?timeMs:0);
+        _maxIdleTime=timeMs;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java b/src/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java
new file mode 100644
index 0000000..bf683bd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/DirectNIOBuffer.java
@@ -0,0 +1,354 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+
+import org.eclipse.jetty.io.AbstractBuffer;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * 
+ * 
+ */
+public class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer
+{ 	
+    private static final Logger LOG = Log.getLogger(DirectNIOBuffer.class);
+
+    protected final ByteBuffer _buf;
+    private ReadableByteChannel _in;
+    private InputStream _inStream;
+    private WritableByteChannel _out;
+    private OutputStream _outStream;
+
+    public DirectNIOBuffer(int size)
+    {
+        super(READWRITE,NON_VOLATILE);
+        _buf = ByteBuffer.allocateDirect(size);
+        _buf.position(0);
+        _buf.limit(_buf.capacity());
+    }
+    
+    public DirectNIOBuffer(ByteBuffer buffer,boolean immutable)
+    {
+        super(immutable?IMMUTABLE:READWRITE,NON_VOLATILE);
+        if (!buffer.isDirect())
+            throw new IllegalArgumentException();
+        _buf = buffer;
+        setGetIndex(buffer.position());
+        setPutIndex(buffer.limit());
+    }
+
+    /**
+     * @param file
+     */
+    public DirectNIOBuffer(File file) throws IOException
+    {
+        super(READONLY,NON_VOLATILE);
+        FileInputStream fis = null;
+        FileChannel fc = null;
+        try
+        {
+            fis = new FileInputStream(file);
+            fc = fis.getChannel();
+            _buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
+            setGetIndex(0);
+            setPutIndex((int)file.length());
+            _access=IMMUTABLE;
+        }
+        finally
+        {
+            if (fc != null) try {fc.close();} catch (IOException e){LOG.ignore(e);}
+            IO.close(fis);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isDirect()
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public byte[] array()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int capacity()
+    {
+        return _buf.capacity();
+    }
+
+    /* ------------------------------------------------------------ */
+    public byte peek(int position)
+    {
+        return _buf.get(position);
+    }
+
+    public int peek(int index, byte[] b, int offset, int length)
+    {
+        int l = length;
+        if (index+l > capacity())
+        {
+            l=capacity()-index;
+            if (l==0)
+                return -1;
+        }
+        
+        if (l < 0) 
+            return -1;
+        try
+        {
+            _buf.position(index);
+            _buf.get(b,offset,l);
+        }
+        finally
+        {
+            _buf.position(0);
+        }
+        
+        return l;
+    }
+
+    public void poke(int index, byte b)
+    {
+        if (isReadOnly()) throw new IllegalStateException(__READONLY);
+        if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0");
+        if (index > capacity())
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+        _buf.put(index,b);
+    }
+
+    @Override
+    public int poke(int index, Buffer src)
+    {
+        if (isReadOnly()) throw new IllegalStateException(__READONLY);
+
+        byte[] array=src.array();
+        if (array!=null)
+        {
+            return poke(index,array,src.getIndex(),src.length());
+        }
+        else
+        {
+            Buffer src_buf=src.buffer();
+            if (src_buf instanceof DirectNIOBuffer)
+            {
+                ByteBuffer src_bytebuf = ((DirectNIOBuffer)src_buf)._buf;
+                if (src_bytebuf==_buf)
+                    src_bytebuf=_buf.duplicate();
+                try
+                {   
+                    _buf.position(index);
+                    int space = _buf.remaining();
+                    
+                    int length=src.length();
+                    if (length>space)    
+                        length=space;
+                    
+                    src_bytebuf.position(src.getIndex());
+                    src_bytebuf.limit(src.getIndex()+length);
+                    
+                    _buf.put(src_bytebuf);
+                    return length;
+                }
+                finally
+                {
+                    _buf.position(0);
+                    src_bytebuf.limit(src_bytebuf.capacity());
+                    src_bytebuf.position(0);
+                }
+            }
+            else
+                return super.poke(index,src);
+        }
+    }
+    
+    @Override
+    public int poke(int index, byte[] b, int offset, int length)
+    {
+        if (isReadOnly()) throw new IllegalStateException(__READONLY);
+
+        if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0");
+
+        if (index + length > capacity())
+        {
+            length=capacity()-index;
+            if (length<0)
+                throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity());
+        }
+
+        try
+        {
+            _buf.position(index);
+            
+            int space=_buf.remaining();
+            
+            if (length>space)
+                length=space;
+            if (length>0)
+                _buf.put(b,offset,length);
+            return length;
+        }
+        finally
+        {
+            _buf.position(0);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ByteBuffer getByteBuffer()
+    {
+        return _buf;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int readFrom(InputStream in, int max) throws IOException
+    {
+        if (_in==null || !_in.isOpen() || in!=_inStream)
+        {
+            _in=Channels.newChannel(in);
+            _inStream=in;
+        }
+
+        if (max<0 || max>space())
+            max=space();
+        int p = putIndex();
+        
+        try
+        {
+            int len=0, total=0, available=max;
+            int loop=0;
+            while (total<max) 
+            {
+                _buf.position(p);
+                _buf.limit(p+available);
+                len=_in.read(_buf);
+                if (len<0)
+                {
+                    _in=null;
+                    _inStream=in;
+                    break;
+                }
+                else if (len>0)
+                {
+                    p += len;
+                    total += len;
+                    available -= len;
+                    setPutIndex(p);
+                    loop=0;
+                }
+                else if (loop++>1)
+                    break;
+                if (in.available()<=0)
+                    break;
+            }
+            if (len<0 && total==0)
+                return -1;
+            return total;
+            
+        }
+        catch(IOException e)
+        {
+            _in=null;
+            _inStream=in;
+            throw e;
+        }
+        finally
+        {
+            if (_in!=null && !_in.isOpen())
+            {
+                _in=null;
+                _inStream=in;
+            }
+            _buf.position(0);
+            _buf.limit(_buf.capacity());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void writeTo(OutputStream out) throws IOException
+    {
+        if (_out==null || !_out.isOpen() || out!=_outStream)
+        {
+            _out=Channels.newChannel(out);
+            _outStream=out;
+        }
+
+        synchronized (_buf)
+        {
+            try
+            {
+                int loop=0;
+                while(hasContent() && _out.isOpen())
+                {
+                    _buf.position(getIndex());
+                    _buf.limit(putIndex());
+                    int len=_out.write(_buf);
+                    if (len<0)
+                        break;
+                    else if (len>0)
+                    {
+                        skip(len);
+                        loop=0;
+                    }
+                    else if (loop++>1)
+                        break;
+                }
+
+            }
+            catch(IOException e)
+            {
+                _out=null;
+                _outStream=null;
+                throw e;
+            }
+            finally
+            {
+                if (_out!=null && !_out.isOpen())
+                {
+                    _out=null;
+                    _outStream=null;
+                }
+                _buf.position(0);
+                _buf.limit(_buf.capacity());
+            }
+        }
+    }
+
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java b/src/java/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java
new file mode 100644
index 0000000..44c2f46
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java
@@ -0,0 +1,62 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jetty.io.ByteArrayBuffer;
+
+public class IndirectNIOBuffer extends ByteArrayBuffer implements NIOBuffer
+{
+    protected final ByteBuffer _buf;
+
+    /* ------------------------------------------------------------ */
+    public IndirectNIOBuffer(int size)
+    {
+        super(size,READWRITE,NON_VOLATILE);
+        _buf = ByteBuffer.wrap(_bytes);
+        _buf.position(0);
+        _buf.limit(_buf.capacity());
+    }
+
+    /* ------------------------------------------------------------ */
+    public IndirectNIOBuffer(ByteBuffer buffer,boolean immutable)
+    {
+        super(buffer.array(),0,0, immutable?IMMUTABLE:READWRITE,NON_VOLATILE);
+        if (buffer.isDirect())
+            throw new IllegalArgumentException();
+        _buf = buffer;
+        _get=buffer.position();
+        _put=buffer.limit();
+        buffer.position(0);
+        buffer.limit(buffer.capacity());
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ByteBuffer getByteBuffer()
+    {
+        return _buf;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isDirect()
+    {
+        return false;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/NIOBuffer.java b/src/java/org/eclipse/jetty/io/nio/NIOBuffer.java
new file mode 100644
index 0000000..4331971
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/NIOBuffer.java
@@ -0,0 +1,37 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jetty.io.Buffer;
+
+/* ------------------------------------------------------------------------------- */
+/** 
+ * 
+ * 
+ */
+public interface NIOBuffer extends Buffer
+{
+    /* ------------------------------------------------------------ */
+    public ByteBuffer getByteBuffer();
+
+    /* ------------------------------------------------------------ */
+    public boolean isDirect();
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/NetworkTrafficSelectChannelEndPoint.java b/src/java/org/eclipse/jetty/io/nio/NetworkTrafficSelectChannelEndPoint.java
new file mode 100644
index 0000000..ce57b57
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/NetworkTrafficSelectChannelEndPoint.java
@@ -0,0 +1,148 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.List;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.NetworkTrafficListener;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class NetworkTrafficSelectChannelEndPoint extends SelectChannelEndPoint
+{
+    private static final Logger LOG = Log.getLogger(NetworkTrafficSelectChannelEndPoint.class);
+
+    private final List<NetworkTrafficListener> listeners;
+
+    public NetworkTrafficSelectChannelEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key, int maxIdleTime, List<NetworkTrafficListener> listeners) throws IOException
+    {
+        super(channel, selectSet, key, maxIdleTime);
+        this.listeners = listeners;
+    }
+
+    @Override
+    public int fill(Buffer buffer) throws IOException
+    {
+        int read = super.fill(buffer);
+        notifyIncoming(buffer, read);
+        return read;
+    }
+
+    @Override
+    public int flush(Buffer buffer) throws IOException
+    {
+        int position = buffer.getIndex();
+        int written = super.flush(buffer);
+        notifyOutgoing(buffer, position, written);
+        return written;
+    }
+
+    @Override
+    protected int gatheringFlush(Buffer header, ByteBuffer bbuf0, Buffer buffer, ByteBuffer bbuf1) throws IOException
+    {
+        int headerPosition = header.getIndex();
+        int headerLength = header.length();
+        int bufferPosition = buffer.getIndex();
+        int written = super.gatheringFlush(header, bbuf0, buffer,bbuf1);
+        notifyOutgoing(header, headerPosition, written > headerLength ? headerLength : written);
+        notifyOutgoing(buffer, bufferPosition, written > headerLength ? written - headerLength : 0);
+        return written;
+    }
+
+    public void notifyOpened()
+    {
+        if (listeners != null && !listeners.isEmpty())
+        {
+            for (NetworkTrafficListener listener : listeners)
+            {
+                try
+                {
+                    listener.opened(_socket);
+                }
+                catch (Exception x)
+                {
+                    LOG.warn(x);
+                }
+            }
+        }
+    }
+
+    public void notifyIncoming(Buffer buffer, int read)
+    {
+        if (listeners != null && !listeners.isEmpty() && read > 0)
+        {
+            for (NetworkTrafficListener listener : listeners)
+            {
+                try
+                {
+                    Buffer view = buffer.asReadOnlyBuffer();
+                    listener.incoming(_socket, view);
+                }
+                catch (Exception x)
+                {
+                    LOG.warn(x);
+                }
+            }
+        }
+    }
+
+    public void notifyOutgoing(Buffer buffer, int position, int written)
+    {
+        if (listeners != null && !listeners.isEmpty() && written > 0)
+        {
+            for (NetworkTrafficListener listener : listeners)
+            {
+                try
+                {
+                    Buffer view = buffer.asReadOnlyBuffer();
+                    view.setGetIndex(position);
+                    view.setPutIndex(position + written);
+                    listener.outgoing(_socket, view);
+                }
+                catch (Exception x)
+                {
+                    LOG.warn(x);
+                }
+            }
+        }
+    }
+
+    public void notifyClosed()
+    {
+        if (listeners != null && !listeners.isEmpty())
+        {
+            for (NetworkTrafficListener listener : listeners)
+            {
+                try
+                {
+                    listener.closed(_socket);
+                }
+                catch (Exception x)
+                {
+                    LOG.warn(x);
+                }
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/RandomAccessFileBuffer.java b/src/java/org/eclipse/jetty/io/nio/RandomAccessFileBuffer.java
new file mode 100644
index 0000000..6b8b2ef
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/RandomAccessFileBuffer.java
@@ -0,0 +1,196 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.WritableByteChannel;
+
+import org.eclipse.jetty.io.AbstractBuffer;
+import org.eclipse.jetty.io.Buffer;
+
+public class RandomAccessFileBuffer extends AbstractBuffer implements Buffer
+{
+    final RandomAccessFile _file;
+    final FileChannel _channel;
+    final int _capacity;
+
+    public RandomAccessFileBuffer(File file) 
+        throws FileNotFoundException
+    {
+        super(READWRITE,true);
+        assert file.length()<=Integer.MAX_VALUE;
+        _file = new RandomAccessFile(file,"rw");
+        _channel=_file.getChannel();
+        _capacity=Integer.MAX_VALUE;
+        setGetIndex(0);
+        setPutIndex((int)file.length());
+    }
+    
+    public RandomAccessFileBuffer(File file,int capacity) 
+        throws FileNotFoundException
+    {
+        super(READWRITE,true);
+        assert capacity>=file.length();
+        assert file.length()<=Integer.MAX_VALUE;
+        _capacity=capacity;
+        _file = new RandomAccessFile(file,"rw");
+        _channel=_file.getChannel();
+        setGetIndex(0);
+        setPutIndex((int)file.length());
+    }
+    
+    public RandomAccessFileBuffer(File file,int capacity,int access) 
+        throws FileNotFoundException
+    {
+        super(access,true);
+        assert capacity>=file.length();
+        assert file.length()<=Integer.MAX_VALUE;
+        _capacity=capacity;
+        _file = new RandomAccessFile(file,access==READWRITE?"rw":"r");
+        _channel=_file.getChannel();
+        setGetIndex(0);
+        setPutIndex((int)file.length());
+    }
+
+    public byte[] array()
+    {
+        return null;
+    }
+
+    public int capacity()
+    {
+        return _capacity;
+    }
+
+    @Override
+    public void clear()
+    {
+        try
+        {
+            synchronized (_file)
+            {
+                super.clear();
+                _file.setLength(0);
+            }
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public byte peek()
+    {
+        synchronized (_file)
+        {
+            try
+            {
+                if (_get!=_file.getFilePointer())
+                    _file.seek(_get);
+                return _file.readByte();
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public byte peek(int index)
+    {
+        synchronized (_file)
+        {
+            try
+            {
+                _file.seek(index);
+                return _file.readByte();
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public int peek(int index, byte[] b, int offset, int length)
+    {
+        synchronized (_file)
+        {
+            try
+            {
+                _file.seek(index);
+                return _file.read(b,offset,length);
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void poke(int index, byte b)
+    {
+        synchronized (_file)
+        {
+            try
+            {
+                _file.seek(index);
+                _file.writeByte(b);
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Override
+    public int poke(int index, byte[] b, int offset, int length)
+    {
+        synchronized (_file)
+        {
+            try
+            {
+                _file.seek(index);
+                _file.write(b,offset,length);
+                return length;
+            }
+            catch(Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    
+    public int writeTo(WritableByteChannel channel,int index, int length)
+        throws IOException
+    {
+        synchronized (_file)
+        {
+            return (int)_channel.transferTo(index,length,channel);
+        }
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/src/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
new file mode 100644
index 0000000..9d16f5d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java
@@ -0,0 +1,868 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.Locale;
+
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout.Task;
+
+/* ------------------------------------------------------------ */
+/**
+ * An Endpoint that can be scheduled by {@link SelectorManager}.
+ */
+public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint, ConnectedEndPoint
+{
+    public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
+
+    private final boolean WORK_AROUND_JVM_BUG_6346658 = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win");
+    private final SelectorManager.SelectSet _selectSet;
+    private final SelectorManager _manager;
+    private  SelectionKey _key;
+    private final Runnable _handler = new Runnable()
+        {
+            public void run() { handle(); }
+        };
+
+    /** The desired value for {@link SelectionKey#interestOps()} */
+    private int _interestOps;
+
+    /**
+     * The connection instance is the handler for any IO activity on the endpoint.
+     * There is a different type of connection for HTTP, AJP, WebSocket and
+     * ProxyConnect.   The connection may change for an SCEP as it is upgraded
+     * from HTTP to proxy connect or websocket.
+     */
+    private volatile AsyncConnection _connection;
+
+    private static final int STATE_NEEDS_DISPATCH=-1;
+    private static final int STATE_UNDISPATCHED=0;
+    private static final int STATE_DISPATCHED=1;
+    private static final int STATE_ASYNC=2;
+    private int _state;
+    
+    private boolean _onIdle;
+
+    /** true if the last write operation succeed and wrote all offered bytes */
+    private volatile boolean _writable = true;
+
+
+    /** True if a thread has is blocked in {@link #blockReadable(long)} */
+    private boolean _readBlocked;
+
+    /** True if a thread has is blocked in {@link #blockWritable(long)} */
+    private boolean _writeBlocked;
+
+    /** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */
+    private boolean _open;
+
+    private volatile long _idleTimestamp;
+    private volatile boolean _checkIdle;
+    
+    private boolean _interruptable;
+
+    private boolean _ishut;
+
+    /* ------------------------------------------------------------ */
+    public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime)
+        throws IOException
+    {
+        super(channel, maxIdleTime);
+
+        _manager = selectSet.getManager();
+        _selectSet = selectSet;
+        _state=STATE_UNDISPATCHED;
+        _onIdle=false;
+        _open=true;
+        _key = key;
+
+        setCheckForIdle(true);
+    }
+
+    /* ------------------------------------------------------------ */
+    public SelectionKey getSelectionKey()
+    {
+        synchronized (this)
+        {
+            return _key;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public SelectorManager getSelectManager()
+    {
+        return _manager;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setConnection(Connection connection)
+    {
+        Connection old=_connection;
+        _connection=(AsyncConnection)connection;
+        if (old!=null && old!=_connection)
+            _manager.endPointUpgraded(this,old);
+    }
+
+    /* ------------------------------------------------------------ */
+    public long getIdleTimestamp()
+    {
+        return _idleTimestamp;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Called by selectSet to schedule handling
+     *
+     */
+    public void schedule()
+    {
+        synchronized (this)
+        {
+            // If there is no key, then do nothing
+            if (_key == null || !_key.isValid())
+            {
+                _readBlocked=false;
+                _writeBlocked=false;
+                this.notifyAll();
+                return;
+            }
+
+            // If there are threads dispatched reading and writing
+            if (_readBlocked || _writeBlocked)
+            {
+                // assert _dispatched;
+                if (_readBlocked && _key.isReadable())
+                    _readBlocked=false;
+                if (_writeBlocked && _key.isWritable())
+                    _writeBlocked=false;
+
+                // wake them up is as good as a dispatched.
+                this.notifyAll();
+
+                // we are not interested in further selecting
+                _key.interestOps(0);
+                if (_state<STATE_DISPATCHED)
+                    updateKey();
+                return;
+            }
+
+            // Remove writeable op
+            if ((_key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE)
+            {
+                // Remove writeable op
+                _interestOps = _key.interestOps() & ~SelectionKey.OP_WRITE;
+                _key.interestOps(_interestOps);
+                _writable = true; // Once writable is in ops, only removed with dispatch.
+            }
+
+            // If dispatched, then deregister interest
+            if (_state>=STATE_DISPATCHED)
+                _key.interestOps(0);
+            else
+            {
+                // other wise do the dispatch
+                dispatch();
+                if (_state>=STATE_DISPATCHED && !_selectSet.getManager().isDeferringInterestedOps0())
+                {
+                    _key.interestOps(0);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void asyncDispatch()
+    {
+        synchronized(this)
+        {
+            switch(_state)
+            {
+                case STATE_NEEDS_DISPATCH:
+                case STATE_UNDISPATCHED:
+                    dispatch();
+                    break;
+                    
+                case STATE_DISPATCHED:
+                case STATE_ASYNC:
+                    _state=STATE_ASYNC;
+                    break;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dispatch()
+    {
+        synchronized(this)
+        {
+            if (_state<=STATE_UNDISPATCHED)
+            {
+                if (_onIdle)
+                    _state = STATE_NEEDS_DISPATCH;
+                else
+                {
+                    _state = STATE_DISPATCHED;
+                    boolean dispatched = _manager.dispatch(_handler);
+                    if(!dispatched)
+                    {
+                        _state = STATE_NEEDS_DISPATCH;
+                        LOG.warn("Dispatched Failed! "+this+" to "+_manager);
+                        updateKey();
+                    }
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Called when a dispatched thread is no longer handling the endpoint.
+     * The selection key operations are updated.
+     * @return If false is returned, the endpoint has been redispatched and
+     * thread must keep handling the endpoint.
+     */
+    protected boolean undispatch()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case STATE_ASYNC:
+                    _state=STATE_DISPATCHED;
+                    return false;
+
+                default:
+                    _state=STATE_UNDISPATCHED;
+                    updateKey();
+                    return true;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void cancelTimeout(Task task)
+    {
+        getSelectSet().cancelTimeout(task);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void scheduleTimeout(Task task, long timeoutMs)
+    {
+        getSelectSet().scheduleTimeout(task,timeoutMs);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setCheckForIdle(boolean check)
+    {
+        if (check)
+        {
+            _idleTimestamp=System.currentTimeMillis();
+            _checkIdle=true;
+        }
+        else
+            _checkIdle=false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isCheckForIdle()
+    {
+        return _checkIdle;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void notIdle()
+    {
+        _idleTimestamp=System.currentTimeMillis();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void checkIdleTimestamp(long now)
+    {
+        if (isCheckForIdle() && _maxIdleTime>0)
+        {
+            final long idleForMs=now-_idleTimestamp;
+
+            if (idleForMs>_maxIdleTime)
+            {
+                // Don't idle out again until onIdleExpired task completes.
+                setCheckForIdle(false);
+                _manager.dispatch(new Runnable()
+                {
+                    public void run()
+                    {
+                        try
+                        {
+                            onIdleExpired(idleForMs);
+                        }
+                        finally
+                        {
+                            setCheckForIdle(true);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onIdleExpired(long idleForMs)
+    {
+        try
+        {
+            synchronized (this)
+            {
+                _onIdle=true;
+            }
+
+            _connection.onIdleExpired(idleForMs);
+        }
+        finally
+        {
+            synchronized (this)
+            {
+                _onIdle=false;
+                if (_state==STATE_NEEDS_DISPATCH)
+                    dispatch();
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int fill(Buffer buffer) throws IOException
+    {
+        int fill=super.fill(buffer);
+        if (fill>0)
+            notIdle();
+        return fill;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+    {
+        int l = super.flush(header, buffer, trailer);
+
+        // If there was something to write and it wasn't written, then we are not writable.
+        if (l==0 && ( header!=null && header.hasContent() || buffer!=null && buffer.hasContent() || trailer!=null && trailer.hasContent()))
+        {
+            synchronized (this)
+            {   
+                _writable=false;
+                if (_state<STATE_DISPATCHED)
+                    updateKey();
+            }
+        }
+        else if (l>0)
+        {
+            _writable=true;
+            notIdle();
+        }
+        return l;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    @Override
+    public int flush(Buffer buffer) throws IOException
+    {
+        int l = super.flush(buffer);
+
+        // If there was something to write and it wasn't written, then we are not writable.
+        if (l==0 && buffer!=null && buffer.hasContent())
+        {
+            synchronized (this)
+            {   
+                _writable=false;
+                if (_state<STATE_DISPATCHED)
+                    updateKey();
+            }
+        }
+        else if (l>0)
+        {
+            _writable=true;
+            notIdle();
+        }
+
+        return l;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Allows thread to block waiting for further events.
+     */
+    @Override
+    public boolean blockReadable(long timeoutMs) throws IOException
+    {
+        synchronized (this)
+        {
+            if (isInputShutdown())
+                throw new EofException();
+
+            long now=_selectSet.getNow();
+            long end=now+timeoutMs;
+            boolean check=isCheckForIdle();
+            setCheckForIdle(true);
+            try
+            {
+                _readBlocked=true;
+                while (!isInputShutdown() && _readBlocked)
+                {
+                    try
+                    {
+                        updateKey();
+                        this.wait(timeoutMs>0?(end-now):10000);
+                    }
+                    catch (final InterruptedException e)
+                    {
+                        LOG.warn(e);
+                        if (_interruptable)
+                            throw new InterruptedIOException(){{this.initCause(e);}};
+                    }
+                    finally
+                    {
+                        now=_selectSet.getNow();
+                    }
+
+                    if (_readBlocked && timeoutMs>0 && now>=end)
+                        return false;
+                }
+            }
+            finally
+            {
+                _readBlocked=false;
+                setCheckForIdle(check);
+            }
+        }
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Allows thread to block waiting for further events.
+     */
+    @Override
+    public boolean blockWritable(long timeoutMs) throws IOException
+    {
+        synchronized (this)
+        {
+            if (isOutputShutdown())
+                throw new EofException();
+
+            long now=_selectSet.getNow();
+            long end=now+timeoutMs;
+            boolean check=isCheckForIdle();
+            setCheckForIdle(true);
+            try
+            {
+                _writeBlocked=true;
+                while (_writeBlocked && !isOutputShutdown())
+                {
+                    try
+                    {
+                        updateKey();
+                        this.wait(timeoutMs>0?(end-now):10000);
+                    }
+                    catch (final InterruptedException e)
+                    {
+                        LOG.warn(e);
+                        if (_interruptable)
+                            throw new InterruptedIOException(){{this.initCause(e);}};
+                    }
+                    finally
+                    {
+                        now=_selectSet.getNow();
+                    }
+                    if (_writeBlocked && timeoutMs>0 && now>=end)
+                        return false;
+                }
+            }
+            finally
+            {
+                _writeBlocked=false;
+                setCheckForIdle(check);
+            }
+        }
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the interruptable mode of the endpoint.
+     * If set to false (default), then interrupts are assumed to be spurious 
+     * and blocking operations continue unless the endpoint has been closed.
+     * If true, then interrupts of blocking operations result in InterruptedIOExceptions
+     * being thrown.
+     * @param interupable
+     */
+    public void setInterruptable(boolean interupable)
+    {
+        synchronized (this)
+        {
+            _interruptable=interupable;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isInterruptable()
+    {
+        return _interruptable;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite()
+     */
+    public void scheduleWrite()
+    {
+        if (_writable)
+            LOG.debug("Required scheduleWrite {}",this);
+
+        _writable=false;
+        updateKey();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isWritable()
+    {
+        return _writable;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean hasProgressed()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Updates selection key. Adds operations types to the selection key as needed. No operations
+     * are removed as this is only done during dispatch. This method records the new key and
+     * schedules a call to doUpdateKey to do the keyChange
+     */
+    private void updateKey()
+    {
+        final boolean changed;
+        synchronized (this)
+        {
+            int current_ops=-1;
+            if (getChannel().isOpen())
+            {
+                boolean read_interest = _readBlocked || (_state<STATE_DISPATCHED && !_connection.isSuspended());
+                boolean write_interest= _writeBlocked || (_state<STATE_DISPATCHED && !_writable);
+
+                _interestOps =
+                    ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ  : 0)
+                |   ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0);
+                try
+                {
+                    current_ops = ((_key!=null && _key.isValid())?_key.interestOps():-1);
+                }
+                catch(Exception e)
+                {
+                    _key=null;
+                    LOG.ignore(e);
+                }
+            }
+            changed=_interestOps!=current_ops;
+        }
+
+        if(changed)
+        {
+            _selectSet.addChange(this);
+            _selectSet.wakeup();
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey
+     */
+    void doUpdateKey()
+    {
+        synchronized (this)
+        {
+            if (getChannel().isOpen())
+            {
+                if (_interestOps>0)
+                {
+                    if (_key==null || !_key.isValid())
+                    {
+                        SelectableChannel sc = (SelectableChannel)getChannel();
+                        if (sc.isRegistered())
+                        {
+                            updateKey();
+                        }
+                        else
+                        {
+                            try
+                            {
+                                _key=((SelectableChannel)getChannel()).register(_selectSet.getSelector(),_interestOps,this);
+                            }
+                            catch (Exception e)
+                            {
+                                LOG.ignore(e);
+                                if (_key!=null && _key.isValid())
+                                {
+                                    _key.cancel();
+                                }
+
+                                if (_open)
+                                {
+                                    _selectSet.destroyEndPoint(this);
+                                }
+                                _open=false;
+                                _key = null;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        _key.interestOps(_interestOps);
+                    }
+                }
+                else
+                {
+                    if (_key!=null && _key.isValid())
+                        _key.interestOps(0);
+                    else
+                        _key=null;
+                }
+            }
+            else
+            {
+                if (_key!=null && _key.isValid())
+                    _key.cancel();
+
+                if (_open)
+                {
+                    _open=false;
+                    _selectSet.destroyEndPoint(this);
+                }
+                _key = null;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    protected void handle()
+    {
+        boolean dispatched=true;
+        try
+        {
+            while(dispatched)
+            {
+                try
+                {
+                    while(true)
+                    {
+                        final AsyncConnection next = (AsyncConnection)_connection.handle();
+                        if (next!=_connection)
+                        {
+                            LOG.debug("{} replaced {}",next,_connection);
+                            Connection old=_connection;
+                            _connection=next;
+                            _manager.endPointUpgraded(this,old);
+                            continue;
+                        }
+                        break;
+                    }
+                }
+                catch (ClosedChannelException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (EofException e)
+                {
+                    LOG.debug("EOF", e);
+                    try{close();}
+                    catch(IOException e2){LOG.ignore(e2);}
+                }
+                catch (IOException e)
+                {
+                    LOG.warn(e.toString());
+                    try{close();}
+                    catch(IOException e2){LOG.ignore(e2);}
+                }
+                catch (Throwable e)
+                {
+                    LOG.warn("handle failed", e);
+                    try{close();}
+                    catch(IOException e2){LOG.ignore(e2);}
+                }
+                finally
+                {
+                    if (!_ishut && isInputShutdown() && isOpen())
+                    {
+                        _ishut=true;
+                        try
+                        {
+                            _connection.onInputShutdown();
+                        }
+                        catch(Throwable x)
+                        {
+                            LOG.warn("onInputShutdown failed", x);
+                            try{close();}
+                            catch(IOException e2){LOG.ignore(e2);}
+                        }
+                        finally
+                        {
+                            updateKey();
+                        }
+                    }
+                    dispatched=!undispatch();
+                }
+            }
+        }
+        finally
+        {
+            if (dispatched)
+            {
+                dispatched=!undispatch();
+                while (dispatched)
+                {
+                    LOG.warn("SCEP.run() finally DISPATCHED");
+                    dispatched=!undispatch();
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.nio.ChannelEndPoint#close()
+     */
+    @Override
+    public void close() throws IOException
+    {
+        // On unix systems there is a JVM issue that if you cancel before closing, it can 
+        // cause the selector to block waiting for a channel to close and that channel can 
+        // block waiting for the remote end.  But on windows, if you don't cancel before a 
+        // close, then the selector can block anyway!
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=357318
+        if (WORK_AROUND_JVM_BUG_6346658)
+        {
+            try
+            {
+                SelectionKey key = _key;
+                if (key!=null)
+                    key.cancel();
+            }
+            catch (Throwable e)
+            {
+                LOG.ignore(e);
+            }
+        }
+
+        try
+        {
+            super.close();
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+        finally
+        {
+            updateKey();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        // Do NOT use synchronized (this)
+        // because it's very easy to deadlock when debugging is enabled.
+        // We do a best effort to print the right toString() and that's it.
+        SelectionKey key = _key;
+        String keyString = "";
+        if (key != null)
+        {
+            if (key.isValid())
+            {
+                if (key.isReadable())
+                    keyString += "r";
+                if (key.isWritable())
+                    keyString += "w";
+            }
+            else
+            {
+                keyString += "!";
+            }
+        }
+        else
+        {
+            keyString += "-";
+        }
+        return String.format("SCEP@%x{l(%s)<->r(%s),s=%d,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s}-{%s}",
+                hashCode(),
+                _socket.getRemoteSocketAddress(),
+                _socket.getLocalSocketAddress(),
+                _state,
+                isOpen(),
+                isInputShutdown(),
+                isOutputShutdown(),
+                _readBlocked,
+                _writeBlocked,
+                _writable,
+                _interestOps,
+                keyString,
+                _connection);
+    }
+
+    /* ------------------------------------------------------------ */
+    public SelectSet getSelectSet()
+    {
+        return _selectSet;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Don't set the SoTimeout
+     * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int)
+     */
+    @Override
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        _maxIdleTime=timeMs;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/SelectorManager.java b/src/java/org/eclipse/jetty/io/nio/SelectorManager.java
new file mode 100644
index 0000000..538fbfa
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/SelectorManager.java
@@ -0,0 +1,1034 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.Channel;
+import java.nio.channels.ClosedSelectorException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout;
+import org.eclipse.jetty.util.thread.Timeout.Task;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * The Selector Manager manages and number of SelectSets to allow
+ * NIO scheduling to scale to large numbers of connections.
+ * <p>
+ */
+public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable
+{
+    public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
+
+    private static final int __MONITOR_PERIOD=Integer.getInteger("org.eclipse.jetty.io.nio.MONITOR_PERIOD",1000).intValue();
+    private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",100000).intValue();
+    private static final int __BUSY_PAUSE=Integer.getInteger("org.eclipse.jetty.io.nio.BUSY_PAUSE",50).intValue();
+    private static final int __IDLE_TICK=Integer.getInteger("org.eclipse.jetty.io.nio.IDLE_TICK",400).intValue();
+
+    private int _maxIdleTime;
+    private int _lowResourcesMaxIdleTime;
+    private long _lowResourcesConnections;
+    private SelectSet[] _selectSet;
+    private int _selectSets=1;
+    private volatile int _set=0;
+    private boolean _deferringInterestedOps0=true;
+    private int _selectorPriorityDelta=0;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxIdleTime The maximum period in milli seconds that a connection may be idle before it is closed.
+     * @see #setLowResourcesMaxIdleTime(long)
+     */
+    public void setMaxIdleTime(long maxIdleTime)
+    {
+        _maxIdleTime=(int)maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param selectSets number of select sets to create
+     */
+    public void setSelectSets(int selectSets)
+    {
+        long lrc = _lowResourcesConnections * _selectSets;
+        _selectSets=selectSets;
+        _lowResourcesConnections=lrc/_selectSets;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the max idle time
+     */
+    public long getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the number of select sets in use
+     */
+    public int getSelectSets()
+    {
+        return _selectSets;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param i
+     * @return The select set
+     */
+    public SelectSet getSelectSet(int i)
+    {
+        return _selectSet[i];
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Register a channel
+     * @param channel
+     * @param att Attached Object
+     */
+    public void register(SocketChannel channel, Object att)
+    {
+        // The ++ increment here is not atomic, but it does not matter.
+        // so long as the value changes sometimes, then connections will
+        // be distributed over the available sets.
+
+        int s=_set++;
+        if (s<0)
+            s=-s;
+        s=s%_selectSets;
+        SelectSet[] sets=_selectSet;
+        if (sets!=null)
+        {
+            SelectSet set=sets[s];
+            set.addChange(channel,att);
+            set.wakeup();
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Register a channel
+     * @param channel
+     */
+    public void register(SocketChannel channel)
+    {
+        // The ++ increment here is not atomic, but it does not matter.
+        // so long as the value changes sometimes, then connections will
+        // be distributed over the available sets.
+
+        int s=_set++;
+        if (s<0)
+            s=-s;
+        s=s%_selectSets;
+        SelectSet[] sets=_selectSet;
+        if (sets!=null)
+        {
+            SelectSet set=sets[s];
+            set.addChange(channel);
+            set.wakeup();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Register a {@link ServerSocketChannel}
+     * @param acceptChannel
+     */
+    public void register(ServerSocketChannel acceptChannel)
+    {
+        int s=_set++;
+        if (s<0)
+            s=-s;
+        s=s%_selectSets;
+        SelectSet set=_selectSet[s];
+        set.addChange(acceptChannel);
+        set.wakeup();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return delta The value to add to the selector thread priority.
+     */
+    public int getSelectorPriorityDelta()
+    {
+        return _selectorPriorityDelta;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the selector thread priorty delta.
+     * @param delta The value to add to the selector thread priority.
+     */
+    public void setSelectorPriorityDelta(int delta)
+    {
+        _selectorPriorityDelta=delta;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the lowResourcesConnections
+     */
+    public long getLowResourcesConnections()
+    {
+        return _lowResourcesConnections*_selectSets;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the number of connections, which if exceeded places this manager in low resources state.
+     * This is not an exact measure as the connection count is averaged over the select sets.
+     * @param lowResourcesConnections the number of connections
+     * @see #setLowResourcesMaxIdleTime(long)
+     */
+    public void setLowResourcesConnections(long lowResourcesConnections)
+    {
+        _lowResourcesConnections=(lowResourcesConnections+_selectSets-1)/_selectSets;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the lowResourcesMaxIdleTime
+     */
+    public long getLowResourcesMaxIdleTime()
+    {
+        return _lowResourcesMaxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param lowResourcesMaxIdleTime the period in ms that a connection is allowed to be idle when this SelectSet has more connections than {@link #getLowResourcesConnections()}
+     * @see #setMaxIdleTime(long)
+     */
+    public void setLowResourcesMaxIdleTime(long lowResourcesMaxIdleTime)
+    {
+        _lowResourcesMaxIdleTime=(int)lowResourcesMaxIdleTime;
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    public abstract boolean dispatch(Runnable task);
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see org.eclipse.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _selectSet = new SelectSet[_selectSets];
+        for (int i=0;i<_selectSet.length;i++)
+            _selectSet[i]= new SelectSet(i);
+
+        super.doStart();
+
+        // start a thread to Select
+        for (int i=0;i<getSelectSets();i++)
+        {
+            final int id=i;
+            boolean selecting=dispatch(new Runnable()
+            {
+                public void run()
+                {
+                    String name=Thread.currentThread().getName();
+                    int priority=Thread.currentThread().getPriority();
+                    try
+                    {
+                        SelectSet[] sets=_selectSet;
+                        if (sets==null)
+                            return;
+                        SelectSet set=sets[id];
+
+                        Thread.currentThread().setName(name+" Selector"+id);
+                        if (getSelectorPriorityDelta()!=0)
+                            Thread.currentThread().setPriority(Thread.currentThread().getPriority()+getSelectorPriorityDelta());
+                        LOG.debug("Starting {} on {}",Thread.currentThread(),this);
+                        while (isRunning())
+                        {
+                            try
+                            {
+                                set.doSelect();
+                            }
+                            catch(IOException e)
+                            {
+                                LOG.ignore(e);
+                            }
+                            catch(Exception e)
+                            {
+                                LOG.warn(e);
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        LOG.debug("Stopped {} on {}",Thread.currentThread(),this);
+                        Thread.currentThread().setName(name);
+                        if (getSelectorPriorityDelta()!=0)
+                            Thread.currentThread().setPriority(priority);
+                    }
+                }
+
+            });
+
+            if (!selecting)
+                throw new IllegalStateException("!Selecting");
+        }
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    protected void doStop() throws Exception
+    {
+        SelectSet[] sets= _selectSet;
+        _selectSet=null;
+        if (sets!=null)
+        {
+            for (SelectSet set : sets)
+            {
+                if (set!=null)
+                    set.stop();
+            }
+        }
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param endpoint
+     */
+    protected abstract void endPointClosed(SelectChannelEndPoint endpoint);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param endpoint
+     */
+    protected abstract void endPointOpened(SelectChannelEndPoint endpoint);
+
+    /* ------------------------------------------------------------ */
+    protected abstract void endPointUpgraded(ConnectedEndPoint endpoint,Connection oldConnection);
+
+    /* ------------------------------------------------------------------------------- */
+    public abstract AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new end point
+     * @param channel
+     * @param selectSet
+     * @param sKey the selection key
+     * @return the new endpoint {@link SelectChannelEndPoint}
+     * @throws IOException
+     */
+    protected abstract SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey sKey) throws IOException;
+
+    /* ------------------------------------------------------------------------------- */
+    protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment)
+    {
+        LOG.warn(ex+","+channel+","+attachment);
+        LOG.debug(ex);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        AggregateLifeCycle.dumpObject(out,this);
+        AggregateLifeCycle.dump(out,indent,TypeUtil.asList(_selectSet));
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    public class SelectSet implements Dumpable
+    {
+        private final int _setID;
+        private final Timeout _timeout;
+
+        private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>();
+
+        private volatile Selector _selector;
+
+        private volatile Thread _selecting;
+        private int _busySelects;
+        private long _monitorNext;
+        private boolean _pausing;
+        private boolean _paused;
+        private volatile long _idleTick;
+        private ConcurrentMap<SelectChannelEndPoint,Object> _endPoints = new ConcurrentHashMap<SelectChannelEndPoint, Object>();
+
+        /* ------------------------------------------------------------ */
+        SelectSet(int acceptorID) throws Exception
+        {
+            _setID=acceptorID;
+
+            _idleTick = System.currentTimeMillis();
+            _timeout = new Timeout(this);
+            _timeout.setDuration(0L);
+
+            // create a selector;
+            _selector = Selector.open();
+            _monitorNext=System.currentTimeMillis()+__MONITOR_PERIOD;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void addChange(Object change)
+        {
+            _changes.add(change);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void addChange(SelectableChannel channel, Object att)
+        {
+            if (att==null)
+                addChange(channel);
+            else if (att instanceof EndPoint)
+                addChange(att);
+            else
+                addChange(new ChannelAndAttachment(channel,att));
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Select and dispatch tasks found from changes and the selector.
+         *
+         * @throws IOException
+         */
+        public void doSelect() throws IOException
+        {
+            try
+            {
+                _selecting=Thread.currentThread();
+                final Selector selector=_selector;
+                // Stopped concurrently ?
+                if (selector == null)
+                    return;
+
+                // Make any key changes required
+                Object change;
+                int changes=_changes.size();
+                while (changes-->0 && (change=_changes.poll())!=null)
+                {
+                    Channel ch=null;
+                    SelectionKey key=null;
+
+                    try
+                    {
+                        if (change instanceof EndPoint)
+                        {
+                            // Update the operations for a key.
+                            SelectChannelEndPoint endpoint = (SelectChannelEndPoint)change;
+                            ch=endpoint.getChannel();
+                            endpoint.doUpdateKey();
+                        }
+                        else if (change instanceof ChannelAndAttachment)
+                        {
+                            // finish accepting/connecting this connection
+                            final ChannelAndAttachment asc = (ChannelAndAttachment)change;
+                            final SelectableChannel channel=asc._channel;
+                            ch=channel;
+                            final Object att = asc._attachment;
+
+                            if ((channel instanceof SocketChannel) && ((SocketChannel)channel).isConnected())
+                            {
+                                key = channel.register(selector,SelectionKey.OP_READ,att);
+                                SelectChannelEndPoint endpoint = createEndPoint((SocketChannel)channel,key);
+                                key.attach(endpoint);
+                                endpoint.schedule();
+                            }
+                            else if (channel.isOpen())
+                            {
+                                key = channel.register(selector,SelectionKey.OP_CONNECT,att);
+                            }
+                        }
+                        else if (change instanceof SocketChannel)
+                        {
+                            // Newly registered channel
+                            final SocketChannel channel=(SocketChannel)change;
+                            ch=channel;
+                            key = channel.register(selector,SelectionKey.OP_READ,null);
+                            SelectChannelEndPoint endpoint = createEndPoint(channel,key);
+                            key.attach(endpoint);
+                            endpoint.schedule();
+                        }
+                        else if (change instanceof ChangeTask)
+                        {
+                            ((Runnable)change).run();
+                        }
+                        else if (change instanceof Runnable)
+                        {
+                            dispatch((Runnable)change);
+                        }
+                        else
+                            throw new IllegalArgumentException(change.toString());
+                    }
+                    catch (CancelledKeyException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (Throwable e)
+                    {
+                        if (isRunning())
+                            LOG.warn(e);
+                        else
+                            LOG.debug(e);
+
+                        try
+                        {
+                            if (ch!=null)
+                                ch.close();
+                        }
+                        catch(IOException e2)
+                        {
+                            LOG.debug(e2);
+                        }
+                    }
+                }
+
+
+                // Do and instant select to see if any connections can be handled.
+                int selected=selector.selectNow();
+
+                long now=System.currentTimeMillis();
+
+                // if no immediate things to do
+                if (selected==0 && selector.selectedKeys().isEmpty())
+                {
+                    // If we are in pausing mode
+                    if (_pausing)
+                    {
+                        try
+                        {
+                            Thread.sleep(__BUSY_PAUSE); // pause to reduce impact of  busy loop
+                        }
+                        catch(InterruptedException e)
+                        {
+                            LOG.ignore(e);
+                        }
+                        now=System.currentTimeMillis();
+                    }
+
+                    // workout how long to wait in select
+                    _timeout.setNow(now);
+                    long to_next_timeout=_timeout.getTimeToNext();
+
+                    long wait = _changes.size()==0?__IDLE_TICK:0L;
+                    if (wait > 0 && to_next_timeout >= 0 && wait > to_next_timeout)
+                        wait = to_next_timeout;
+
+                    // If we should wait with a select
+                    if (wait>0)
+                    {
+                        long before=now;
+                        selector.select(wait);
+                        now = System.currentTimeMillis();
+                        _timeout.setNow(now);
+
+                        // If we are monitoring for busy selector
+                        // and this select did not wait more than 1ms
+                        if (__MONITOR_PERIOD>0 && now-before <=1)
+                        {
+                            // count this as a busy select and if there have been too many this monitor cycle
+                            if (++_busySelects>__MAX_SELECTS)
+                            {
+                                // Start injecting pauses
+                                _pausing=true;
+
+                                // if this is the first pause
+                                if (!_paused)
+                                {
+                                    // Log and dump some status
+                                    _paused=true;
+                                    LOG.warn("Selector {} is too busy, pausing!",this);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // have we been destroyed while sleeping
+                if (_selector==null || !selector.isOpen())
+                    return;
+
+                // Look for things to do
+                for (SelectionKey key: selector.selectedKeys())
+                {
+                    SocketChannel channel=null;
+
+                    try
+                    {
+                        if (!key.isValid())
+                        {
+                            key.cancel();
+                            SelectChannelEndPoint endpoint = (SelectChannelEndPoint)key.attachment();
+                            if (endpoint != null)
+                                endpoint.doUpdateKey();
+                            continue;
+                        }
+
+                        Object att = key.attachment();
+                        if (att instanceof SelectChannelEndPoint)
+                        {
+                            if (key.isReadable()||key.isWritable())
+                                ((SelectChannelEndPoint)att).schedule();
+                        }
+                        else if (key.isConnectable())
+                        {
+                            // Complete a connection of a registered channel
+                            channel = (SocketChannel)key.channel();
+                            boolean connected=false;
+                            try
+                            {
+                                connected=channel.finishConnect();
+                            }
+                            catch(Exception e)
+                            {
+                                connectionFailed(channel,e,att);
+                            }
+                            finally
+                            {
+                                if (connected)
+                                {
+                                    key.interestOps(SelectionKey.OP_READ);
+                                    SelectChannelEndPoint endpoint = createEndPoint(channel,key);
+                                    key.attach(endpoint);
+                                    endpoint.schedule();
+                                }
+                                else
+                                {
+                                    key.cancel();
+                                    channel.close();
+                                }
+                            }
+                        }
+                        else
+                        {
+                            // Wrap readable registered channel in an endpoint
+                            channel = (SocketChannel)key.channel();
+                            SelectChannelEndPoint endpoint = createEndPoint(channel,key);
+                            key.attach(endpoint);
+                            if (key.isReadable())
+                                endpoint.schedule();
+                        }
+                        key = null;
+                    }
+                    catch (CancelledKeyException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (Exception e)
+                    {
+                        if (isRunning())
+                            LOG.warn(e);
+                        else
+                            LOG.ignore(e);
+
+                        try
+                        {
+                            if (channel!=null)
+                                channel.close();
+                        }
+                        catch(IOException e2)
+                        {
+                            LOG.debug(e2);
+                        }
+
+                        if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid())
+                            key.cancel();
+                    }
+                }
+
+                // Everything always handled
+                selector.selectedKeys().clear();
+
+                now=System.currentTimeMillis();
+                _timeout.setNow(now);
+                Task task = _timeout.expired();
+                while (task!=null)
+                {
+                    if (task instanceof Runnable)
+                        dispatch((Runnable)task);
+                    task = _timeout.expired();
+                }
+
+                // Idle tick
+                if (now-_idleTick>__IDLE_TICK)
+                {
+                    _idleTick=now;
+
+                    final long idle_now=((_lowResourcesConnections>0 && selector.keys().size()>_lowResourcesConnections))
+                        ?(now+_maxIdleTime-_lowResourcesMaxIdleTime)
+                        :now;
+
+                    dispatch(new Runnable()
+                    {
+                        public void run()
+                        {
+                            for (SelectChannelEndPoint endp:_endPoints.keySet())
+                            {
+                                endp.checkIdleTimestamp(idle_now);
+                            }
+                        }
+                        public String toString() {return "Idle-"+super.toString();}
+                    });
+
+                }
+
+                // Reset busy select monitor counts
+                if (__MONITOR_PERIOD>0 && now>_monitorNext)
+                {
+                    _busySelects=0;
+                    _pausing=false;
+                    _monitorNext=now+__MONITOR_PERIOD;
+
+                }
+            }
+            catch (ClosedSelectorException e)
+            {
+                if (isRunning())
+                    LOG.warn(e);
+                else
+                    LOG.ignore(e);
+            }
+            catch (CancelledKeyException e)
+            {
+                LOG.ignore(e);
+            }
+            finally
+            {
+                _selecting=null;
+            }
+        }
+
+
+        /* ------------------------------------------------------------ */
+        private void renewSelector()
+        {
+            try
+            {
+                synchronized (this)
+                {
+                    Selector selector=_selector;
+                    if (selector==null)
+                        return;
+                    final Selector new_selector = Selector.open();
+                    for (SelectionKey k: selector.keys())
+                    {
+                        if (!k.isValid() || k.interestOps()==0)
+                            continue;
+
+                        final SelectableChannel channel = k.channel();
+                        final Object attachment = k.attachment();
+
+                        if (attachment==null)
+                            addChange(channel);
+                        else
+                            addChange(channel,attachment);
+                    }
+                    _selector.close();
+                    _selector=new_selector;
+                }
+            }
+            catch(IOException e)
+            {
+                throw new RuntimeException("recreating selector",e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public SelectorManager getManager()
+        {
+            return SelectorManager.this;
+        }
+
+        /* ------------------------------------------------------------ */
+        public long getNow()
+        {
+            return _timeout.getNow();
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @param task The task to timeout. If it implements Runnable, then
+         * expired will be called from a dispatched thread.
+         *
+         * @param timeoutMs
+         */
+        public void scheduleTimeout(Timeout.Task task, long timeoutMs)
+        {
+            if (!(task instanceof Runnable))
+                throw new IllegalArgumentException("!Runnable");
+            _timeout.schedule(task, timeoutMs);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void cancelTimeout(Timeout.Task task)
+        {
+            task.cancel();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void wakeup()
+        {
+            try
+            {
+                Selector selector = _selector;
+                if (selector!=null)
+                    selector.wakeup();
+            }
+            catch(Exception e)
+            {
+                addChange(new ChangeTask()
+                {
+                    public void run()
+                    {
+                        renewSelector();
+                    }
+                });
+
+                renewSelector();
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        private SelectChannelEndPoint createEndPoint(SocketChannel channel, SelectionKey sKey) throws IOException
+        {
+            SelectChannelEndPoint endp = newEndPoint(channel,this,sKey);
+            LOG.debug("created {}",endp);
+            endPointOpened(endp);
+            _endPoints.put(endp,this);
+            return endp;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void destroyEndPoint(SelectChannelEndPoint endp)
+        {
+            LOG.debug("destroyEndPoint {}",endp);
+            _endPoints.remove(endp);
+            endPointClosed(endp);
+        }
+
+        /* ------------------------------------------------------------ */
+        Selector getSelector()
+        {
+            return _selector;
+        }
+
+        /* ------------------------------------------------------------ */
+        void stop() throws Exception
+        {
+            // Spin for a while waiting for selector to complete
+            // to avoid unneccessary closed channel exceptions
+            try
+            {
+                for (int i=0;i<100 && _selecting!=null;i++)
+                {
+                    wakeup();
+                    Thread.sleep(10);
+                }
+            }
+            catch(Exception e)
+            {
+                LOG.ignore(e);
+            }
+
+            // close endpoints and selector
+            synchronized (this)
+            {
+                Selector selector=_selector;
+                for (SelectionKey key:selector.keys())
+                {
+                    if (key==null)
+                        continue;
+                    Object att=key.attachment();
+                    if (att instanceof EndPoint)
+                    {
+                        EndPoint endpoint = (EndPoint)att;
+                        try
+                        {
+                            endpoint.close();
+                        }
+                        catch(IOException e)
+                        {
+                            LOG.ignore(e);
+                        }
+                    }
+                }
+
+
+                _timeout.cancelAll();
+                try
+                {
+                    selector=_selector;
+                    if (selector != null)
+                        selector.close();
+                }
+                catch (IOException e)
+                {
+                    LOG.ignore(e);
+                }
+                _selector=null;
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public String dump()
+        {
+            return AggregateLifeCycle.dump(this);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void dump(Appendable out, String indent) throws IOException
+        {
+            out.append(String.valueOf(this)).append(" id=").append(String.valueOf(_setID)).append("\n");
+
+            Thread selecting = _selecting;
+
+            Object where = "not selecting";
+            StackTraceElement[] trace =selecting==null?null:selecting.getStackTrace();
+            if (trace!=null)
+            {
+                for (StackTraceElement t:trace)
+                    if (t.getClassName().startsWith("org.eclipse.jetty."))
+                    {
+                        where=t;
+                        break;
+                    }
+            }
+
+            Selector selector=_selector;
+            if (selector!=null)
+            {
+                final ArrayList<Object> dump = new ArrayList<Object>(selector.keys().size()*2);
+                dump.add(where);
+
+                final CountDownLatch latch = new CountDownLatch(1);
+
+                addChange(new ChangeTask()
+                {
+                    public void run()
+                    {
+                        dumpKeyState(dump);
+                        latch.countDown();
+                    }
+                });
+
+                try
+                {
+                    latch.await(5,TimeUnit.SECONDS);
+                }
+                catch(InterruptedException e)
+                {
+                    LOG.ignore(e);
+                }
+
+                AggregateLifeCycle.dump(out,indent,dump);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public void dumpKeyState(List<Object> dumpto)
+        {
+            Selector selector=_selector;
+            Set<SelectionKey> keys = selector.keys();
+            dumpto.add(selector + " keys=" + keys.size());
+            for (SelectionKey key: keys)
+            {
+                if (key.isValid())
+                    dumpto.add(key.attachment()+" iOps="+key.interestOps()+" rOps="+key.readyOps());
+                else
+                    dumpto.add(key.attachment()+" iOps=-1 rOps=-1");
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public String toString()
+        {
+            Selector selector=_selector;
+            return String.format("%s keys=%d selected=%d",
+                    super.toString(),
+                    selector != null && selector.isOpen() ? selector.keys().size() : -1,
+                    selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private static class ChannelAndAttachment
+    {
+        final SelectableChannel _channel;
+        final Object _attachment;
+
+        public ChannelAndAttachment(SelectableChannel channel, Object attachment)
+        {
+            super();
+            _channel = channel;
+            _attachment = attachment;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isDeferringInterestedOps0()
+    {
+        return _deferringInterestedOps0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setDeferringInterestedOps0(boolean deferringInterestedOps0)
+    {
+        _deferringInterestedOps0 = deferringInterestedOps0;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private interface ChangeTask extends Runnable
+    {}
+
+}
diff --git a/src/java/org/eclipse/jetty/io/nio/SslConnection.java b/src/java/org/eclipse/jetty/io/nio/SslConnection.java
new file mode 100644
index 0000000..3d27606
--- /dev/null
+++ b/src/java/org/eclipse/jetty/io/nio/SslConnection.java
@@ -0,0 +1,865 @@
+//
+//  ========================================================================
+//  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.io.nio;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout.Task;
+
+/* ------------------------------------------------------------ */
+/** SSL Connection.
+ * An AysyncConnection that acts as an interceptor between and EndPoint and another
+ * Connection, that implements TLS encryption using an {@link SSLEngine}.
+ * <p>
+ * The connector uses an {@link AsyncEndPoint} (like {@link SelectChannelEndPoint}) as
+ * it's source/sink of encrypted data.   It then provides {@link #getSslEndPoint()} to
+ * expose a source/sink of unencrypted data to another connection (eg HttpConnection).
+ */
+public class SslConnection extends AbstractConnection implements AsyncConnection
+{
+    private final Logger _logger = Log.getLogger("org.eclipse.jetty.io.nio.ssl");
+
+    private static final NIOBuffer __ZERO_BUFFER=new IndirectNIOBuffer(0);
+
+    private static final ThreadLocal<SslBuffers> __buffers = new ThreadLocal<SslBuffers>();
+    private final SSLEngine _engine;
+    private final SSLSession _session;
+    private AsyncConnection _connection;
+    private final SslEndPoint _sslEndPoint;
+    private int _allocations;
+    private SslBuffers _buffers;
+    private NIOBuffer _inbound;
+    private NIOBuffer _unwrapBuf;
+    private NIOBuffer _outbound;
+    private AsyncEndPoint _aEndp;
+    private boolean _allowRenegotiate=true;
+    private boolean _handshook;
+    private boolean _ishut;
+    private boolean _oshut;
+    private final AtomicBoolean _progressed = new AtomicBoolean();
+
+    /* ------------------------------------------------------------ */
+    /* this is a half baked buffer pool
+     */
+    private static class SslBuffers
+    {
+        final NIOBuffer _in;
+        final NIOBuffer _out;
+        final NIOBuffer _unwrap;
+
+        SslBuffers(int packetSize, int appSize)
+        {
+            _in=new IndirectNIOBuffer(packetSize);
+            _out=new IndirectNIOBuffer(packetSize);
+            _unwrap=new IndirectNIOBuffer(appSize);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public SslConnection(SSLEngine engine,EndPoint endp)
+    {
+        this(engine,endp,System.currentTimeMillis());
+    }
+
+    /* ------------------------------------------------------------ */
+    public SslConnection(SSLEngine engine,EndPoint endp, long timeStamp)
+    {
+        super(endp,timeStamp);
+        _engine=engine;
+        _session=_engine.getSession();
+        _aEndp=(AsyncEndPoint)endp;
+        _sslEndPoint = newSslEndPoint();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected SslEndPoint newSslEndPoint()
+    {
+        return new SslEndPoint();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL re-negotiation is allowed (default false)
+     */
+    public boolean isAllowRenegotiate()
+    {
+        return _allowRenegotiate;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
+     * does not have CVE-2009-3555 fixed, then re-negotiation should
+     * not be allowed.  CVE-2009-3555 was fixed in Sun java 1.6 with a ban
+     * of renegotiates in u19 and with RFC5746 in u22.
+     *
+     * @param allowRenegotiate
+     *            true if re-negotiation is allowed (default false)
+     */
+    public void setAllowRenegotiate(boolean allowRenegotiate)
+    {
+        _allowRenegotiate = allowRenegotiate;
+    }
+
+    /* ------------------------------------------------------------ */
+    private void allocateBuffers()
+    {
+        synchronized (this)
+        {
+            if (_allocations++==0)
+            {
+                if (_buffers==null)
+                {
+                    _buffers=__buffers.get();
+                    if (_buffers==null)
+                        _buffers=new SslBuffers(_session.getPacketBufferSize()*2,_session.getApplicationBufferSize()*2);
+                    _inbound=_buffers._in;
+                    _outbound=_buffers._out;
+                    _unwrapBuf=_buffers._unwrap;
+                    __buffers.set(null);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void releaseBuffers()
+    {
+        synchronized (this)
+        {
+            if (--_allocations==0)
+            {
+                if (_buffers!=null &&
+                    _inbound.length()==0 &&
+                    _outbound.length()==0 &&
+                    _unwrapBuf.length()==0)
+                {
+                    _inbound=null;
+                    _outbound=null;
+                    _unwrapBuf=null;
+                    __buffers.set(_buffers);
+                    _buffers=null;
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection handle() throws IOException
+    {
+        try
+        {
+            allocateBuffers();
+
+            boolean progress=true;
+
+            while (progress)
+            {
+                progress=false;
+
+                // If we are handshook let the delegate connection
+                if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING)
+                    progress=process(null,null);
+
+                // handle the delegate connection
+                AsyncConnection next = (AsyncConnection)_connection.handle();
+                if (next!=_connection && next!=null)
+                {
+                    _connection=next;
+                    progress=true;
+                }
+
+                _logger.debug("{} handle {} progress={}", _session, this, progress);
+            }
+        }
+        finally
+        {
+            releaseBuffers();
+
+            if (!_ishut && _sslEndPoint.isInputShutdown() && _sslEndPoint.isOpen())
+            {
+                _ishut=true;
+                try
+                {
+                    _connection.onInputShutdown();
+                }
+                catch(Throwable x)
+                {
+                    _logger.warn("onInputShutdown failed", x);
+                    try{_sslEndPoint.close();}
+                    catch(IOException e2){
+                        _logger.ignore(e2);}
+                }
+            }
+        }
+
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        Connection connection = _sslEndPoint.getConnection();
+        if (connection != null && connection != this)
+            connection.onClose();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void onIdleExpired(long idleForMs)
+    {
+        try
+        {
+            _logger.debug("onIdleExpired {}ms on {}",idleForMs,this);
+            if (_endp.isOutputShutdown())
+                _sslEndPoint.close();
+            else
+                _sslEndPoint.shutdownOutput();
+        }
+        catch (IOException e)
+        {
+            _logger.warn(e);
+            super.onIdleExpired(idleForMs);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onInputShutdown() throws IOException
+    {
+
+    }
+
+    /* ------------------------------------------------------------ */
+    private synchronized boolean process(Buffer toFill, Buffer toFlush) throws IOException
+    {
+        boolean some_progress=false;
+        try
+        {
+            // We need buffers to progress
+            allocateBuffers();
+
+            // if we don't have a buffer to put received data into
+            if (toFill==null)
+            {
+                // use the unwrapbuffer to hold received data.
+                _unwrapBuf.compact();
+                toFill=_unwrapBuf;
+            }
+            // Else if the fill buffer is too small for the SSL session
+            else if (toFill.capacity()<_session.getApplicationBufferSize())
+            {
+                // fill to the temporary unwrapBuffer
+                boolean progress=process(null,toFlush);
+
+                // if we received any data,
+                if (_unwrapBuf!=null && _unwrapBuf.hasContent())
+                {
+                    // transfer from temp buffer to fill buffer
+                    _unwrapBuf.skip(toFill.put(_unwrapBuf));
+                    return true;
+                }
+                else
+                    // return progress from recursive call
+                    return progress;
+            }
+            // Else if there is some temporary data
+            else if (_unwrapBuf!=null && _unwrapBuf.hasContent())
+            {
+                // transfer from temp buffer to fill buffer
+                _unwrapBuf.skip(toFill.put(_unwrapBuf));
+                return true;
+            }
+
+            // If we are here, we have a buffer ready into which we can put some read data.
+
+            // If we have no data to flush, flush the empty buffer
+            if (toFlush==null)
+                toFlush=__ZERO_BUFFER;
+
+            // While we are making progress processing SSL engine
+            boolean progress=true;
+            while (progress)
+            {
+                progress=false;
+
+                // Do any real IO
+                int filled=0,flushed=0;
+                try
+                {
+                    // Read any available data
+                    if (_inbound.space()>0 && (filled=_endp.fill(_inbound))>0)
+                        progress = true;
+
+                    // flush any output data
+                    if (_outbound.hasContent() && (flushed=_endp.flush(_outbound))>0)
+                        progress = true;
+                }
+                catch (IOException e)
+                {
+                    _endp.close();
+                    throw e;
+                }
+                finally
+                {
+                    _logger.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.length(),flushed,_outbound.length());
+                }
+
+                // handle the current hand share status
+                switch(_engine.getHandshakeStatus())
+                {
+                    case FINISHED:
+                        throw new IllegalStateException();
+
+                    case NOT_HANDSHAKING:
+                    {
+                        // Try unwrapping some application data
+                        if (toFill.space()>0 && _inbound.hasContent() && unwrap(toFill))
+                            progress=true;
+
+                        // Try wrapping some application data
+                        if (toFlush.hasContent() && _outbound.space()>0 && wrap(toFlush))
+                            progress=true;
+                    }
+                    break;
+
+                    case NEED_TASK:
+                    {
+                        // A task needs to be run, so run it!
+                        Runnable task;
+                        while ((task=_engine.getDelegatedTask())!=null)
+                        {
+                            progress=true;
+                            task.run();
+                        }
+
+                    }
+                    break;
+
+                    case NEED_WRAP:
+                    {
+                        // The SSL needs to send some handshake data to the other side
+                        if (_handshook && !_allowRenegotiate)
+                            _endp.close();
+                        else if (wrap(toFlush))
+                            progress=true;
+                    }
+                    break;
+
+                    case NEED_UNWRAP:
+                    {
+                        // The SSL needs to receive some handshake data from the other side
+                        if (_handshook && !_allowRenegotiate)
+                            _endp.close();
+                        else if (!_inbound.hasContent()&&filled==-1)
+                        {
+                            // No more input coming
+                            _endp.shutdownInput();
+                        }
+                        else if (unwrap(toFill))
+                            progress=true;
+                    }
+                    break;
+                }
+
+                // pass on ishut/oshut state
+                if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasContent())
+                    closeInbound();
+
+                if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent())
+                    _endp.shutdownOutput();
+
+                // remember if any progress has been made
+                some_progress|=progress;
+            }
+
+            // If we are reading into the temp buffer and it has some content, then we should be dispatched.
+            if (toFill==_unwrapBuf && _unwrapBuf.hasContent() && !_connection.isSuspended())
+                _aEndp.dispatch();
+        }
+        finally
+        {
+            releaseBuffers();
+            if (some_progress)
+                _progressed.set(true);
+        }
+        return some_progress;
+    }
+
+    private void closeInbound()
+    {
+        try
+        {
+            _engine.closeInbound();
+        }
+        catch (SSLException x)
+        {
+            _logger.debug(x);
+        }
+    }
+
+    private synchronized boolean wrap(final Buffer buffer) throws IOException
+    {
+        ByteBuffer bbuf=extractByteBuffer(buffer);
+        final SSLEngineResult result;
+
+        synchronized(bbuf)
+        {
+            _outbound.compact();
+            ByteBuffer out_buffer=_outbound.getByteBuffer();
+            synchronized(out_buffer)
+            {
+                try
+                {
+                    bbuf.position(buffer.getIndex());
+                    bbuf.limit(buffer.putIndex());
+                    out_buffer.position(_outbound.putIndex());
+                    out_buffer.limit(out_buffer.capacity());
+                    result=_engine.wrap(bbuf,out_buffer);
+                    if (_logger.isDebugEnabled())
+                        _logger.debug("{} wrap {} {} consumed={} produced={}",
+                            _session,
+                            result.getStatus(),
+                            result.getHandshakeStatus(),
+                            result.bytesConsumed(),
+                            result.bytesProduced());
+
+
+                    buffer.skip(result.bytesConsumed());
+                    _outbound.setPutIndex(_outbound.putIndex()+result.bytesProduced());
+                }
+                catch(SSLException e)
+                {
+                    _logger.debug(String.valueOf(_endp), e);
+                    _endp.close();
+                    throw e;
+                }
+                finally
+                {
+                    out_buffer.position(0);
+                    out_buffer.limit(out_buffer.capacity());
+                    bbuf.position(0);
+                    bbuf.limit(bbuf.capacity());
+                }
+            }
+        }
+
+        switch(result.getStatus())
+        {
+            case BUFFER_UNDERFLOW:
+                throw new IllegalStateException();
+
+            case BUFFER_OVERFLOW:
+                break;
+
+            case OK:
+                if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+                    _handshook=true;
+                break;
+
+            case CLOSED:
+                _logger.debug("wrap CLOSE {} {}",this,result);
+                if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+                    _endp.close();
+                break;
+
+            default:
+                _logger.debug("{} wrap default {}",_session,result);
+            throw new IOException(result.toString());
+        }
+
+        return result.bytesConsumed()>0 || result.bytesProduced()>0;
+    }
+
+    private synchronized boolean unwrap(final Buffer buffer) throws IOException
+    {
+        if (!_inbound.hasContent())
+            return false;
+
+        ByteBuffer bbuf=extractByteBuffer(buffer);
+        final SSLEngineResult result;
+
+        synchronized(bbuf)
+        {
+            ByteBuffer in_buffer=_inbound.getByteBuffer();
+            synchronized(in_buffer)
+            {
+                try
+                {
+                    bbuf.position(buffer.putIndex());
+                    bbuf.limit(buffer.capacity());
+                    in_buffer.position(_inbound.getIndex());
+                    in_buffer.limit(_inbound.putIndex());
+
+                    result=_engine.unwrap(in_buffer,bbuf);
+                    if (_logger.isDebugEnabled())
+                        _logger.debug("{} unwrap {} {} consumed={} produced={}",
+                            _session,
+                            result.getStatus(),
+                            result.getHandshakeStatus(),
+                            result.bytesConsumed(),
+                            result.bytesProduced());
+
+                    _inbound.skip(result.bytesConsumed());
+                    _inbound.compact();
+                    buffer.setPutIndex(buffer.putIndex()+result.bytesProduced());
+                }
+                catch(SSLException e)
+                {
+                    _logger.debug(String.valueOf(_endp), e);
+                    _endp.close();
+                    throw e;
+                }
+                finally
+                {
+                    in_buffer.position(0);
+                    in_buffer.limit(in_buffer.capacity());
+                    bbuf.position(0);
+                    bbuf.limit(bbuf.capacity());
+                }
+            }
+        }
+
+        switch(result.getStatus())
+        {
+            case BUFFER_UNDERFLOW:
+                if (_endp.isInputShutdown())
+                    _inbound.clear();
+                break;
+
+            case BUFFER_OVERFLOW:
+                if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
+                break;
+
+            case OK:
+                if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+                    _handshook=true;
+                break;
+
+            case CLOSED:
+                _logger.debug("unwrap CLOSE {} {}",this,result);
+                if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
+                    _endp.close();
+                break;
+
+            default:
+                _logger.debug("{} wrap default {}",_session,result);
+            throw new IOException(result.toString());
+        }
+
+        //if (LOG.isDebugEnabled() && result.bytesProduced()>0)
+        //    LOG.debug("{} unwrapped '{}'",_session,buffer);
+
+        return result.bytesConsumed()>0 || result.bytesProduced()>0;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private ByteBuffer extractByteBuffer(Buffer buffer)
+    {
+        if (buffer.buffer() instanceof NIOBuffer)
+            return ((NIOBuffer)buffer.buffer()).getByteBuffer();
+        return ByteBuffer.wrap(buffer.array());
+    }
+
+    /* ------------------------------------------------------------ */
+    public AsyncEndPoint getSslEndPoint()
+    {
+        return _sslEndPoint;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return String.format("%s %s", super.toString(), _sslEndPoint);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class SslEndPoint implements AsyncEndPoint
+    {
+        public SSLEngine getSslEngine()
+        {
+            return _engine;
+        }
+
+        public AsyncEndPoint getEndpoint()
+        {
+            return _aEndp;
+        }
+
+        public void shutdownOutput() throws IOException
+        {
+            synchronized (SslConnection.this)
+            {
+                _logger.debug("{} ssl endp.oshut {}",_session,this);
+                _engine.closeOutbound();
+                _oshut=true;
+            }
+            flush();
+        }
+
+        public boolean isOutputShutdown()
+        {
+            synchronized (SslConnection.this)
+            {
+                return _oshut||!isOpen()||_engine.isOutboundDone();
+            }
+        }
+
+        public void shutdownInput() throws IOException
+        {
+            _logger.debug("{} ssl endp.ishut!",_session);
+            // We do not do a closeInput here, as SSL does not support half close.
+            // isInputShutdown works it out itself from buffer state and underlying endpoint state.
+        }
+
+        public boolean isInputShutdown()
+        {
+            synchronized (SslConnection.this)
+            {
+                return _endp.isInputShutdown() &&
+                !(_unwrapBuf!=null&&_unwrapBuf.hasContent()) &&
+                !(_inbound!=null&&_inbound.hasContent());
+            }
+        }
+
+        public void close() throws IOException
+        {
+            _logger.debug("{} ssl endp.close",_session);
+            _endp.close();
+        }
+
+        public int fill(Buffer buffer) throws IOException
+        {
+            int size=buffer.length();
+            process(buffer, null);
+
+            int filled=buffer.length()-size;
+
+            if (filled==0 && isInputShutdown())
+                return -1;
+            return filled;
+        }
+
+        public int flush(Buffer buffer) throws IOException
+        {
+            int size = buffer.length();
+            process(null, buffer);
+            return size-buffer.length();
+        }
+
+        public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+        {
+            if (header!=null && header.hasContent())
+                return flush(header);
+            if (buffer!=null && buffer.hasContent())
+                return flush(buffer);
+            if (trailer!=null && trailer.hasContent())
+                return flush(trailer);
+            return 0;
+        }
+
+        public boolean blockReadable(long millisecs) throws IOException
+        {
+            long now = System.currentTimeMillis();
+            long end=millisecs>0?(now+millisecs):Long.MAX_VALUE;
+
+            while (now<end)
+            {
+                if (process(null,null))
+                    break;
+                _endp.blockReadable(end-now);
+                now = System.currentTimeMillis();
+            }
+
+            return now<end;
+        }
+
+        public boolean blockWritable(long millisecs) throws IOException
+        {
+            return _endp.blockWritable(millisecs);
+        }
+
+        public boolean isOpen()
+        {
+            return _endp.isOpen();
+        }
+
+        public Object getTransport()
+        {
+            return _endp;
+        }
+
+        public void flush() throws IOException
+        {
+            process(null, null);
+        }
+
+        public void dispatch()
+        {
+            _aEndp.dispatch();
+        }
+
+        public void asyncDispatch()
+        {
+            _aEndp.asyncDispatch();
+        }
+
+        public void scheduleWrite()
+        {
+            _aEndp.scheduleWrite();
+        }
+
+        public void onIdleExpired(long idleForMs)
+        {
+            _aEndp.onIdleExpired(idleForMs);
+        }
+
+        public void setCheckForIdle(boolean check)
+        {
+            _aEndp.setCheckForIdle(check);
+        }
+
+        public boolean isCheckForIdle()
+        {
+            return _aEndp.isCheckForIdle();
+        }
+
+        public void scheduleTimeout(Task task, long timeoutMs)
+        {
+            _aEndp.scheduleTimeout(task,timeoutMs);
+        }
+
+        public void cancelTimeout(Task task)
+        {
+            _aEndp.cancelTimeout(task);
+        }
+
+        public boolean isWritable()
+        {
+            return _aEndp.isWritable();
+        }
+
+        public boolean hasProgressed()
+        {
+            return _progressed.getAndSet(false);
+        }
+
+        public String getLocalAddr()
+        {
+            return _aEndp.getLocalAddr();
+        }
+
+        public String getLocalHost()
+        {
+            return _aEndp.getLocalHost();
+        }
+
+        public int getLocalPort()
+        {
+            return _aEndp.getLocalPort();
+        }
+
+        public String getRemoteAddr()
+        {
+            return _aEndp.getRemoteAddr();
+        }
+
+        public String getRemoteHost()
+        {
+            return _aEndp.getRemoteHost();
+        }
+
+        public int getRemotePort()
+        {
+            return _aEndp.getRemotePort();
+        }
+
+        public boolean isBlocking()
+        {
+            return false;
+        }
+
+        public int getMaxIdleTime()
+        {
+            return _aEndp.getMaxIdleTime();
+        }
+
+        public void setMaxIdleTime(int timeMs) throws IOException
+        {
+            _aEndp.setMaxIdleTime(timeMs);
+        }
+
+        public Connection getConnection()
+        {
+            return _connection;
+        }
+
+        public void setConnection(Connection connection)
+        {
+            _connection=(AsyncConnection)connection;
+        }
+
+        public String toString()
+        {
+            // Do NOT use synchronized (SslConnection.this)
+            // because it's very easy to deadlock when debugging is enabled.
+            // We do a best effort to print the right toString() and that's it.
+            Buffer inbound = _inbound;
+            Buffer outbound = _outbound;
+            Buffer unwrap = _unwrapBuf;
+            int i = inbound == null? -1 : inbound.length();
+            int o = outbound == null ? -1 : outbound.length();
+            int u = unwrap == null ? -1 : unwrap.length();
+            return String.format("SSL %s i/o/u=%d/%d/%d ishut=%b oshut=%b {%s}",
+                    _engine.getHandshakeStatus(),
+                    i, o, u,
+                    _ishut, _oshut,
+                    _connection);
+        }
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/jmx/ConnectorServer.java b/src/java/org/eclipse/jetty/jmx/ConnectorServer.java
new file mode 100644
index 0000000..a00772a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/jmx/ConnectorServer.java
@@ -0,0 +1,195 @@
+//
+//  ========================================================================
+//  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.jmx;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.Map;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ShutdownThread;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * AbstractLifeCycle wrapper for JMXConnector Server
+ */
+public class ConnectorServer extends AbstractLifeCycle
+{
+    private static final Logger LOG = Log.getLogger(ConnectorServer.class);
+
+    JMXConnectorServer _connectorServer;
+    Registry _registry;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructs connector server
+     * 
+     * @param serviceURL the address of the new connector server.
+     * The actual address of the new connector server, as returned 
+     * by its getAddress method, will not necessarily be exactly the same.
+     * @param name object name string to be assigned to connector server bean
+     * @throws Exception
+     */
+    public ConnectorServer(JMXServiceURL serviceURL, String name)
+        throws Exception
+    {
+        this(serviceURL, null, name);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructs connector server
+     * 
+     * @param svcUrl the address of the new connector server.
+     * The actual address of the new connector server, as returned 
+     * by its getAddress method, will not necessarily be exactly the same.
+     * @param environment  a set of attributes to control the new connector
+     * server's behavior. This parameter can be null. Keys in this map must
+     * be Strings. The appropriate type of each associated value depends on
+     * the attribute. The contents of environment are not changed by this call. 
+     * @param name object name string to be assigned to connector server bean
+     * @throws Exception
+     */
+    public ConnectorServer(JMXServiceURL svcUrl, Map<String,?> environment, String name)
+         throws Exception
+    {
+    	String urlPath = svcUrl.getURLPath();
+    	int idx = urlPath.indexOf("rmi://");
+    	if (idx > 0)
+    	{
+    	    String hostPort = urlPath.substring(idx+6, urlPath.indexOf('/', idx+6));
+    	    String regHostPort = startRegistry(hostPort);
+    	    if (regHostPort != null) {
+    	        urlPath = urlPath.replace(hostPort,regHostPort);
+    	        svcUrl = new JMXServiceURL(svcUrl.getProtocol(), svcUrl.getHost(), svcUrl.getPort(), urlPath);
+    	    }
+    	}
+        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+        _connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(svcUrl, environment, mbeanServer);
+        mbeanServer.registerMBean(_connectorServer,new ObjectName(name));
+    }
+
+	/* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    public void doStart()
+        throws Exception
+    {
+        _connectorServer.start();
+        ShutdownThread.register(0, this);       
+        
+        LOG.info("JMX Remote URL: {}", _connectorServer.getAddress().toString());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    @Override
+    public void doStop()
+        throws Exception
+    {
+        ShutdownThread.deregister(this);
+        _connectorServer.stop();
+        stopRegistry();
+    }
+
+    /**
+     * Check that local RMI registry is used, and ensure it is started. If local RMI registry is being used and not started, start it.
+     * 
+     * @param hostPath
+     *            hostname and port number of RMI registry
+     * @throws Exception
+     */
+    private String startRegistry(String hostPath) throws Exception
+    {
+        int rmiPort = 1099; // default RMI registry port
+        String rmiHost = hostPath;
+
+        int idx = hostPath.indexOf(':');
+        if (idx > 0)
+        {
+            rmiPort = Integer.parseInt(hostPath.substring(idx + 1));
+            rmiHost = hostPath.substring(0,idx);
+        }
+
+        // Verify that local registry is being used
+        InetAddress hostAddress = InetAddress.getByName(rmiHost);
+        if(hostAddress.isLoopbackAddress())
+        {
+            if (rmiPort == 0)
+            {
+                ServerSocket socket = new ServerSocket(0);
+                rmiPort = socket.getLocalPort();
+                socket.close();
+            }
+            else
+            {
+                try
+                {
+                    // Check if a local registry is already running
+                    LocateRegistry.getRegistry(rmiPort).list();
+                    return null;
+                }
+                catch (Exception ex)
+                {
+                    LOG.ignore(ex);
+                }
+            }
+
+            _registry = LocateRegistry.createRegistry(rmiPort);
+            Thread.sleep(1000);
+            
+            rmiHost = InetAddress.getLocalHost().getCanonicalHostName();
+            return rmiHost + ':' + Integer.toString(rmiPort);
+        }
+        
+        return null;
+    }
+
+    private void stopRegistry()
+    {
+        if (_registry != null)
+        {
+            try
+            {
+                UnicastRemoteObject.unexportObject(_registry,true);
+            }
+            catch (Exception ex)
+            {
+                LOG.ignore(ex);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/jmx/MBeanContainer.java b/src/java/org/eclipse/jetty/jmx/MBeanContainer.java
new file mode 100644
index 0000000..00a031f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -0,0 +1,366 @@
+//
+//  ========================================================================
+//  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.jmx;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Container;
+import org.eclipse.jetty.util.component.Container.Relationship;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.log.StdErrLog;
+import org.eclipse.jetty.util.thread.ShutdownThread;
+
+/**
+ * Container class for the MBean instances
+ */
+public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable
+{
+    private final static Logger LOG = Log.getLogger(MBeanContainer.class.getName());
+    private final static HashMap<String, Integer> __unique = new HashMap<String, Integer>();
+    
+    public final static void resetUnique()
+    {
+        synchronized (__unique)
+        {
+            __unique.clear();
+        }
+    }
+    
+    private final MBeanServer _server;
+    private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
+    private final WeakHashMap<ObjectName,List<Container.Relationship>> _relations = new WeakHashMap<ObjectName,List<Container.Relationship>>();
+    private String _domain = null;
+
+    /**
+     * Lookup an object name by instance
+     *
+     * @param object instance for which object name is looked up
+     * @return object name associated with specified instance, or null if not found
+     */
+    public synchronized ObjectName findMBean(Object object)
+    {
+        ObjectName bean = _beans.get(object);
+        return bean == null ? null : bean;
+    }
+
+    /**
+     * Lookup an instance by object name
+     *
+     * @param oname object name of instance
+     * @return instance associated with specified object name, or null if not found
+     */
+    public synchronized Object findBean(ObjectName oname)
+    {
+        for (Map.Entry<Object, ObjectName> entry : _beans.entrySet())
+        {
+            ObjectName bean = entry.getValue();
+            if (bean.equals(oname))
+                return entry.getKey();
+        }
+        return null;
+    }
+
+    /**
+     * Constructs MBeanContainer
+     *
+     * @param server instance of MBeanServer for use by container
+     */
+    public MBeanContainer(MBeanServer server)
+    {
+        _server = server;
+    }
+
+    /**
+     * Retrieve instance of MBeanServer used by container
+     *
+     * @return instance of MBeanServer
+     */
+    public MBeanServer getMBeanServer()
+    {
+        return _server;
+    }
+
+    /**
+     * Set domain to be used to add MBeans
+     *
+     * @param domain domain name
+     */
+    public void setDomain(String domain)
+    {
+        _domain = domain;
+    }
+
+    /**
+     * Retrieve domain name used to add MBeans
+     *
+     * @return domain name
+     */
+    public String getDomain()
+    {
+        return _domain;
+    }
+
+    /**
+     * Implementation of Container.Listener interface
+     *
+     * @see org.eclipse.jetty.util.component.Container.Listener#add(org.eclipse.jetty.util.component.Container.Relationship)
+     */
+    public synchronized void add(Relationship relationship)
+    {
+        LOG.debug("add {}",relationship);
+        ObjectName parent = _beans.get(relationship.getParent());
+        if (parent == null)
+        {
+            addBean(relationship.getParent());
+            parent = _beans.get(relationship.getParent());
+        }
+
+        ObjectName child = _beans.get(relationship.getChild());
+        if (child == null)
+        {
+            addBean(relationship.getChild());
+            child = _beans.get(relationship.getChild());
+        }
+
+        if (parent != null && child != null)
+        {
+            List<Container.Relationship> rels = _relations.get(parent);
+            if (rels==null)
+            {
+                rels=new ArrayList<Container.Relationship>();
+                _relations.put(parent,rels);
+            }
+            rels.add(relationship);
+        }
+    }
+
+    /**
+     * Implementation of Container.Listener interface
+     *
+     * @see org.eclipse.jetty.util.component.Container.Listener#remove(org.eclipse.jetty.util.component.Container.Relationship)
+     */
+    public synchronized void remove(Relationship relationship)
+    {
+        LOG.debug("remove {}",relationship);
+        ObjectName parent = _beans.get(relationship.getParent());
+        ObjectName child = _beans.get(relationship.getChild());
+
+        if (parent != null && child != null)
+        {
+            List<Container.Relationship> rels = _relations.get(parent);
+            if (rels!=null)
+            {
+                for (Iterator<Container.Relationship> i=rels.iterator();i.hasNext();)
+                {
+                    Container.Relationship r = i.next();
+                    if (relationship.equals(r) || r.getChild()==null)
+                        i.remove();
+                }
+            }
+        }
+    }
+
+    /**
+     * Implementation of Container.Listener interface
+     *
+     * @see org.eclipse.jetty.util.component.Container.Listener#removeBean(java.lang.Object)
+     */
+    public synchronized void removeBean(Object obj)
+    {
+        LOG.debug("removeBean {}",obj);
+        ObjectName bean = _beans.remove(obj);
+
+        if (bean != null)
+        {
+            List<Container.Relationship> beanRelations= _relations.remove(bean);
+            if (beanRelations != null)
+            {
+                LOG.debug("Unregister {}", beanRelations);
+                List<?> removeList = new ArrayList<Object>(beanRelations);
+                for (Object r : removeList)
+                {
+                    Container.Relationship relation = (Relationship)r;
+                    relation.getContainer().update(relation.getParent(), relation.getChild(), null, relation.getRelationship(), true);
+                }
+            }
+
+            try
+            {
+                _server.unregisterMBean(bean);
+                LOG.debug("Unregistered {}", bean);
+            }
+            catch (javax.management.InstanceNotFoundException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+            }
+        }
+    }
+
+    /**
+     * Implementation of Container.Listener interface
+     *
+     * @see org.eclipse.jetty.util.component.Container.Listener#addBean(java.lang.Object)
+     */
+    public synchronized void addBean(Object obj)
+    {
+        LOG.debug("addBean {}",obj);
+        try
+        {
+            if (obj == null || _beans.containsKey(obj))
+                return;
+
+            Object mbean = ObjectMBean.mbeanFor(obj);
+            if (mbean == null)
+                return;
+
+            ObjectName oname = null;
+            if (mbean instanceof ObjectMBean)
+            {
+                ((ObjectMBean)mbean).setMBeanContainer(this);
+                oname = ((ObjectMBean)mbean).getObjectName();
+            }
+
+            //no override mbean object name, so make a generic one
+            if (oname == null)
+            {
+                String type = obj.getClass().getName().toLowerCase(Locale.ENGLISH);
+                int dot = type.lastIndexOf('.');
+                if (dot >= 0)
+                    type = type.substring(dot + 1);
+
+                String context = null;
+                if (mbean instanceof ObjectMBean)
+                {
+                    context = makeName(((ObjectMBean)mbean).getObjectContextBasis());
+                }
+
+                String name = null;
+                if (mbean instanceof ObjectMBean)
+                {
+                    name = makeName(((ObjectMBean)mbean).getObjectNameBasis());
+                }
+
+                StringBuffer buf = new StringBuffer();
+                buf.append("type=").append(type);
+                if (context != null && context.length()>1)
+                {
+                    buf.append(buf.length()>0 ? ",":"");
+                    buf.append("context=").append(context);
+                }
+                if (name != null && name.length()>1)
+                {
+                    buf.append(buf.length()>0 ? ",":"");
+                    buf.append("name=").append(name);
+                }
+                    
+                String basis = buf.toString();
+                Integer count;
+                synchronized (__unique)
+                {
+                    count = __unique.get(basis);
+                    count = count == null ? 0 : 1 + count;
+                    __unique.put(basis, count);
+                }
+
+                //if no explicit domain, create one
+                String domain = _domain;
+                if (domain == null)
+                    domain = obj.getClass().getPackage().getName();
+
+                oname = ObjectName.getInstance(domain + ":" + basis + ",id=" + count);
+            }
+
+            ObjectInstance oinstance = _server.registerMBean(mbean, oname);
+            LOG.debug("Registered {}", oinstance.getObjectName());
+            _beans.put(obj, oinstance.getObjectName());
+
+        }
+        catch (Exception e)
+        {
+            LOG.warn("bean: " + obj, e);
+        }
+    }
+
+    /**
+     * @param basis name to strip of special characters.
+     * @return normalized name
+     */
+    public String makeName(String basis)
+    {
+        if (basis==null)
+            return basis;
+        return basis.replace(':', '_').replace('*', '_').replace('?', '_').replace('=', '_').replace(',', '_').replace(' ', '_');
+    }
+
+    /**
+     * Perform actions needed to start lifecycle
+     *
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    public void doStart()
+    {
+        ShutdownThread.register(this);
+    }
+
+    /**
+     * Perform actions needed to stop lifecycle
+     *
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    public void doStop()
+    {
+        Set<Object> removeSet = new HashSet<Object>(_beans.keySet());
+        for (Object removeObj : removeSet)
+        {
+            removeBean(removeObj);
+        }
+    }
+
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        AggregateLifeCycle.dumpObject(out,this);
+        AggregateLifeCycle.dump(out, indent, _beans.entrySet());
+    }
+
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/jmx/ObjectMBean.java b/src/java/org/eclipse/jetty/jmx/ObjectMBean.java
new file mode 100644
index 0000000..c3d49ff
--- /dev/null
+++ b/src/java/org/eclipse/jetty/jmx/ObjectMBean.java
@@ -0,0 +1,777 @@
+//
+//  ========================================================================
+//  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.jmx;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.modelmbean.ModelMBean;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** ObjectMBean.
+ * A dynamic MBean that can wrap an arbitary Object instance.
+ * the attributes and methods exposed by this bean are controlled by
+ * the merge of property bundles discovered by names related to all
+ * superclasses and all superinterfaces.
+ *
+ * Attributes and methods exported may be "Object" and must exist on the
+ * wrapped object, or "MBean" and must exist on a subclass of OBjectMBean
+ * or "MObject" which exists on the wrapped object, but whose values are
+ * converted to MBean object names.
+ *
+ */
+public class ObjectMBean implements DynamicMBean
+{
+    private static final Logger LOG = Log.getLogger(ObjectMBean.class);
+
+    private static Class[] OBJ_ARG = new Class[]{Object.class};
+
+    protected Object _managed;
+    private MBeanInfo _info;
+    private Map _getters=new HashMap();
+    private Map _setters=new HashMap();
+    private Map _methods=new HashMap();
+    private Set _convert=new HashSet();
+    private ClassLoader _loader;
+    private MBeanContainer _mbeanContainer;
+
+    private static String OBJECT_NAME_CLASS = ObjectName.class.getName();
+    private static String OBJECT_NAME_ARRAY_CLASS = ObjectName[].class.getName();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create MBean for Object. Attempts to create an MBean for the object by searching the package
+     * and class name space. For example an object of the type
+     *
+     * <PRE>
+     * class com.acme.MyClass extends com.acme.util.BaseClass implements com.acme.Iface
+     * </PRE>
+     *
+     * Then this method would look for the following classes:
+     * <UL>
+     * <LI>com.acme.jmx.MyClassMBean
+     * <LI>com.acme.util.jmx.BaseClassMBean
+     * <LI>org.eclipse.jetty.jmx.ObjectMBean
+     * </UL>
+     *
+     * @param o The object
+     * @return A new instance of an MBean for the object or null.
+     */
+    public static Object mbeanFor(Object o)
+    {
+        try
+        {
+            Class oClass = o.getClass();
+            Object mbean = null;
+
+            while (mbean == null && oClass != null)
+            {
+                String pName = oClass.getPackage().getName();
+                String cName = oClass.getName().substring(pName.length() + 1);
+                String mName = pName + ".jmx." + cName + "MBean";
+                
+
+                try
+                {
+                    Class mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName,true);
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("mbeanFor " + o + " mClass=" + mClass);
+
+                    try
+                    {
+                        Constructor constructor = mClass.getConstructor(OBJ_ARG);
+                        mbean=constructor.newInstance(new Object[]{o});
+                    }
+                    catch(Exception e)
+                    {
+                        LOG.ignore(e);
+                        if (ModelMBean.class.isAssignableFrom(mClass))
+                        {
+                            mbean=mClass.newInstance();
+                            ((ModelMBean)mbean).setManagedResource(o, "objectReference");
+                        }
+                    }
+
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("mbeanFor " + o + " is " + mbean);
+                    return mbean;
+                }
+                catch (ClassNotFoundException e)
+                {
+                    // The code below was modified to fix bugs 332200 and JETTY-1416 
+                    // The issue was caused by additional information added to the 
+                    // message after the class name when running in Apache Felix,
+                    // as well as before the class name when running in JBoss.
+                    if (e.getMessage().contains(mName))
+                        LOG.ignore(e);
+                    else
+                        LOG.warn(e);
+                }
+                catch (Error e)
+                {
+                    LOG.warn(e);
+                    mbean = null;
+                }
+                catch (Exception e)
+                {
+                    LOG.warn(e);
+                    mbean = null;
+                }
+
+                oClass = oClass.getSuperclass();
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+        return null;
+    }
+
+
+    public ObjectMBean(Object managedObject)
+    {
+        _managed = managedObject;
+        _loader = Thread.currentThread().getContextClassLoader();
+    }
+    
+    public Object getManagedObject()
+    {
+        return _managed;
+    }
+    
+    public ObjectName getObjectName()
+    {
+        return null;
+    }
+    
+    public String getObjectContextBasis()
+    {
+        return null;
+    }
+    
+    public String getObjectNameBasis()
+    {
+        return null;
+    }
+
+    protected void setMBeanContainer(MBeanContainer container)
+    {
+       this._mbeanContainer = container;
+    }
+
+    public MBeanContainer getMBeanContainer ()
+    {
+        return this._mbeanContainer;
+    }
+    
+    
+    public MBeanInfo getMBeanInfo()
+    {
+        try
+        {
+            if (_info==null)
+            {
+                // Start with blank lazy lists attributes etc.
+                String desc=null;
+                Object attributes=null;
+                Object constructors=null;
+                Object operations=null;
+                Object notifications=null;
+
+                // Find list of classes that can influence the mbean
+                Class o_class=_managed.getClass();
+                Object influences = findInfluences(null, _managed.getClass());
+
+                // Set to record defined items
+                Set defined=new HashSet();
+
+                // For each influence
+                for (int i=0;i<LazyList.size(influences);i++)
+                {
+                    Class oClass = (Class)LazyList.get(influences, i);
+
+                    // look for a bundle defining methods
+                    if (Object.class.equals(oClass))
+                        oClass=ObjectMBean.class;
+                    String pName = oClass.getPackage().getName();
+                    String cName = oClass.getName().substring(pName.length() + 1);
+                    String rName = pName.replace('.', '/') + "/jmx/" + cName+"-mbean";
+
+                    try
+                    {
+                        LOG.debug(rName);
+                        ResourceBundle bundle = Loader.getResourceBundle(o_class, rName,true,Locale.getDefault());
+
+                        
+                        // Extract meta data from bundle
+                        Enumeration e = bundle.getKeys();
+                        while (e.hasMoreElements())
+                        {
+                            String key = (String)e.nextElement();
+                            String value = bundle.getString(key);
+
+                            // Determin if key is for mbean , attribute or for operation
+                            if (key.equals(cName))
+                            {
+                                // set the mbean description
+                                if (desc==null)
+                                    desc=value;
+                            }
+                            else if (key.indexOf('(')>0)
+                            {
+                                // define an operation
+                                if (!defined.contains(key) && key.indexOf('[')<0)
+                                {
+                                    defined.add(key);
+                                    operations=LazyList.add(operations,defineOperation(key, value, bundle));
+                                }
+                            }
+                            else
+                            {
+                                // define an attribute
+                                if (!defined.contains(key))
+                                {
+                                    defined.add(key);
+                                    MBeanAttributeInfo info=defineAttribute(key, value);
+                                    if (info!=null)
+                                        attributes=LazyList.add(attributes,info);
+                                }
+                            }
+                        }
+                    }
+                    catch(MissingResourceException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                }
+
+                _info = new MBeanInfo(o_class.getName(),
+                                desc,
+                                (MBeanAttributeInfo[])LazyList.toArray(attributes, MBeanAttributeInfo.class),
+                                (MBeanConstructorInfo[])LazyList.toArray(constructors, MBeanConstructorInfo.class),
+                                (MBeanOperationInfo[])LazyList.toArray(operations, MBeanOperationInfo.class),
+                                (MBeanNotificationInfo[])LazyList.toArray(notifications, MBeanNotificationInfo.class));
+            }
+        }
+        catch(RuntimeException e)
+        {
+            LOG.warn(e);
+            throw e;
+        }
+        return _info;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException
+    {
+        Method getter = (Method) _getters.get(name);
+        if (getter == null)
+            throw new AttributeNotFoundException(name);
+        try
+        {
+            Object o = _managed;
+            if (getter.getDeclaringClass().isInstance(this))
+                o = this; // mbean method
+
+            // get the attribute
+            Object r=getter.invoke(o, (java.lang.Object[]) null);
+
+            // convert to ObjectName if need be.
+            if (r!=null && _convert.contains(name))
+            {
+                if (r.getClass().isArray())
+                {
+                    ObjectName[] on = new ObjectName[Array.getLength(r)];
+                    for (int i=0;i<on.length;i++)
+                        on[i]=_mbeanContainer.findMBean(Array.get(r, i));
+                    r=on;
+                }
+                else if (r instanceof Collection<?>)
+                {
+                    Collection<Object> c = (Collection<Object>)r;
+                    ObjectName[] on = new ObjectName[c.size()];
+                    int i=0;
+                    for (Object obj :c)
+                        on[i++]=_mbeanContainer.findMBean(obj);
+                    r=on;
+                }
+                else
+                {
+                    ObjectName mbean = _mbeanContainer.findMBean(r);
+                    if (mbean==null)
+                        return null;
+                    r=mbean;
+                }
+            }
+            return r;
+        }
+        catch (IllegalAccessException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new AttributeNotFoundException(e.toString());
+        }
+        catch (InvocationTargetException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new ReflectionException(new Exception(e.getCause()));
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public AttributeList getAttributes(String[] names)
+    {
+        AttributeList results = new AttributeList(names.length);
+        for (int i = 0; i < names.length; i++)
+        {
+            try
+            {
+                results.add(new Attribute(names[i], getAttribute(names[i])));
+            }
+            catch (Exception e)
+            {
+                LOG.warn(Log.EXCEPTION, e);
+            }
+        }
+        return results;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setAttribute(Attribute attr) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException
+    {
+        if (attr == null)
+            return;
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("setAttribute " + _managed + ":" +attr.getName() + "=" + attr.getValue());
+        Method setter = (Method) _setters.get(attr.getName());
+        if (setter == null)
+            throw new AttributeNotFoundException(attr.getName());
+        try
+        {
+            Object o = _managed;
+            if (setter.getDeclaringClass().isInstance(this))
+                o = this;
+
+            // get the value
+            Object value = attr.getValue();
+
+            // convert from ObjectName if need be
+            if (value!=null && _convert.contains(attr.getName()))
+            {
+                if (value.getClass().isArray())
+                {
+                    Class t=setter.getParameterTypes()[0].getComponentType();
+                    Object na = Array.newInstance(t,Array.getLength(value));
+                    for (int i=Array.getLength(value);i-->0;)
+                        Array.set(na, i, _mbeanContainer.findBean((ObjectName)Array.get(value, i)));
+                    value=na;
+                }
+                else
+                    value=_mbeanContainer.findBean((ObjectName)value);
+            }
+
+            // do the setting
+            setter.invoke(o, new Object[]{ value });
+        }
+        catch (IllegalAccessException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new AttributeNotFoundException(e.toString());
+        }
+        catch (InvocationTargetException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new ReflectionException(new Exception(e.getCause()));
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public AttributeList setAttributes(AttributeList attrs)
+    {
+        LOG.debug("setAttributes");
+
+        AttributeList results = new AttributeList(attrs.size());
+        Iterator iter = attrs.iterator();
+        while (iter.hasNext())
+        {
+            try
+            {
+                Attribute attr = (Attribute) iter.next();
+                setAttribute(attr);
+                results.add(new Attribute(attr.getName(), getAttribute(attr.getName())));
+            }
+            catch (Exception e)
+            {
+                LOG.warn(Log.EXCEPTION, e);
+            }
+        }
+        return results;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("invoke " + name);
+
+        String methodKey = name + "(";
+        if (signature != null)
+            for (int i = 0; i < signature.length; i++)
+                methodKey += (i > 0 ? "," : "") + signature[i];
+        methodKey += ")";
+
+        ClassLoader old_loader=Thread.currentThread().getContextClassLoader();
+        try
+        {
+            Thread.currentThread().setContextClassLoader(_loader);
+            Method method = (Method) _methods.get(methodKey);
+            if (method == null)
+                throw new NoSuchMethodException(methodKey);
+
+            Object o = _managed;
+            if (method.getDeclaringClass().isInstance(this))
+                o = this;
+            return method.invoke(o, params);
+        }
+        catch (NoSuchMethodException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new ReflectionException(e);
+        }
+        catch (IllegalAccessException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new MBeanException(e);
+        }
+        catch (InvocationTargetException e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new ReflectionException(new Exception(e.getCause()));
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader(old_loader);
+        }
+    }
+
+    private static Object findInfluences(Object influences, Class aClass)
+    {
+        if (aClass!=null)
+        {
+            // This class is an influence
+            influences=LazyList.add(influences,aClass);
+
+            // So are the super classes
+            influences=findInfluences(influences,aClass.getSuperclass());
+
+            // So are the interfaces
+            Class[] ifs = aClass.getInterfaces();
+            for (int i=0;ifs!=null && i<ifs.length;i++)
+                influences=findInfluences(influences,ifs[i]);
+        }
+        return influences;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Define an attribute on the managed object. The meta data is defined by looking for standard
+     * getter and setter methods. Descriptions are obtained with a call to findDescription with the
+     * attribute name.
+     *
+     * @param name
+     * @param metaData "description" or "access:description" or "type:access:description"  where type is
+     * one of: <ul>
+     * <li>"Object" The field/method is on the managed object.
+     * <li>"MBean" The field/method is on the mbean proxy object
+     * <li>"MObject" The field/method is on the managed object and value should be converted to MBean reference
+     * <li>"MMBean" The field/method is on the mbean proxy object and value should be converted to MBean reference
+     * </ul>
+     * the access is either "RW" or "RO".
+     */
+    public MBeanAttributeInfo defineAttribute(String name, String metaData)
+    {
+        String description = "";
+        boolean writable = true;
+        boolean onMBean = false;
+        boolean convert = false;
+
+        if (metaData!= null)
+        {
+            String[] tokens = metaData.split(":", 3);
+            for (int t=0;t<tokens.length-1;t++)
+            {
+                tokens[t]=tokens[t].trim();
+                if ("RO".equals(tokens[t]))
+                    writable=false;
+                else 
+                {
+                    onMBean=("MMBean".equalsIgnoreCase(tokens[t]) || "MBean".equalsIgnoreCase(tokens[t]));
+                    convert=("MMBean".equalsIgnoreCase(tokens[t]) || "MObject".equalsIgnoreCase(tokens[t]));
+                }
+            }
+            description=tokens[tokens.length-1];
+        }
+        
+
+        String uName = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
+        Class oClass = onMBean ? this.getClass() : _managed.getClass();
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("defineAttribute "+name+" "+onMBean+":"+writable+":"+oClass+":"+description);
+
+        Class type = null;
+        Method getter = null;
+        Method setter = null;
+        Method[] methods = oClass.getMethods();
+        for (int m = 0; m < methods.length; m++)
+        {
+            if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0)
+                continue;
+
+            // Look for a getter
+            if (methods[m].getName().equals("get" + uName) && methods[m].getParameterTypes().length == 0)
+            {
+                if (getter != null)
+                {
+		    LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
+		    continue;
+		}
+                getter = methods[m];
+                if (type != null && !type.equals(methods[m].getReturnType()))
+                {
+		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
+		    continue;
+		}
+                type = methods[m].getReturnType();
+            }
+
+            // Look for an is getter
+            if (methods[m].getName().equals("is" + uName) && methods[m].getParameterTypes().length == 0)
+            {
+                if (getter != null)
+                {
+		    LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
+		    continue;
+		}
+                getter = methods[m];
+                if (type != null && !type.equals(methods[m].getReturnType()))
+                {
+		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
+		    continue;
+		}
+                type = methods[m].getReturnType();
+            }
+
+            // look for a setter
+            if (writable && methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1)
+            {
+                if (setter != null)
+                {
+		    LOG.warn("Multiple setters for mbean attr " + name+ " in "+oClass);
+		    continue;
+		}
+                setter = methods[m];
+                if (type != null && !type.equals(methods[m].getParameterTypes()[0]))
+                {
+		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
+		    continue;
+		}
+                type = methods[m].getParameterTypes()[0];
+            }
+        }
+        
+        if (convert)
+        {
+            if (type==null)
+            {
+	        LOG.warn("No mbean type for " + name+" on "+_managed.getClass());
+		return null;
+	    }
+                
+            if (type.isPrimitive() && !type.isArray())
+            {
+	        LOG.warn("Cannot convert mbean primative " + name);
+		return null;
+	    }
+        }
+
+        if (getter == null && setter == null)
+        {
+	    LOG.warn("No mbean getter or setters found for " + name+ " in "+oClass);
+	    return null;
+	}
+
+        try
+        {
+            // Remember the methods
+            _getters.put(name, getter);
+            _setters.put(name, setter);
+
+            MBeanAttributeInfo info=null;
+            if (convert)
+            {
+                _convert.add(name);
+                if (type.isArray())
+                    info= new MBeanAttributeInfo(name,OBJECT_NAME_ARRAY_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
+
+                else
+                    info= new MBeanAttributeInfo(name,OBJECT_NAME_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
+            }
+            else
+                info= new MBeanAttributeInfo(name,description,getter,setter);
+
+            return info;
+        }
+        catch (Exception e)
+        {
+            LOG.warn(name+": "+metaData, e);
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Define an operation on the managed object. Defines an operation with parameters. Refection is
+     * used to determine find the method and it's return type. The description of the method is
+     * found with a call to findDescription on "name(signature)". The name and description of each
+     * parameter is found with a call to findDescription with "name(signature)[n]", the returned
+     * description is for the last parameter of the partial signature and is assumed to start with
+     * the parameter name, followed by a colon.
+     *
+     * @param metaData "description" or "impact:description" or "type:impact:description", type is
+     * the "Object","MBean", "MMBean" or "MObject" to indicate the method is on the object, the MBean or on the
+     * object but converted to an MBean reference, and impact is either "ACTION","INFO","ACTION_INFO" or "UNKNOWN".
+     */
+    private MBeanOperationInfo defineOperation(String signature, String metaData, ResourceBundle bundle)
+    {
+        String[] tokens=metaData.split(":",3);
+        int i=tokens.length-1;
+        String description=tokens[i--];
+        String impact_name = i<0?"UNKNOWN":tokens[i--].trim();
+        if (i==0)
+            tokens[0]=tokens[0].trim();
+        boolean onMBean= i==0 && ("MBean".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0]));
+        boolean convert= i==0 && ("MObject".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0]));
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("defineOperation "+signature+" "+onMBean+":"+impact_name+":"+description);
+
+        Class oClass = onMBean ? this.getClass() : _managed.getClass();
+
+        try
+        {
+            // Resolve the impact
+            int impact=MBeanOperationInfo.UNKNOWN;
+            if (impact_name==null || impact_name.equals("UNKNOWN"))
+                impact=MBeanOperationInfo.UNKNOWN;
+            else if (impact_name.equals("ACTION"))
+                impact=MBeanOperationInfo.ACTION;
+            else if (impact_name.equals("INFO"))
+                impact=MBeanOperationInfo.INFO;
+            else if (impact_name.equals("ACTION_INFO"))
+                impact=MBeanOperationInfo.ACTION_INFO;
+            else
+                LOG.warn("Unknown impact '"+impact_name+"' for "+signature);
+
+
+            // split the signature
+            String[] parts=signature.split("[\\(\\)]");
+            String method_name=parts[0];
+            String arguments=parts.length==2?parts[1]:null;
+            String[] args=arguments==null?new String[0]:arguments.split(" *, *");
+
+            // Check types and normalize signature.
+            Class[] types = new Class[args.length];
+            MBeanParameterInfo[] pInfo = new MBeanParameterInfo[args.length];
+            signature=method_name;
+            for (i = 0; i < args.length; i++)
+            {
+                Class type = TypeUtil.fromName(args[i]);
+                if (type == null)
+                    type = Thread.currentThread().getContextClassLoader().loadClass(args[i]);
+                types[i] = type;
+                args[i] = type.isPrimitive() ? TypeUtil.toName(type) : args[i];
+                signature+=(i>0?",":"(")+args[i];
+            }
+            signature+=(i>0?")":"()");
+
+            // Build param infos
+            for (i = 0; i < args.length; i++)
+            {
+                String param_desc = bundle.getString(signature + "[" + i + "]");
+                parts=param_desc.split(" *: *",2);
+                if (LOG.isDebugEnabled())
+                    LOG.debug(parts[0]+": "+parts[1]);
+                pInfo[i] = new MBeanParameterInfo(parts[0].trim(), args[i], parts[1].trim());
+            }
+
+            // build the operation info
+            Method method = oClass.getMethod(method_name, types);
+            Class returnClass = method.getReturnType();
+            _methods.put(signature, method);
+            if (convert)
+                _convert.add(signature);
+
+            return new MBeanOperationInfo(method_name, description, pInfo, returnClass.isPrimitive() ? TypeUtil.toName(returnClass) : (returnClass.getName()), impact);
+        }
+        catch (Exception e)
+        {
+            LOG.warn("Operation '"+signature+"'", e);
+            throw new IllegalArgumentException(e.toString());
+        }
+
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/Authenticator.java b/src/java/org/eclipse/jetty/security/Authenticator.java
new file mode 100644
index 0000000..0b57353
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/Authenticator.java
@@ -0,0 +1,122 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.Server;
+
+/**
+ * Authenticator Interface
+ * <p>
+ * An Authenticator is responsible for checking requests and sending
+ * response challenges in order to authenticate a request. 
+ * Various types of {@link Authentication} are returned in order to
+ * signal the next step in authentication.
+ * 
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public interface Authenticator
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * Configure the Authenticator
+     * @param configuration
+     */
+    void setConfiguration(AuthConfiguration configuration);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The name of the authentication method
+     */
+    String getAuthMethod();
+    
+    /* ------------------------------------------------------------ */
+    /** Validate a response
+     * @param request The request
+     * @param response The response
+     * @param mandatory True if authentication is mandatory.
+     * @return An Authentication.  If Authentication is successful, this will be a {@link org.eclipse.jetty.server.Authentication.User}. If a response has 
+     * been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will
+     * implement {@link org.eclipse.jetty.server.Authentication.ResponseSent}.  If Authentication is not manditory, then a 
+     * {@link org.eclipse.jetty.server.Authentication.Deferred} may be returned.
+     * 
+     * @throws ServerAuthException
+     */
+    Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param request
+     * @param response
+     * @param mandatory
+     * @param validatedUser
+     * @return true if response is secure
+     * @throws ServerAuthException
+     */
+    boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException;
+    
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /** 
+     * Authenticator Configuration
+     */
+    interface AuthConfiguration
+    {
+        String getAuthMethod();
+        String getRealmName();
+        
+        /** Get a SecurityHandler init parameter
+         * @see SecurityHandler#getInitParameter(String)
+         * @param param parameter name
+         * @return Parameter value or null
+         */
+        String getInitParameter(String param);
+        
+        /* ------------------------------------------------------------ */
+        /** Get a SecurityHandler init parameter names
+         * @see SecurityHandler#getInitParameterNames()
+         * @return Set of parameter names
+         */
+        Set<String> getInitParameterNames();
+        
+        LoginService getLoginService();
+        IdentityService getIdentityService();
+        boolean isSessionRenewedOnAuthentication();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /** 
+     * Authenticator Factory
+     */
+    interface Factory
+    {
+        Authenticator getAuthenticator(Server server, ServletContext context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/ConstraintAware.java b/src/java/org/eclipse/jetty/security/ConstraintAware.java
new file mode 100644
index 0000000..e836125
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/ConstraintAware.java
@@ -0,0 +1,54 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $
+ */
+public interface ConstraintAware
+{
+    List<ConstraintMapping> getConstraintMappings();
+    Set<String> getRoles();
+    
+    /* ------------------------------------------------------------ */
+    /** Set Constraint Mappings and roles.
+     * Can only be called during initialization.
+     * @param constraintMappings
+     * @param roles
+     */
+    void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles);
+    
+    /* ------------------------------------------------------------ */
+    /** Add a Constraint Mapping.
+     * May be called for running webapplication as an annotated servlet is instantiated.
+     * @param mapping
+     */
+    void addConstraintMapping(ConstraintMapping mapping);
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Add a Role definition.
+     * May be called on running webapplication as an annotated servlet is instantiated.
+     * @param role
+     */
+    void addRole(String role);
+}
diff --git a/src/java/org/eclipse/jetty/security/ConstraintMapping.java b/src/java/org/eclipse/jetty/security/ConstraintMapping.java
new file mode 100644
index 0000000..dd99c5b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/ConstraintMapping.java
@@ -0,0 +1,100 @@
+//
+//  ========================================================================
+//  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.security;
+
+import org.eclipse.jetty.util.security.Constraint;
+
+public class ConstraintMapping
+{
+    String _method;
+    String[] _methodOmissions;
+
+    String _pathSpec;
+
+    Constraint _constraint;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the constraint.
+     */
+    public Constraint getConstraint()
+    {
+        return _constraint;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param constraint The constraint to set.
+     */
+    public void setConstraint(Constraint constraint)
+    {
+        this._constraint = constraint;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the method.
+     */
+    public String getMethod()
+    {
+        return _method;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param method The method to set.
+     */
+    public void setMethod(String method)
+    {
+        this._method = method;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the pathSpec.
+     */
+    public String getPathSpec()
+    {
+        return _pathSpec;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpec The pathSpec to set.
+     */
+    public void setPathSpec(String pathSpec)
+    {
+        this._pathSpec = pathSpec;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param omissions The http-method-omission
+     */
+    public void setMethodOmissions(String[] omissions)
+    {
+        _methodOmissions = omissions;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String[] getMethodOmissions()
+    {
+        return _methodOmissions;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/src/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
new file mode 100644
index 0000000..2671871
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -0,0 +1,813 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.eclipse.jetty.http.HttpSchemes;
+import javax.servlet.HttpConstraintElement;
+import javax.servlet.HttpMethodConstraintElement;
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
+import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
+
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.StringMap;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.security.Constraint;
+
+/* ------------------------------------------------------------ */
+/**
+ * Handler to enforce SecurityConstraints. This implementation is servlet spec
+ * 3.0 compliant and precomputes the constraint combinations for runtime
+ * efficiency.
+ *
+ */
+public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware
+{
+    private static final String OMISSION_SUFFIX = ".omission";
+    
+    private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<ConstraintMapping>();
+    private final Set<String> _roles = new CopyOnWriteArraySet<String>();
+    private final PathMap _constraintMap = new PathMap();
+    private boolean _strict = true;
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return
+     */
+    public static Constraint createConstraint()
+    {
+        return new Constraint();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param constraint
+     * @return
+     */
+    public static Constraint createConstraint(Constraint constraint)
+    {
+        try
+        {
+            return (Constraint)constraint.clone();
+        }
+        catch (CloneNotSupportedException e)
+        {
+            throw new IllegalStateException (e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a security constraint
+     * 
+     * @param name
+     * @param authenticate
+     * @param roles
+     * @param dataConstraint
+     * @return
+     */
+    public static Constraint createConstraint (String name, boolean authenticate, String[] roles, int dataConstraint)
+    {
+        Constraint constraint = createConstraint();
+        if (name != null)
+            constraint.setName(name);
+        constraint.setAuthenticate(authenticate);
+        constraint.setRoles(roles);
+        constraint.setDataConstraint(dataConstraint);
+        return constraint;
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     * @param element
+     * @return
+     */
+    public static Constraint createConstraint (String name, HttpConstraintElement element)
+    {
+        return createConstraint(name, element.getRolesAllowed(), element.getEmptyRoleSemantic(), element.getTransportGuarantee());     
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     * @param rolesAllowed
+     * @param permitOrDeny
+     * @param transport
+     * @return
+     */
+    public static Constraint createConstraint (String name, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport)
+    {
+        Constraint constraint = createConstraint();
+        
+        if (rolesAllowed == null || rolesAllowed.length==0)
+        {           
+            if (permitOrDeny.equals(EmptyRoleSemantic.DENY))
+            {
+                //Equivalent to <auth-constraint> with no roles
+                constraint.setName(name+"-Deny");
+                constraint.setAuthenticate(true);
+            }
+            else
+            {
+                //Equivalent to no <auth-constraint>
+                constraint.setName(name+"-Permit");
+                constraint.setAuthenticate(false);
+            }
+        }
+        else
+        {
+            //Equivalent to <auth-constraint> with list of <security-role-name>s
+            constraint.setAuthenticate(true);
+            constraint.setRoles(rolesAllowed);
+            constraint.setName(name+"-RolesAllowed");           
+        } 
+
+        //Equivalent to //<user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>
+        constraint.setDataConstraint((transport.equals(TransportGuarantee.CONFIDENTIAL)?Constraint.DC_CONFIDENTIAL:Constraint.DC_NONE));
+        return constraint; 
+    }
+    
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpec
+     * @param constraintMappings
+     * @return
+     */
+    public static List<ConstraintMapping> getConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings)
+    {
+        if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0)
+            return Collections.emptyList();
+        
+        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
+        for (ConstraintMapping mapping:constraintMappings)
+        {
+            if (pathSpec.equals(mapping.getPathSpec()))
+            {
+               mappings.add(mapping);
+            }
+        }
+        return mappings;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Take out of the constraint mappings those that match the 
+     * given path.
+     * 
+     * @param pathSpec
+     * @param constraintMappings a new list minus the matching constraints
+     * @return
+     */
+    public static List<ConstraintMapping> removeConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings)
+    {
+        if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0)
+            return Collections.emptyList();
+        
+        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
+        for (ConstraintMapping mapping:constraintMappings)
+        {
+            //Remove the matching mappings by only copying in non-matching mappings
+            if (!pathSpec.equals(mapping.getPathSpec()))
+            {
+               mappings.add(mapping);
+            }
+        }
+        return mappings;
+    }
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement
+     * 
+     * @param name
+     * @param pathSpec
+     * @param securityElement
+     * @return
+     */
+    public static List<ConstraintMapping> createConstraintsWithMappingsForPath (String name, String pathSpec, ServletSecurityElement securityElement)
+    {
+        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
+
+        //Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints)
+        Constraint constraint = ConstraintSecurityHandler.createConstraint(name, securityElement);
+
+        //Create a mapping for the pathSpec for the default case
+        ConstraintMapping defaultMapping = new ConstraintMapping();
+        defaultMapping.setPathSpec(pathSpec);
+        defaultMapping.setConstraint(constraint);  
+        mappings.add(defaultMapping);
+
+
+        //See Spec 13.4.1.2 p127
+        List<String> methodOmissions = new ArrayList<String>();
+        
+        //make constraint mappings for this url for each of the HttpMethodConstraintElements
+        Collection<HttpMethodConstraintElement> methodConstraints = securityElement.getHttpMethodConstraints();
+        if (methodConstraints != null)
+        {
+            for (HttpMethodConstraintElement methodConstraint:methodConstraints)
+            {
+                //Make a Constraint that captures the <auth-constraint> and <user-data-constraint> elements supplied for the HttpMethodConstraintElement
+                Constraint mconstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraint);
+                ConstraintMapping mapping = new ConstraintMapping();
+                mapping.setConstraint(mconstraint);
+                mapping.setPathSpec(pathSpec);
+                if (methodConstraint.getMethodName() != null)
+                {
+                    mapping.setMethod(methodConstraint.getMethodName());
+                    //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
+                    methodOmissions.add(methodConstraint.getMethodName());
+                }
+                mappings.add(mapping);
+            }
+        }
+        //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
+        if (methodOmissions.size() > 0)
+            defaultMapping.setMethodOmissions(methodOmissions.toArray(new String[methodOmissions.size()]));
+
+        return mappings;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Get the strict mode.
+     * @return true if the security handler is running in strict mode.
+     */
+    public boolean isStrict()
+    {
+        return _strict;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the strict mode of the security handler.
+     * <p>
+     * When in strict mode (the default), the full servlet specification
+     * will be implemented.
+     * If not in strict mode, some additional flexibility in configuration
+     * is allowed:<ul>
+     * <li>All users do not need to have a role defined in the deployment descriptor
+     * <li>The * role in a constraint applies to ANY role rather than all roles defined in
+     * the deployment descriptor.
+     * </ul>
+     *
+     * @param strict the strict to set
+     * @see #setRoles(Set)
+     * @see #setConstraintMappings(List, Set)
+     */
+    public void setStrict(boolean strict)
+    {
+        _strict = strict;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the constraintMappings.
+     */
+    public List<ConstraintMapping> getConstraintMappings()
+    {
+        return _constraintMappings;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Set<String> getRoles()
+    {
+        return _roles;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Process the constraints following the combining rules in Servlet 3.0 EA
+     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
+     *
+     * @param constraintMappings
+     *            The constraintMappings to set, from which the set of known roles
+     *            is determined.
+     */
+    public void setConstraintMappings(List<ConstraintMapping> constraintMappings)
+    {
+        setConstraintMappings(constraintMappings,null);
+    }
+
+    /**
+     * Process the constraints following the combining rules in Servlet 3.0 EA
+     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
+     *
+     * @param constraintMappings
+     *            The constraintMappings to set as array, from which the set of known roles
+     *            is determined.  Needed to retain API compatibility for 7.x
+     */
+    public void setConstraintMappings( ConstraintMapping[] constraintMappings )
+    {
+        setConstraintMappings( Arrays.asList(constraintMappings), null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Process the constraints following the combining rules in Servlet 3.0 EA
+     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
+     *
+     * @param constraintMappings
+     *            The constraintMappings to set.
+     * @param roles The known roles (or null to determine them from the mappings)
+     */
+    public void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles)
+    {
+        _constraintMappings.clear();
+        _constraintMappings.addAll(constraintMappings);
+
+        if (roles==null)
+        {
+            roles = new HashSet<String>();
+            for (ConstraintMapping cm : constraintMappings)
+            {
+                String[] cmr = cm.getConstraint().getRoles();
+                if (cmr!=null)
+                {
+                    for (String r : cmr)
+                        if (!"*".equals(r))
+                            roles.add(r);
+                }
+            }
+        }
+        setRoles(roles);
+        
+        if (isStarted())
+        {
+            for (ConstraintMapping mapping : _constraintMappings)
+            {
+                processConstraintMapping(mapping);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the known roles.
+     * This may be overridden by a subsequent call to {@link #setConstraintMappings(ConstraintMapping[])} or
+     * {@link #setConstraintMappings(List, Set)}.
+     * @see #setStrict(boolean)
+     * @param roles The known roles (or null to determine them from the mappings)
+     */
+    public void setRoles(Set<String> roles)
+    {
+        _roles.clear();
+        _roles.addAll(roles);
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping)
+     */
+    public void addConstraintMapping(ConstraintMapping mapping)
+    {
+        _constraintMappings.add(mapping);
+        if (mapping.getConstraint()!=null && mapping.getConstraint().getRoles()!=null)
+            for (String role :  mapping.getConstraint().getRoles())
+                addRole(role);
+
+        if (isStarted())
+        {
+            processConstraintMapping(mapping);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String)
+     */
+    public void addRole(String role)
+    {
+        boolean modified = _roles.add(role);
+        if (isStarted() && modified && _strict)
+        {
+            // Add the new role to currently defined any role role infos
+            for (Map<String,RoleInfo> map : (Collection<Map<String,RoleInfo>>)_constraintMap.values())
+            {
+                for (RoleInfo info : map.values())
+                {
+                    if (info.isAnyRole())
+                        info.addRole(role);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.SecurityHandler#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _constraintMap.clear();
+        if (_constraintMappings!=null)
+        {
+            for (ConstraintMapping mapping : _constraintMappings)
+            {
+                processConstraintMapping(mapping);
+            }
+        }
+        super.doStart();
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        _constraintMap.clear();
+        _constraintMappings.clear();
+        _roles.clear();
+        super.doStop();
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Create and combine the constraint with the existing processed
+     * constraints.
+     * 
+     * @param mapping
+     */
+    protected void processConstraintMapping(ConstraintMapping mapping)
+    {
+        Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec());
+        if (mappings == null)
+        {
+            mappings = new StringMap();
+            _constraintMap.put(mapping.getPathSpec(),mappings);
+        }
+        RoleInfo allMethodsRoleInfo = mappings.get(null);
+        if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden())
+            return;
+       
+        if (mapping.getMethodOmissions() != null && mapping.getMethodOmissions().length > 0)
+        {
+           
+            processConstraintMappingWithMethodOmissions(mapping, mappings);
+            return;
+        }
+
+        String httpMethod = mapping.getMethod();       
+        RoleInfo roleInfo = mappings.get(httpMethod);
+        if (roleInfo == null)
+        {
+            roleInfo = new RoleInfo();
+            mappings.put(httpMethod,roleInfo);
+            if (allMethodsRoleInfo != null)
+            {
+                roleInfo.combine(allMethodsRoleInfo);
+            }
+        }
+        if (roleInfo.isForbidden())
+            return;
+
+        //add in info from the constraint
+        configureRoleInfo(roleInfo, mapping);
+        
+        if (roleInfo.isForbidden())
+        {
+            if (httpMethod == null)
+            {
+                mappings.clear();
+                mappings.put(null,roleInfo);
+            }
+        }
+        else
+        {
+            //combine with any entry that covers all methods
+            if (httpMethod == null)
+            {
+                for (Map.Entry<String, RoleInfo> entry : mappings.entrySet())
+                {
+                    if (entry.getKey() != null)
+                    {
+                        RoleInfo specific = entry.getValue();
+                        specific.combine(roleInfo);
+                    }
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Constraints that name method omissions are dealt with differently.
+     * We create an entry in the mappings with key "method.omission". This entry
+     * is only ever combined with other omissions for the same method to produce a
+     * consolidated RoleInfo. Then, when we wish to find the relevant constraints for
+     *  a given Request (in prepareConstraintInfo()), we consult 3 types of entries in 
+     * the mappings: an entry that names the method of the Request specifically, an
+     * entry that names constraints that apply to all methods, entries of the form
+     * method.omission, where the method of the Request is not named in the omission.
+     * @param mapping
+     * @param mappings
+     */
+    protected void processConstraintMappingWithMethodOmissions (ConstraintMapping mapping, Map<String, RoleInfo> mappings)
+    {
+        String[] omissions = mapping.getMethodOmissions();
+
+        for (String omission:omissions)
+        {
+            //for each method omission, see if there is already a RoleInfo for it in mappings
+            RoleInfo ri = mappings.get(omission+OMISSION_SUFFIX);
+            if (ri == null)
+            {
+                //if not, make one
+                ri = new RoleInfo();
+                mappings.put(omission+OMISSION_SUFFIX, ri);
+            }
+
+            //initialize RoleInfo or combine from ConstraintMapping
+            configureRoleInfo(ri, mapping);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Initialize or update the RoleInfo from the constraint
+     * @param ri
+     * @param mapping
+     */
+    protected void configureRoleInfo (RoleInfo ri, ConstraintMapping mapping)
+    {
+        Constraint constraint = mapping.getConstraint();
+        boolean forbidden = constraint.isForbidden();
+        ri.setForbidden(forbidden);
+        
+        //set up the data constraint (NOTE: must be done after setForbidden, as it nulls out the data constraint
+        //which we need in order to do combining of omissions in prepareConstraintInfo
+        UserDataConstraint userDataConstraint = UserDataConstraint.get(mapping.getConstraint().getDataConstraint());
+        ri.setUserDataConstraint(userDataConstraint);
+        
+
+        //if forbidden, no point setting up roles
+        if (!ri.isForbidden())
+        {
+            //add in the roles
+            boolean checked = mapping.getConstraint().getAuthenticate();
+            ri.setChecked(checked);
+            if (ri.isChecked())
+            {
+                if (mapping.getConstraint().isAnyRole())
+                {
+                    if (_strict)
+                    {
+                        // * means "all defined roles"
+                        for (String role : _roles)
+                            ri.addRole(role);
+                    }
+                    else
+                        // * means any role
+                        ri.setAnyRole(true);
+                }
+                else
+                {
+                    String[] newRoles = mapping.getConstraint().getRoles();
+                    for (String role : newRoles)
+                    {
+                        if (_strict &&!_roles.contains(role))
+                            throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
+                        ri.addRole(role);
+                    }
+                }
+            }
+        }
+    }
+   
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * Find constraints that apply to the given path.
+     * In order to do this, we consult 3 different types of information stored in the mappings for each path - each mapping
+     * represents a merged set of user data constraints, roles etc -:
+     * <ol>
+     * <li>A mapping of an exact method name </li>
+     * <li>A mapping will null key that matches every method name</li>
+     * <li>Mappings with keys of the form "method.omission" that indicates it will match every method name EXCEPT that given</li>
+     * </ol>
+     * 
+     * @see org.eclipse.jetty.security.SecurityHandler#prepareConstraintInfo(java.lang.String, org.eclipse.jetty.server.Request)
+     */
+    protected Object prepareConstraintInfo(String pathInContext, Request request)
+    {
+        Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.match(pathInContext);
+
+        if (mappings != null)
+        {
+            String httpMethod = request.getMethod();
+            RoleInfo roleInfo = mappings.get(httpMethod);
+            if (roleInfo == null)
+            {
+                //No specific http-method names matched
+                List<RoleInfo> applicableConstraints = new ArrayList<RoleInfo>();
+
+                //Get info for constraint that matches all methods if it exists
+                RoleInfo all = mappings.get(null);
+                if (all != null)
+                    applicableConstraints.add(all);
+          
+                
+                //Get info for constraints that name method omissions where target method name is not omitted
+                //(ie matches because target method is not omitted, hence considered covered by the constraint)
+                for (Entry<String, RoleInfo> entry: mappings.entrySet())
+                {
+                    if (entry.getKey() != null && entry.getKey().contains(OMISSION_SUFFIX) && !(httpMethod+OMISSION_SUFFIX).equals(entry.getKey()))
+                        applicableConstraints.add(entry.getValue());
+                }
+                
+                if (applicableConstraints.size() == 1)
+                    roleInfo = applicableConstraints.get(0);
+                else
+                {
+                    roleInfo = new RoleInfo();
+                    roleInfo.setUserDataConstraint(UserDataConstraint.None);
+                    
+                    for (RoleInfo r:applicableConstraints)
+                        roleInfo.combine(r);
+                }
+
+            }
+            return roleInfo;
+        }
+        return null;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.security.SecurityHandler#checkUserDataPermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object)
+     */
+    protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException
+    {
+        if (constraintInfo == null)
+            return true;
+
+        RoleInfo roleInfo = (RoleInfo)constraintInfo;
+        if (roleInfo.isForbidden())
+            return false;
+
+
+        UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint();
+        if (dataConstraint == null || dataConstraint == UserDataConstraint.None)
+        {
+            return true;
+        }
+        AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
+        Connector connector = connection.getConnector();
+
+        if (dataConstraint == UserDataConstraint.Integral)
+        {
+            if (connector.isIntegral(request))
+                return true;
+            if (connector.getIntegralPort() > 0)
+            {
+                String scheme=connector.getIntegralScheme();
+                int port=connector.getIntegralPort();
+                String url = (HttpSchemes.HTTPS.equalsIgnoreCase(scheme) && port==443)
+                    ? "https://"+request.getServerName()+request.getRequestURI()
+                    : scheme + "://" + request.getServerName() + ":" + port + request.getRequestURI();
+                if (request.getQueryString() != null)
+                    url += "?" + request.getQueryString();
+                response.setContentLength(0);
+                response.sendRedirect(url);
+            }
+            else
+                response.sendError(Response.SC_FORBIDDEN,"!Integral");
+
+            request.setHandled(true);
+            return false;
+        }
+        else if (dataConstraint == UserDataConstraint.Confidential)
+        {
+            if (connector.isConfidential(request))
+                return true;
+
+            if (connector.getConfidentialPort() > 0)
+            {
+                String scheme=connector.getConfidentialScheme();
+                int port=connector.getConfidentialPort();
+                String url = (HttpSchemes.HTTPS.equalsIgnoreCase(scheme) && port==443)
+                    ? "https://"+request.getServerName()+request.getRequestURI()
+                    : scheme + "://" + request.getServerName() + ":" + port + request.getRequestURI();                    
+                if (request.getQueryString() != null)
+                    url += "?" + request.getQueryString();
+                response.setContentLength(0);
+                response.sendRedirect(url);
+            }
+            else
+                response.sendError(Response.SC_FORBIDDEN,"!Confidential");
+
+            request.setHandled(true);
+            return false;
+        }
+        else
+        {
+            throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint);
+        }
+
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.security.SecurityHandler#isAuthMandatory(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object)
+     */
+    protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo)
+    {
+        if (constraintInfo == null)
+        {
+            return false;
+        }
+        return ((RoleInfo)constraintInfo).isChecked();
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.security.SecurityHandler#checkWebResourcePermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object, org.eclipse.jetty.server.UserIdentity)
+     */
+    @Override
+    protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity)
+            throws IOException
+    {
+        if (constraintInfo == null)
+        {
+            return true;
+        }
+        RoleInfo roleInfo = (RoleInfo)constraintInfo;
+
+        if (!roleInfo.isChecked())
+        {
+            return true;
+        }
+
+        if (roleInfo.isAnyRole() && request.getAuthType()!=null)
+            return true;
+
+        for (String role : roleInfo.getRoles())
+        {
+            if (userIdentity.isUserInRole(role, null))
+                return true;
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void dump(Appendable out,String indent) throws IOException
+    {
+        dumpThis(out);
+        dump(out,indent,
+                Collections.singleton(getLoginService()),
+                Collections.singleton(getIdentityService()),
+                Collections.singleton(getAuthenticator()),
+                Collections.singleton(_roles),
+                _constraintMap.entrySet(),
+                getBeans(),
+                TypeUtil.asList(getHandlers()));
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java b/src/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java
new file mode 100644
index 0000000..e2de9f7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java
@@ -0,0 +1,36 @@
+//
+//  ========================================================================
+//  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.security;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $
+ */
+public interface CrossContextPsuedoSession<T>
+{
+
+    T fetch(HttpServletRequest request);
+
+    void store(T data, HttpServletResponse response);
+
+    void clear(HttpServletRequest request);
+
+}
diff --git a/src/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/src/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
new file mode 100644
index 0000000..534a6d4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java
@@ -0,0 +1,96 @@
+//
+//  ========================================================================
+//  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.security;
+
+import javax.servlet.ServletContext;
+
+import org.eclipse.jetty.security.Authenticator.AuthConfiguration;
+import org.eclipse.jetty.security.authentication.BasicAuthenticator;
+import org.eclipse.jetty.security.authentication.ClientCertAuthenticator;
+import org.eclipse.jetty.security.authentication.DigestAuthenticator;
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.security.authentication.SpnegoAuthenticator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.security.Constraint;
+
+/* ------------------------------------------------------------ */
+/**
+ * The Default Authenticator Factory.
+ * Uses the {@link AuthConfiguration#getAuthMethod()} to select an {@link Authenticator} from: <ul>
+ * <li>{@link org.eclipse.jetty.security.authentication.BasicAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.DigestAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.FormAuthenticator}</li>
+ * <li>{@link org.eclipse.jetty.security.authentication.ClientCertAuthenticator}</li>
+ * </ul>
+ * All authenticators derived from {@link org.eclipse.jetty.security.authentication.LoginAuthenticator} are 
+ * wrapped with a {@link org.eclipse.jetty.security.authentication.DeferredAuthentication}
+ * instance, which is used if authentication is not mandatory.
+ * 
+ * The Authentications from the {@link org.eclipse.jetty.security.authentication.FormAuthenticator} are always wrapped in a 
+ * {@link org.eclipse.jetty.security.authentication.SessionAuthentication}
+ * <p>
+ * If a {@link LoginService} has not been set on this factory, then
+ * the service is selected by searching the {@link Server#getBeans(Class)} results for
+ * a service that matches the realm name, else the first LoginService found is used.
+ *
+ */
+public class DefaultAuthenticatorFactory implements Authenticator.Factory
+{
+    LoginService _loginService;
+    
+    public Authenticator getAuthenticator(Server server, ServletContext context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService)
+    {
+        String auth=configuration.getAuthMethod();
+        Authenticator authenticator=null;
+        
+        if (auth==null || Constraint.__BASIC_AUTH.equalsIgnoreCase(auth))
+            authenticator=new BasicAuthenticator();
+        else if (Constraint.__DIGEST_AUTH.equalsIgnoreCase(auth))
+            authenticator=new DigestAuthenticator();
+        else if (Constraint.__FORM_AUTH.equalsIgnoreCase(auth))
+            authenticator=new FormAuthenticator();
+        else if ( Constraint.__SPNEGO_AUTH.equalsIgnoreCase(auth) )
+            authenticator = new SpnegoAuthenticator();
+        else if ( Constraint.__NEGOTIATE_AUTH.equalsIgnoreCase(auth) ) // see Bug #377076
+            authenticator = new SpnegoAuthenticator(Constraint.__NEGOTIATE_AUTH);
+        if (Constraint.__CERT_AUTH.equalsIgnoreCase(auth)||Constraint.__CERT_AUTH2.equalsIgnoreCase(auth))
+            authenticator=new ClientCertAuthenticator();
+        
+        return authenticator;
+    }
+   
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the loginService
+     */
+    public LoginService getLoginService()
+    {
+        return _loginService;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param loginService the loginService to set
+     */
+    public void setLoginService(LoginService loginService)
+    {
+        _loginService = loginService;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/DefaultIdentityService.java b/src/java/org/eclipse/jetty/security/DefaultIdentityService.java
new file mode 100644
index 0000000..7121faf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/DefaultIdentityService.java
@@ -0,0 +1,90 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.UserIdentity;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Default Identity Service implementation.
+ * This service handles only role reference maps passed in an
+ * associated {@link org.eclipse.jetty.server.UserIdentity.Scope}.  If there are roles
+ * refs present, then associate will wrap the UserIdentity with one
+ * that uses the role references in the 
+ * {@link org.eclipse.jetty.server.UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)}
+ * implementation. All other operations are effectively noops.
+ *
+ */
+public class DefaultIdentityService implements IdentityService
+{
+    /* ------------------------------------------------------------ */
+    public DefaultIdentityService()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * If there are roles refs present in the scope, then wrap the UserIdentity 
+     * with one that uses the role references in the {@link UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)}
+     */
+    public Object associate(UserIdentity user)
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void disassociate(Object previous) 
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object setRunAs(UserIdentity user, RunAsToken token)
+    {
+        return token;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void unsetRunAs(Object lastToken)
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public RunAsToken newRunAsToken(String runAsName)
+    {
+        return new RoleRunAsToken(runAsName);
+    }
+
+    /* ------------------------------------------------------------ */
+    public UserIdentity getSystemUserIdentity()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public UserIdentity newUserIdentity(final Subject subject, final Principal userPrincipal, final String[] roles)
+    {
+        return new DefaultUserIdentity(subject,userPrincipal,roles);
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/src/java/org/eclipse/jetty/security/DefaultUserIdentity.java
new file mode 100644
index 0000000..7409887
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/DefaultUserIdentity.java
@@ -0,0 +1,72 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.UserIdentity;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * The default implementation of UserIdentity.
+ *
+ */
+public class DefaultUserIdentity implements UserIdentity
+{    
+    private final Subject _subject;
+    private final Principal _userPrincipal;
+    private final String[] _roles;
+    
+    public DefaultUserIdentity(Subject subject, Principal userPrincipal, String[] roles)
+    {
+        _subject=subject;
+        _userPrincipal=userPrincipal;
+        _roles=roles;
+    }
+
+    public Subject getSubject()
+    {
+        return _subject;
+    }
+
+    public Principal getUserPrincipal()
+    {
+        return _userPrincipal;
+    }
+
+    public boolean isUserInRole(String role, Scope scope)
+    {
+        if (scope!=null && scope.getRoleRefMap()!=null)
+            role=scope.getRoleRefMap().get(role);
+
+        for (String r :_roles)
+            if (r.equals(role))
+                return true;
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return DefaultUserIdentity.class.getSimpleName()+"('"+_userPrincipal+"')";
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java b/src/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java
new file mode 100644
index 0000000..0b016a5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java
@@ -0,0 +1,95 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @version $Rev: 4660 $ $Date: 2009-02-25 17:29:53 +0100 (Wed, 25 Feb 2009) $
+ */
+public class HashCrossContextPsuedoSession<T> implements CrossContextPsuedoSession<T>
+{
+    private final String _cookieName;
+
+    private final String _cookiePath;
+
+    private final Random _random = new SecureRandom();
+
+    private final Map<String, T> _data = new HashMap<String, T>();
+
+    public HashCrossContextPsuedoSession(String cookieName, String cookiePath)
+    {
+        this._cookieName = cookieName;
+        this._cookiePath = cookiePath == null ? "/" : cookiePath;
+    }
+
+    public T fetch(HttpServletRequest request)
+    {
+        for (Cookie cookie : request.getCookies())
+        {
+            if (_cookieName.equals(cookie.getName()))
+            {
+                String key = cookie.getValue();
+                return _data.get(key);
+            }
+        }
+        return null;
+    }
+
+    public void store(T datum, HttpServletResponse response)
+    {
+        String key;
+
+        synchronized (_data)
+        {
+            // Create new ID
+            while (true)
+            {
+                key = Long.toString(Math.abs(_random.nextLong()), 30 + (int) (System.currentTimeMillis() % 7));
+                if (!_data.containsKey(key)) break;
+            }
+
+            _data.put(key, datum);
+        }
+
+        Cookie cookie = new Cookie(_cookieName, key);
+        cookie.setPath(_cookiePath);
+        response.addCookie(cookie);
+    }
+
+    public void clear(HttpServletRequest request)
+    {
+        for (Cookie cookie : request.getCookies())
+        {
+            if (_cookieName.equals(cookie.getName()))
+            {
+                String key = cookie.getValue();
+                _data.remove(key);
+                break;
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/HashLoginService.java b/src/java/org/eclipse/jetty/security/HashLoginService.java
new file mode 100644
index 0000000..55f7ed2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/HashLoginService.java
@@ -0,0 +1,180 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.security.PropertyUserStore.UserListener;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.Scanner;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
+
+/* ------------------------------------------------------------ */
+/**
+ * Properties User Realm.
+ * 
+ * An implementation of UserRealm that stores users and roles in-memory in HashMaps.
+ * <P>
+ * Typically these maps are populated by calling the load() method or passing a properties resource to the constructor. The format of the properties file is:
+ * 
+ * <PRE>
+ *  username: password [,rolename ...]
+ * </PRE>
+ * 
+ * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password
+ * checksums.
+ * 
+ * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:.
+ */
+public class HashLoginService extends MappedLoginService implements UserListener
+{
+    private static final Logger LOG = Log.getLogger(HashLoginService.class);
+
+    private PropertyUserStore _propertyUserStore;
+    private String _config;
+    private Resource _configResource;
+    private Scanner _scanner;
+    private int _refreshInterval = 0;// default is not to reload
+
+    /* ------------------------------------------------------------ */
+    public HashLoginService()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public HashLoginService(String name)
+    {
+        setName(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    public HashLoginService(String name, String config)
+    {
+        setName(name);
+        setConfig(config);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getConfig()
+    {
+        return _config;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void getConfig(String config)
+    {
+        _config = config;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Resource getConfigResource()
+    {
+        return _configResource;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Load realm users from properties file. The property file maps usernames to password specs followed by an optional comma separated list of role names.
+     * 
+     * @param config
+     *            Filename or url of user properties file.
+     */
+    public void setConfig(String config)
+    {
+        _config = config;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setRefreshInterval(int msec)
+    {
+        _refreshInterval = msec;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getRefreshInterval()
+    {
+        return _refreshInterval;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected UserIdentity loadUser(String username)
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void loadUsers() throws IOException
+    {
+        // TODO: Consider refactoring MappedLoginService to not have to override with unused methods
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+        
+        if (_propertyUserStore == null)
+        {
+            if(LOG.isDebugEnabled())
+                LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval);
+            
+            _propertyUserStore = new PropertyUserStore();
+            _propertyUserStore.setRefreshInterval(_refreshInterval);
+            _propertyUserStore.setConfig(_config);
+            _propertyUserStore.registerUserListener(this);
+            _propertyUserStore.start();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        if (_scanner != null)
+            _scanner.stop();
+        _scanner = null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void update(String userName, Credential credential, String[] roleArray)
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("update: " + userName + " Roles: " + roleArray.length);
+        putUser(userName,credential,roleArray);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void remove(String userName)
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("remove: " + userName);
+        removeUser(userName);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/IdentityService.java b/src/java/org/eclipse/jetty/security/IdentityService.java
new file mode 100644
index 0000000..3cb8cb5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/IdentityService.java
@@ -0,0 +1,95 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.UserIdentity;
+
+/* ------------------------------------------------------------ */
+/**
+ * Associates UserIdentities from with threads and UserIdentity.Contexts.
+ * 
+ */
+public interface IdentityService
+{
+    final static String[] NO_ROLES = new String[]{}; 
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Associate a user identity with the current thread.
+     * This is called with as a thread enters the 
+     * {@link SecurityHandler#handle(String, Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+     * method and then again with a null argument as that call exits.
+     * @param user The current user or null for no user to associated.
+     * @return an object representing the previous associated state
+     */
+    Object associate(UserIdentity user);
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * Disassociate the user identity from the current thread 
+     * and restore previous identity.
+     * @param previous The opaque object returned from a call to {@link IdentityService#associate(UserIdentity)}
+     */
+    void disassociate(Object previous);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Associate a runas Token with the current user and thread.
+     * @param user The UserIdentity
+     * @param token The runAsToken to associate.
+     * @return The previous runAsToken or null.
+     */
+    Object setRunAs(UserIdentity user, RunAsToken token);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Disassociate the current runAsToken from the thread
+     * and reassociate the previous token.
+     * @param token RUNAS returned from previous associateRunAs call
+     */
+    void unsetRunAs(Object token);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new UserIdentity for use with this identity service.
+     * The UserIdentity should be immutable and able to be cached.
+     * 
+     * @param subject Subject to include in UserIdentity
+     * @param userPrincipal Principal to include in UserIdentity.  This will be returned from getUserPrincipal calls
+     * @param roles set of roles to include in UserIdentity.
+     * @return A new immutable UserIdententity
+     */
+    UserIdentity newUserIdentity(Subject subject, Principal userPrincipal, String[] roles);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create a new RunAsToken from a runAsName (normally a role).
+     * @param runAsName Normally a role name
+     * @return A new immutable RunAsToken
+     */
+    RunAsToken newRunAsToken(String runAsName);
+
+    /* ------------------------------------------------------------ */
+    UserIdentity getSystemUserIdentity();
+}
diff --git a/src/java/org/eclipse/jetty/security/JDBCLoginService.java b/src/java/org/eclipse/jetty/security/JDBCLoginService.java
new file mode 100644
index 0000000..8fd9edf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/JDBCLoginService.java
@@ -0,0 +1,283 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
+
+/* ------------------------------------------------------------ */
+/**
+ * HashMapped User Realm with JDBC as data source. JDBCLoginService extends
+ * HashULoginService and adds a method to fetch user information from database.
+ * The login() method checks the inherited Map for the user. If the user is not
+ * found, it will fetch details from the database and populate the inherited
+ * Map. It then calls the superclass login() method to perform the actual
+ * authentication. Periodically (controlled by configuration parameter),
+ * internal hashes are cleared. Caching can be disabled by setting cache refresh
+ * interval to zero. Uses one database connection that is initialized at
+ * startup. Reconnect on failures. authenticate() is 'synchronized'.
+ * 
+ * An example properties file for configuration is in
+ * $JETTY_HOME/etc/jdbcRealm.properties
+ * 
+ * @version $Id: JDBCLoginService.java 4792 2009-03-18 21:55:52Z gregw $
+ * 
+ * 
+ * 
+ * 
+ */
+
+public class JDBCLoginService extends MappedLoginService
+{
+    private static final Logger LOG = Log.getLogger(JDBCLoginService.class);
+
+    private String _config;
+    private String _jdbcDriver;
+    private String _url;
+    private String _userName;
+    private String _password;
+    private String _userTableKey;
+    private String _userTablePasswordField;
+    private String _roleTableRoleField;
+    private int _cacheTime;
+    private long _lastHashPurge;
+    private Connection _con;
+    private String _userSql;
+    private String _roleSql;
+
+
+    /* ------------------------------------------------------------ */
+    public JDBCLoginService()
+        throws IOException
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    public JDBCLoginService(String name)
+        throws IOException
+    {
+        setName(name);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public JDBCLoginService(String name, String config)
+        throws IOException
+    {
+        setName(name);
+        setConfig(config);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public JDBCLoginService(String name, IdentityService identityService, String config)
+        throws IOException
+    {
+        setName(name);
+        setIdentityService(identityService);
+        setConfig(config);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.MappedLoginService#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        Properties properties = new Properties();
+        Resource resource = Resource.newResource(_config);
+        properties.load(resource.getInputStream());
+
+        _jdbcDriver = properties.getProperty("jdbcdriver");
+        _url = properties.getProperty("url");
+        _userName = properties.getProperty("username");
+        _password = properties.getProperty("password");
+        String _userTable = properties.getProperty("usertable");
+        _userTableKey = properties.getProperty("usertablekey");
+        String _userTableUserField = properties.getProperty("usertableuserfield");
+        _userTablePasswordField = properties.getProperty("usertablepasswordfield");
+        String _roleTable = properties.getProperty("roletable");
+        String _roleTableKey = properties.getProperty("roletablekey");
+        _roleTableRoleField = properties.getProperty("roletablerolefield");
+        String _userRoleTable = properties.getProperty("userroletable");
+        String _userRoleTableUserKey = properties.getProperty("userroletableuserkey");
+        String _userRoleTableRoleKey = properties.getProperty("userroletablerolekey");
+        _cacheTime = new Integer(properties.getProperty("cachetime"));
+
+        if (_jdbcDriver == null || _jdbcDriver.equals("")
+            || _url == null
+            || _url.equals("")
+            || _userName == null
+            || _userName.equals("")
+            || _password == null
+            || _cacheTime < 0)
+        {
+            LOG.warn("UserRealm " + getName() + " has not been properly configured");
+        }
+        _cacheTime *= 1000;
+        _lastHashPurge = 0;
+        _userSql = "select " + _userTableKey + "," + _userTablePasswordField + " from " + _userTable + " where " + _userTableUserField + " = ?";
+        _roleSql = "select r." + _roleTableRoleField
+                   + " from "
+                   + _roleTable
+                   + " r, "
+                   + _userRoleTable
+                   + " u where u."
+                   + _userRoleTableUserKey
+                   + " = ?"
+                   + " and r."
+                   + _roleTableKey
+                   + " = u."
+                   + _userRoleTableRoleKey;
+        
+        Loader.loadClass(this.getClass(), _jdbcDriver).newInstance();
+        super.doStart();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public String getConfig()
+    {
+        return _config;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Load JDBC connection configuration from properties file.
+     * 
+     * @param config Filename or url of user properties file.
+     */
+    public void setConfig(String config)
+    {        
+        if (isRunning())
+            throw new IllegalStateException("Running");
+        _config=config;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * (re)Connect to database with parameters setup by loadConfig()
+     */
+    public void connectDatabase()
+    {
+        try
+        {
+            Class.forName(_jdbcDriver);
+            _con = DriverManager.getConnection(_url, _userName, _password);
+        }
+        catch (SQLException e)
+        {
+            LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
+        }
+        catch (ClassNotFoundException e)
+        {
+            LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public UserIdentity login(String username, Object credentials)
+    {
+        long now = System.currentTimeMillis();
+        if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
+        {
+            _users.clear();
+            _lastHashPurge = now;
+            closeConnection();
+        }
+        
+        return super.login(username,credentials);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void loadUsers()
+    {   
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    protected UserIdentity loadUser(String username)
+    {
+        try
+        {
+            if (null == _con) 
+                connectDatabase();
+
+            if (null == _con) 
+                throw new SQLException("Can't connect to database");
+
+            PreparedStatement stat = _con.prepareStatement(_userSql);
+            stat.setObject(1, username);
+            ResultSet rs = stat.executeQuery();
+
+            if (rs.next())
+            {
+                int key = rs.getInt(_userTableKey);
+                String credentials = rs.getString(_userTablePasswordField);
+                stat.close();
+
+                stat = _con.prepareStatement(_roleSql);
+                stat.setInt(1, key);
+                rs = stat.executeQuery();
+                List<String> roles = new ArrayList<String>();
+                while (rs.next())
+                    roles.add(rs.getString(_roleTableRoleField));
+
+                stat.close();
+                return putUser(username, Credential.getCredential(credentials),roles.toArray(new String[roles.size()]));
+            }
+        }
+        catch (SQLException e)
+        {
+            LOG.warn("UserRealm " + getName() + " could not load user information from database", e);
+            closeConnection();
+        }
+        return null;
+    }
+
+    /**
+     * Close an existing connection
+     */
+    private void closeConnection ()
+    {
+        if (_con != null)
+        {
+            if (LOG.isDebugEnabled()) LOG.debug("Closing db connection for JDBCUserRealm");
+            try { _con.close(); }catch (Exception e) {LOG.ignore(e);}
+        }
+        _con = null;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/LoginService.java b/src/java/org/eclipse/jetty/security/LoginService.java
new file mode 100644
index 0000000..1e64141
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/LoginService.java
@@ -0,0 +1,72 @@
+//
+//  ========================================================================
+//  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.security;
+
+import org.eclipse.jetty.server.UserIdentity;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Login Service Interface.
+ * <p>
+ * The Login service provides an abstract mechanism for an {@link Authenticator}
+ * to check credentials and to create a {@link UserIdentity} using the 
+ * set {@link IdentityService}.
+ */
+public interface LoginService
+{
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Get the name of the login service (aka Realm name)
+     */
+    String getName();
+    
+    /* ------------------------------------------------------------ */
+    /** Login a user.
+     * @param username The user name
+     * @param credentials The users credentials
+     * @return A UserIdentity if the credentials matched, otherwise null
+     */
+    UserIdentity login(String username,Object credentials);
+    
+    /* ------------------------------------------------------------ */
+    /** Validate a user identity.
+     * Validate that a UserIdentity previously created by a call 
+     * to {@link #login(String, Object)} is still valid.
+     * @param user The user to validate
+     * @return true if authentication has not been revoked for the user.
+     */
+    boolean validate(UserIdentity user);
+    
+    /* ------------------------------------------------------------ */
+    /** Get the IdentityService associated with this Login Service.
+     * @return the IdentityService associated with this Login Service.
+     */
+    IdentityService getIdentityService();
+    
+    /* ------------------------------------------------------------ */
+    /** Set the IdentityService associated with this Login Service.
+     * @param service the IdentityService associated with this Login Service.
+     */
+    void setIdentityService(IdentityService service);
+    
+    void logout(UserIdentity user);
+
+}
diff --git a/src/java/org/eclipse/jetty/security/MappedLoginService.java b/src/java/org/eclipse/jetty/security/MappedLoginService.java
new file mode 100644
index 0000000..6e3645a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/MappedLoginService.java
@@ -0,0 +1,340 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Credential;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * A login service that keeps UserIdentities in a concurrent map
+ * either as the source or a cache of the users.
+ * 
+ */
+public abstract class MappedLoginService extends AbstractLifeCycle implements LoginService
+{
+    private static final Logger LOG = Log.getLogger(MappedLoginService.class);
+
+    protected IdentityService _identityService=new DefaultIdentityService();
+    protected String _name;
+    protected final ConcurrentMap<String, UserIdentity> _users=new ConcurrentHashMap<String, UserIdentity>();
+
+    /* ------------------------------------------------------------ */
+    protected MappedLoginService()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the name.
+     * @return the name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the identityService.
+     * @return the identityService
+     */
+    public IdentityService getIdentityService()
+    {
+        return _identityService;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the users.
+     * @return the users
+     */
+    public ConcurrentMap<String, UserIdentity> getUsers()
+    {
+        return _users;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the identityService.
+     * @param identityService the identityService to set
+     */
+    public void setIdentityService(IdentityService identityService)
+    {
+        if (isRunning())
+            throw new IllegalStateException("Running");
+        _identityService = identityService;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the name.
+     * @param name the name to set
+     */
+    public void setName(String name)
+    {
+        if (isRunning())
+            throw new IllegalStateException("Running");
+        _name = name;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the users.
+     * @param users the users to set
+     */
+    public void setUsers(Map<String, UserIdentity> users)
+    {
+        if (isRunning())
+            throw new IllegalStateException("Running");
+        _users.clear();
+        _users.putAll(users);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        loadUsers();
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void logout(UserIdentity identity)
+    {   
+        LOG.debug("logout {}",identity);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return this.getClass().getSimpleName()+"["+_name+"]";
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Put user into realm.
+     * Called by implementations to put the user data loaded from
+     * file/db etc into the user structure.
+     * @param userName User name
+     * @param info a UserIdentity instance, or a String password or Credential instance
+     * @return User instance
+     */
+    protected synchronized UserIdentity putUser(String userName, Object info)
+    {
+        final UserIdentity identity;
+        if (info instanceof UserIdentity)
+            identity=(UserIdentity)info;
+        else
+        {
+            Credential credential = (info instanceof Credential)?(Credential)info:Credential.getCredential(info.toString());
+            
+            Principal userPrincipal = new KnownUser(userName,credential);
+            Subject subject = new Subject();
+            subject.getPrincipals().add(userPrincipal);
+            subject.getPrivateCredentials().add(credential);
+            subject.setReadOnly();
+            identity=_identityService.newUserIdentity(subject,userPrincipal,IdentityService.NO_ROLES);
+        }
+        
+        _users.put(userName,identity);
+        return identity;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Put user into realm.
+     * @param userName The user to add
+     * @param credential The users Credentials
+     * @param roles The users roles
+     * @return UserIdentity
+     */
+    public synchronized UserIdentity putUser(String userName, Credential credential, String[] roles)
+    {
+        Principal userPrincipal = new KnownUser(userName,credential);
+        Subject subject = new Subject();
+        subject.getPrincipals().add(userPrincipal);
+        subject.getPrivateCredentials().add(credential);
+        
+        if (roles!=null)
+            for (String role : roles)
+                subject.getPrincipals().add(new RolePrincipal(role));
+
+        subject.setReadOnly();
+        UserIdentity identity=_identityService.newUserIdentity(subject,userPrincipal,roles);
+        _users.put(userName,identity);
+        return identity;
+    } 
+    
+    /* ------------------------------------------------------------ */
+    public void removeUser(String username)
+    {
+        _users.remove(username);
+    }   
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.LoginService#login(java.lang.String, java.lang.Object)
+     */
+    public UserIdentity login(String username, Object credentials)
+    {
+        UserIdentity user = _users.get(username);
+        
+        if (user==null)
+            user = loadUser(username);
+        
+        if (user!=null)
+        {
+            UserPrincipal principal = (UserPrincipal)user.getUserPrincipal();
+            if (principal.authenticate(credentials))
+                return user;
+        }
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean validate(UserIdentity user)
+    {
+        if (_users.containsKey(user.getUserPrincipal().getName()))
+            return true;
+        
+        if (loadUser(user.getUserPrincipal().getName())!=null)
+            return true;
+                
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected abstract UserIdentity loadUser(String username);
+    
+    /* ------------------------------------------------------------ */
+    protected abstract void loadUsers() throws IOException;
+
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public interface UserPrincipal extends Principal,Serializable
+    {
+        boolean authenticate(Object credentials);
+        public boolean isAuthenticated();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static class RolePrincipal implements Principal,Serializable
+    {
+        private static final long serialVersionUID = 2998397924051854402L;
+        private final String _roleName;
+        public RolePrincipal(String name)
+        {
+            _roleName=name;
+        }
+        public String getName()
+        {
+            return _roleName;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static class Anonymous implements UserPrincipal,Serializable
+    {
+        private static final long serialVersionUID = 1097640442553284845L;
+
+        public boolean isAuthenticated()
+        {
+            return false;
+        }
+
+        public String getName()
+        {
+            return "Anonymous";
+        }
+        
+        public boolean authenticate(Object credentials)
+        {
+            return false;
+        }
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static class KnownUser implements UserPrincipal,Serializable
+    {
+        private static final long serialVersionUID = -6226920753748399662L;
+        private final String _name;
+        private final Credential _credential;
+        
+        /* -------------------------------------------------------- */
+        public KnownUser(String name,Credential credential)
+        {
+            _name=name;
+            _credential=credential;
+        }
+
+        /* -------------------------------------------------------- */
+        public boolean authenticate(Object credentials)
+        {
+            return _credential!=null && _credential.check(credentials);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public String getName()
+        {
+            return _name;
+        }
+        
+        /* -------------------------------------------------------- */
+        public boolean isAuthenticated()
+        {
+            return true;
+        }
+
+        /* -------------------------------------------------------- */
+        @Override
+        public String toString()
+        {
+            return _name;
+        }
+    }
+}
+
diff --git a/src/java/org/eclipse/jetty/security/PropertyUserStore.java b/src/java/org/eclipse/jetty/security/PropertyUserStore.java
new file mode 100644
index 0000000..74e689f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/PropertyUserStore.java
@@ -0,0 +1,356 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.security.MappedLoginService.KnownUser;
+import org.eclipse.jetty.security.MappedLoginService.RolePrincipal;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.Scanner;
+import org.eclipse.jetty.util.Scanner.BulkListener;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
+
+/**
+ * PropertyUserStore
+ * 
+ * This class monitors a property file of the format mentioned below and notifies registered listeners of the changes to the the given file.
+ * 
+ * <PRE>
+ *  username: password [,rolename ...]
+ * </PRE>
+ * 
+ * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password
+ * checksums.
+ * 
+ * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:.
+ */
+public class PropertyUserStore extends AbstractLifeCycle
+{
+    private static final Logger LOG = Log.getLogger(PropertyUserStore.class);
+
+    private String _config;
+    private Resource _configResource;
+    private Scanner _scanner;
+    private int _refreshInterval = 0;// default is not to reload
+
+    private IdentityService _identityService = new DefaultIdentityService();
+    private boolean _firstLoad = true; // true if first load, false from that point on
+    private final List<String> _knownUsers = new ArrayList<String>();
+    private final Map<String, UserIdentity> _knownUserIdentities = new HashMap<String, UserIdentity>();
+    private List<UserListener> _listeners;
+
+    /* ------------------------------------------------------------ */
+    public String getConfig()
+    {
+        return _config;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setConfig(String config)
+    {
+        _config = config;
+    }
+    
+    /* ------------------------------------------------------------ */
+        public UserIdentity getUserIdentity(String userName)
+        {
+            return _knownUserIdentities.get(userName);
+        }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * returns the resource associated with the configured properties file, creating it if necessary
+     */
+    public Resource getConfigResource() throws IOException
+    {
+        if (_configResource == null)
+        {
+            _configResource = Resource.newResource(_config);
+        }
+
+        return _configResource;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * sets the refresh interval (in seconds)
+     */
+    public void setRefreshInterval(int msec)
+    {
+        _refreshInterval = msec;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * refresh interval in seconds for how often the properties file should be checked for changes
+     */
+    public int getRefreshInterval()
+    {
+        return _refreshInterval;
+    }
+
+    /* ------------------------------------------------------------ */
+    private void loadUsers() throws IOException
+    {
+        if (_config == null)
+            return;
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("Load " + this + " from " + _config);
+        Properties properties = new Properties();
+        if (getConfigResource().exists())
+            properties.load(getConfigResource().getInputStream());
+        Set<String> known = new HashSet<String>();
+
+        for (Map.Entry<Object, Object> entry : properties.entrySet())
+        {
+            String username = ((String)entry.getKey()).trim();
+            String credentials = ((String)entry.getValue()).trim();
+            String roles = null;
+            int c = credentials.indexOf(',');
+            if (c > 0)
+            {
+                roles = credentials.substring(c + 1).trim();
+                credentials = credentials.substring(0,c).trim();
+            }
+
+            if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
+            {
+                String[] roleArray = IdentityService.NO_ROLES;
+                if (roles != null && roles.length() > 0)
+                {
+                    roleArray = roles.split(",");
+                }
+                known.add(username);
+                Credential credential = Credential.getCredential(credentials);
+                
+                Principal userPrincipal = new KnownUser(username,credential);
+                Subject subject = new Subject();
+                subject.getPrincipals().add(userPrincipal);
+                subject.getPrivateCredentials().add(credential);
+
+                if (roles != null)
+                {
+                    for (String role : roleArray)
+                    {
+                        subject.getPrincipals().add(new RolePrincipal(role));
+                    }
+                }
+                
+                subject.setReadOnly();
+                
+                _knownUserIdentities.put(username,_identityService.newUserIdentity(subject,userPrincipal,roleArray));
+                notifyUpdate(username,credential,roleArray);
+            }
+        }
+
+        synchronized (_knownUsers)
+        {
+            /*
+             * if its not the initial load then we want to process removed users
+             */
+            if (!_firstLoad)
+            {
+                Iterator<String> users = _knownUsers.iterator();
+                while (users.hasNext())
+                {
+                    String user = users.next();
+                    if (!known.contains(user))
+                    {
+                        _knownUserIdentities.remove(user);
+                        notifyRemove(user);
+                    }
+                }
+            }
+
+            /*
+             * reset the tracked _users list to the known users we just processed
+             */
+
+            _knownUsers.clear();
+            _knownUsers.addAll(known);
+
+        }
+
+        /*
+         * set initial load to false as there should be no more initial loads
+         */
+        _firstLoad = false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Depending on the value of the refresh interval, this method will either start up a scanner thread that will monitor the properties file for changes after
+     * it has initially loaded it. Otherwise the users will be loaded and there will be no active monitoring thread so changes will not be detected.
+     * 
+     * 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+
+        if (getRefreshInterval() > 0)
+        {
+            _scanner = new Scanner();
+            _scanner.setScanInterval(getRefreshInterval());
+            List<File> dirList = new ArrayList<File>(1);
+            dirList.add(getConfigResource().getFile().getParentFile());
+            _scanner.setScanDirs(dirList);
+            _scanner.setFilenameFilter(new FilenameFilter()
+            {
+                public boolean accept(File dir, String name)
+                {
+                    File f = new File(dir,name);
+                    try
+                    {
+                        if (f.compareTo(getConfigResource().getFile()) == 0)
+                        {
+                            return true;
+                        }
+                    }
+                    catch (IOException e)
+                    {
+                        return false;
+                    }
+
+                    return false;
+                }
+
+            });
+
+            _scanner.addListener(new BulkListener()
+            {
+                public void filesChanged(List<String> filenames) throws Exception
+                {
+                    if (filenames == null)
+                        return;
+                    if (filenames.isEmpty())
+                        return;
+                    if (filenames.size() == 1)
+                    {
+                        Resource r = Resource.newResource(filenames.get(0));
+                        if (r.getFile().equals(_configResource.getFile()))
+                            loadUsers();
+                    }
+                }
+
+                public String toString()
+                {
+                    return "PropertyUserStore$Scanner";
+                }
+
+            });
+
+            _scanner.setReportExistingFilesOnStartup(true);
+            _scanner.setRecursive(false);
+            _scanner.start();
+        }
+        else
+        {
+            loadUsers();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        if (_scanner != null)
+            _scanner.stop();
+        _scanner = null;
+    }
+
+    /**
+     * Notifies the registered listeners of potential updates to a user
+     * 
+     * @param username
+     * @param credential
+     * @param roleArray
+     */
+    private void notifyUpdate(String username, Credential credential, String[] roleArray)
+    {
+        if (_listeners != null)
+        {
+            for (Iterator<UserListener> i = _listeners.iterator(); i.hasNext();)
+            {
+                i.next().update(username,credential,roleArray);
+            }
+        }
+    }
+
+    /**
+     * notifies the registered listeners that a user has been removed.
+     * 
+     * @param username
+     */
+    private void notifyRemove(String username)
+    {
+        if (_listeners != null)
+        {
+            for (Iterator<UserListener> i = _listeners.iterator(); i.hasNext();)
+            {
+                i.next().remove(username);
+            }
+        }
+    }
+
+    /**
+     * registers a listener to be notified of the contents of the property file
+     */
+    public void registerUserListener(UserListener listener)
+    {
+        if (_listeners == null)
+        {
+            _listeners = new ArrayList<UserListener>();
+        }
+        _listeners.add(listener);
+    }
+
+    /**
+     * UserListener
+     */
+    public interface UserListener
+    {
+        public void update(String username, Credential credential, String[] roleArray);
+
+        public void remove(String username);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/RoleInfo.java b/src/java/org/eclipse/jetty/security/RoleInfo.java
new file mode 100644
index 0000000..730995f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/RoleInfo.java
@@ -0,0 +1,143 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * 
+ * Badly named class that holds the role and user data constraint info for a
+ * path/http method combination, extracted and combined from security
+ * constraints.
+ * 
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class RoleInfo
+{
+    private boolean _isAnyRole;
+    private boolean _checked;
+    private boolean _forbidden;
+    private UserDataConstraint _userDataConstraint;
+
+    private final Set<String> _roles = new CopyOnWriteArraySet<String>();
+
+    public RoleInfo()
+    {    
+    }
+    
+    public boolean isChecked()
+    {
+        return _checked;
+    }
+
+    public void setChecked(boolean checked)
+    {
+        this._checked = checked;
+        if (!checked)
+        {
+            _forbidden=false;
+            _roles.clear();
+            _isAnyRole=false;
+        }
+    }
+
+    public boolean isForbidden()
+    {
+        return _forbidden;
+    }
+
+    public void setForbidden(boolean forbidden)
+    {
+        this._forbidden = forbidden;
+        if (forbidden)
+        {
+            _checked = true;
+            _userDataConstraint = null;
+            _isAnyRole=false;
+            _roles.clear();
+        }
+    }
+
+    public boolean isAnyRole()
+    {
+        return _isAnyRole;
+    }
+
+    public void setAnyRole(boolean anyRole)
+    {
+        this._isAnyRole=anyRole;
+        if (anyRole)
+        {
+            _checked = true;
+            _roles.clear();
+        }
+    }
+
+    public UserDataConstraint getUserDataConstraint()
+    {
+        return _userDataConstraint;
+    }
+
+    public void setUserDataConstraint(UserDataConstraint userDataConstraint)
+    {
+        if (userDataConstraint == null) throw new NullPointerException("Null UserDataConstraint");
+        if (this._userDataConstraint == null)
+        {
+            this._userDataConstraint = userDataConstraint;
+        }
+        else
+        {
+            this._userDataConstraint = this._userDataConstraint.combine(userDataConstraint);
+        }
+    }
+
+    public Set<String> getRoles()
+    {
+        return _roles;
+    }
+    
+    public void addRole(String role)
+    {
+        _roles.add(role);
+    }
+
+    public void combine(RoleInfo other)
+    {
+        if (other._forbidden)
+            setForbidden(true);
+        else if (!other._checked) // TODO is this the right way around???
+            setChecked(true);
+        else if (other._isAnyRole)
+            setAnyRole(true);
+        else if (!_isAnyRole)
+        {
+            for (String r : other._roles)
+                _roles.add(r);
+        }
+        
+        setUserDataConstraint(other._userDataConstraint);
+    }
+    
+    @Override
+    public String toString()
+    {
+        return "{RoleInfo"+(_forbidden?",F":"")+(_checked?",C":"")+(_isAnyRole?",*":_roles)+"}";
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/RoleRunAsToken.java b/src/java/org/eclipse/jetty/security/RoleRunAsToken.java
new file mode 100644
index 0000000..13a7ea7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/RoleRunAsToken.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.security;
+
+
+
+/**
+ * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $
+ */
+public class RoleRunAsToken implements RunAsToken
+{
+    private final String _runAsRole;
+
+    public RoleRunAsToken(String runAsRole)
+    {
+        this._runAsRole = runAsRole;
+    }
+
+    public String getRunAsRole()
+    {
+        return _runAsRole;
+    }
+
+    public String toString()
+    {
+        return "RoleRunAsToken("+_runAsRole+")";
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/RunAsToken.java b/src/java/org/eclipse/jetty/security/RunAsToken.java
new file mode 100644
index 0000000..639c972
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/RunAsToken.java
@@ -0,0 +1,27 @@
+//
+//  ========================================================================
+//  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.security;
+
+/**
+ * marker interface for run-as-role tokens
+ * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $
+ */
+public interface RunAsToken
+{
+}
diff --git a/src/java/org/eclipse/jetty/security/SecurityHandler.java b/src/java/org/eclipse/jetty/security/SecurityHandler.java
new file mode 100644
index 0000000..4e55183
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/SecurityHandler.java
@@ -0,0 +1,685 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.eclipse.jetty.security.authentication.DeferredAuthentication;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.server.session.AbstractSessionManager;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Abstract SecurityHandler.
+ * Select and apply an {@link Authenticator} to a request.
+ * <p>
+ * The Authenticator may either be directly set on the handler
+ * or will be create during {@link #start()} with a call to
+ * either the default or set AuthenticatorFactory.
+ * <p>
+ * SecurityHandler has a set of initparameters that are used by the 
+ * Authentication.Configuration. At startup, any context init parameters
+ * that start with "org.eclipse.jetty.security." that do not have 
+ * values in the SecurityHandler init parameters, are copied.  
+ * 
+ */
+public abstract class SecurityHandler extends HandlerWrapper implements Authenticator.AuthConfiguration
+{
+    private static final Logger LOG = Log.getLogger(SecurityHandler.class);
+
+    /* ------------------------------------------------------------ */
+    private boolean _checkWelcomeFiles = false;
+    private Authenticator _authenticator;
+    private Authenticator.Factory _authenticatorFactory=new DefaultAuthenticatorFactory();
+    private String _realmName;
+    private String _authMethod;
+    private final Map<String,String> _initParameters=new HashMap<String,String>();
+    private LoginService _loginService;
+    private boolean _loginServiceShared;
+    private IdentityService _identityService;
+    private boolean _renewSession=true;
+
+    /* ------------------------------------------------------------ */
+    protected SecurityHandler()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the identityService.
+     * @return the identityService
+     */
+    public IdentityService getIdentityService()
+    {
+        return _identityService;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the identityService.
+     * @param identityService the identityService to set
+     */
+    public void setIdentityService(IdentityService identityService)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Started");
+        _identityService = identityService;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the loginService.
+     * @return the loginService
+     */
+    public LoginService getLoginService()
+    {
+        return _loginService;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the loginService.
+     * @param loginService the loginService to set
+     */
+    public void setLoginService(LoginService loginService)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Started");
+        _loginService = loginService;
+        _loginServiceShared=false;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public Authenticator getAuthenticator()
+    {
+        return _authenticator;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the authenticator.
+     * @param authenticator
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public void setAuthenticator(Authenticator authenticator)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Started");
+        _authenticator = authenticator;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the authenticatorFactory
+     */
+    public Authenticator.Factory getAuthenticatorFactory()
+    {
+        return _authenticatorFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param authenticatorFactory the authenticatorFactory to set
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public void setAuthenticatorFactory(Authenticator.Factory authenticatorFactory)
+    {
+        if (isRunning())
+            throw new IllegalStateException("running");
+        _authenticatorFactory = authenticatorFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the realmName
+     */
+    public String getRealmName()
+    {
+        return _realmName;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param realmName the realmName to set
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public void setRealmName(String realmName)
+    {
+        if (isRunning())
+            throw new IllegalStateException("running");
+        _realmName = realmName;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the authMethod
+     */
+    public String getAuthMethod()
+    {
+        return _authMethod;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param authMethod the authMethod to set
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public void setAuthMethod(String authMethod)
+    {
+        if (isRunning())
+            throw new IllegalStateException("running");
+        _authMethod = authMethod;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if forwards to welcome files are authenticated
+     */
+    public boolean isCheckWelcomeFiles()
+    {
+        return _checkWelcomeFiles;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param authenticateWelcomeFiles True if forwards to welcome files are
+     *                authenticated
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public void setCheckWelcomeFiles(boolean authenticateWelcomeFiles)
+    {
+        if (isRunning())
+            throw new IllegalStateException("running");
+        _checkWelcomeFiles = authenticateWelcomeFiles;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getInitParameter(String key)
+    {
+        return _initParameters.get(key);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Set<String> getInitParameterNames()
+    {
+        return _initParameters.keySet();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set an initialization parameter.
+     * @param key
+     * @param value
+     * @return previous value
+     * @throws IllegalStateException if the SecurityHandler is running
+     */
+    public String setInitParameter(String key, String value)
+    {
+        if (isRunning())
+            throw new IllegalStateException("running");
+        return _initParameters.put(key,value);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected LoginService findLoginService()
+    {
+        List<LoginService> list = getServer().getBeans(LoginService.class);
+        
+        String realm=getRealmName();
+        if (realm!=null)
+        {
+            for (LoginService service : list)
+                if (service.getName()!=null && service.getName().equals(realm))
+                    return service;
+        }
+        else if (list.size()==1)
+            return list.get(0);
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected IdentityService findIdentityService()
+    {
+        return getServer().getBean(IdentityService.class);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     */
+    @Override
+    protected void doStart()
+        throws Exception
+    {
+        // copy security init parameters
+        ContextHandler.Context context =ContextHandler.getCurrentContext();
+        if (context!=null)
+        {
+            Enumeration<String> names=context.getInitParameterNames();
+            while (names!=null && names.hasMoreElements())
+            {
+                String name =names.nextElement();
+                if (name.startsWith("org.eclipse.jetty.security.") &&
+                        getInitParameter(name)==null)
+                    setInitParameter(name,context.getInitParameter(name));
+            }
+            
+            //register a session listener to handle securing sessions when authentication is performed
+            context.getContextHandler().addEventListener(new HttpSessionListener()
+            {
+                
+                public void sessionDestroyed(HttpSessionEvent se)
+                {
+                   
+                }
+                
+                public void sessionCreated(HttpSessionEvent se)
+                {
+                    //if current request is authenticated, then as we have just created the session, mark it as secure, as it has not yet been returned to a user
+                    AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
+                    if (connection == null)
+                        return;
+                    Request request = connection.getRequest();
+                    if (request == null)
+                        return;
+                    
+                    if (request.isSecure())
+                    {
+                        se.getSession().setAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE);
+                    }
+                }
+            });
+        }
+        
+        // complicated resolution of login and identity service to handle
+        // many different ways these can be constructed and injected.
+        
+        if (_loginService==null)
+        {
+            _loginService=findLoginService();
+            if (_loginService!=null)
+                _loginServiceShared=true;
+        }
+        
+        if (_identityService==null)
+        {
+           
+            if (_loginService!=null)
+                _identityService=_loginService.getIdentityService();
+
+            if (_identityService==null)
+                _identityService=findIdentityService();
+            
+            if (_identityService==null && _realmName!=null)
+                _identityService=new DefaultIdentityService();
+        }
+        
+        if (_loginService!=null)
+        {
+            if (_loginService.getIdentityService()==null)
+                _loginService.setIdentityService(_identityService);
+            else if (_loginService.getIdentityService()!=_identityService)
+                throw new IllegalStateException("LoginService has different IdentityService to "+this);
+        }
+
+        if (!_loginServiceShared && _loginService instanceof LifeCycle)
+            ((LifeCycle)_loginService).start();        
+        
+        if (_authenticator==null && _authenticatorFactory!=null && _identityService!=null)
+        {
+            _authenticator=_authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this, _identityService, _loginService);
+            if (_authenticator!=null)
+                _authMethod=_authenticator.getAuthMethod();
+        }
+
+        if (_authenticator==null)
+        {
+            if (_realmName!=null)
+            {
+                LOG.warn("No ServerAuthentication for "+this);
+                throw new IllegalStateException("No ServerAuthentication");
+            }
+        }
+        else
+        {
+            _authenticator.setConfiguration(this);
+            if (_authenticator instanceof LifeCycle)
+                ((LifeCycle)_authenticator).start();
+        }
+
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        
+        if (!_loginServiceShared && _loginService instanceof LifeCycle)
+            ((LifeCycle)_loginService).stop();
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    protected boolean checkSecurity(Request request)
+    {
+        switch(request.getDispatcherType())
+        {
+            case REQUEST:
+            case ASYNC:
+                return true;
+            case FORWARD:
+                if (_checkWelcomeFiles && request.getAttribute("org.eclipse.jetty.server.welcome") != null)
+                {
+                    request.removeAttribute("org.eclipse.jetty.server.welcome");
+                    return true;
+                }
+                return false;
+            default:
+                return false;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication()
+     */
+    public boolean isSessionRenewedOnAuthentication()
+    {
+        return _renewSession;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set renew the session on Authentication.
+     * <p>
+     * If set to true, then on authentication, the session associated with a reqeuest is invalidated and replaced with a new session.
+     * @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication()
+     */
+    public void setSessionRenewedOnAuthentication(boolean renew)
+    {
+        _renewSession=renew;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Handler#handle(java.lang.String,
+     *      javax.servlet.http.HttpServletRequest,
+     *      javax.servlet.http.HttpServletResponse, int)
+     */
+    @Override
+    public void handle(String pathInContext, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        final Response base_response = baseRequest.getResponse();
+        final Handler handler=getHandler();
+        
+        if (handler==null)
+            return;
+
+        final Authenticator authenticator = _authenticator;
+        
+        if (checkSecurity(baseRequest))
+        {
+            Object constraintInfo = prepareConstraintInfo(pathInContext, baseRequest);
+            
+            // Check data constraints
+            if (!checkUserDataPermissions(pathInContext, baseRequest, base_response, constraintInfo))
+            {
+                if (!baseRequest.isHandled())
+                {
+                    response.sendError(Response.SC_FORBIDDEN);
+                    baseRequest.setHandled(true);
+                }
+                return;
+            }
+
+            // is Auth mandatory?
+            boolean isAuthMandatory = 
+                isAuthMandatory(baseRequest, base_response, constraintInfo);
+
+            if (isAuthMandatory && authenticator==null)
+            {
+                LOG.warn("No authenticator for: "+constraintInfo);
+                if (!baseRequest.isHandled())
+                {
+                    response.sendError(Response.SC_FORBIDDEN);
+                    baseRequest.setHandled(true);
+                }
+                return;
+            }
+            
+            // check authentication
+            Object previousIdentity = null;
+            try
+            {
+                Authentication authentication = baseRequest.getAuthentication();
+                if (authentication==null || authentication==Authentication.NOT_CHECKED)
+                    authentication=authenticator==null?Authentication.UNAUTHENTICATED:authenticator.validateRequest(request, response, isAuthMandatory);
+
+                if (authentication instanceof Authentication.Wrapped)
+                {
+                    request=((Authentication.Wrapped)authentication).getHttpServletRequest();
+                    response=((Authentication.Wrapped)authentication).getHttpServletResponse();
+                }
+
+                if (authentication instanceof Authentication.ResponseSent)
+                {
+                    baseRequest.setHandled(true);
+                }
+                else if (authentication instanceof Authentication.User)
+                {
+                    Authentication.User userAuth = (Authentication.User)authentication;
+                    baseRequest.setAuthentication(authentication);
+                    if (_identityService!=null)
+                        previousIdentity = _identityService.associate(userAuth.getUserIdentity());
+
+                    if (isAuthMandatory)
+                    {
+                        boolean authorized=checkWebResourcePermissions(pathInContext, baseRequest, base_response, constraintInfo, userAuth.getUserIdentity());
+                        if (!authorized)
+                        {
+                            response.sendError(Response.SC_FORBIDDEN, "!role");
+                            baseRequest.setHandled(true);
+                            return;
+                        }
+                    }
+                         
+                    handler.handle(pathInContext, baseRequest, request, response);
+                    if (authenticator!=null)
+                        authenticator.secureResponse(request, response, isAuthMandatory, userAuth);
+                }
+                else if (authentication instanceof Authentication.Deferred)
+                {
+                    DeferredAuthentication deferred= (DeferredAuthentication)authentication;
+                    baseRequest.setAuthentication(authentication);
+
+                    try
+                    {
+                        handler.handle(pathInContext, baseRequest, request, response);
+                    }
+                    finally
+                    {
+                        previousIdentity = deferred.getPreviousAssociation();
+                    }
+
+                    if (authenticator!=null)
+                    {
+                        Authentication auth=baseRequest.getAuthentication();
+                        if (auth instanceof Authentication.User)
+                        {
+                            Authentication.User userAuth = (Authentication.User)auth;
+                            authenticator.secureResponse(request, response, isAuthMandatory, userAuth);
+                        }
+                        else
+                            authenticator.secureResponse(request, response, isAuthMandatory, null);
+                    }
+                }
+                else
+                {
+                    baseRequest.setAuthentication(authentication);
+                    if (_identityService!=null)
+                        previousIdentity = _identityService.associate(null);
+                    handler.handle(pathInContext, baseRequest, request, response);
+                    if (authenticator!=null)
+                        authenticator.secureResponse(request, response, isAuthMandatory, null);
+                }
+            }
+            catch (ServerAuthException e)
+            {
+                // jaspi 3.8.3 send HTTP 500 internal server error, with message
+                // from AuthException
+                response.sendError(Response.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+            }
+            finally
+            {
+                if (_identityService!=null)
+                    _identityService.disassociate(previousIdentity);
+            }
+        }
+        else
+            handler.handle(pathInContext, baseRequest, request, response);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public static SecurityHandler getCurrentSecurityHandler()
+    {
+        Context context = ContextHandler.getCurrentContext();
+        if (context==null)
+            return null;
+        
+        SecurityHandler security = context.getContextHandler().getChildHandlerByClass(SecurityHandler.class);
+        return security;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void logout(Authentication.User user)
+    {
+        LOG.debug("logout {}",user);
+        LoginService login_service=getLoginService();
+        if (login_service!=null)
+        {
+            login_service.logout(user.getUserIdentity());
+        }
+        
+        IdentityService identity_service=getIdentityService();
+        if (identity_service!=null)
+        {
+            // TODO recover previous from threadlocal (or similar)
+            Object previous=null;
+            identity_service.disassociate(previous);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected abstract Object prepareConstraintInfo(String pathInContext, Request request);
+
+    /* ------------------------------------------------------------ */
+    protected abstract boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    protected abstract boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo);
+
+    /* ------------------------------------------------------------ */
+    protected abstract boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo,
+                                                           UserIdentity userIdentity) throws IOException;
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class NotChecked implements Principal
+    {
+        public String getName()
+        {
+            return null;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "NOT CHECKED";
+        }
+
+        public SecurityHandler getSecurityHandler()
+        {
+            return SecurityHandler.this;
+        }
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public static Principal __NO_USER = new Principal()
+    {
+        public String getName()
+        {
+            return null;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "No User";
+        }
+    };
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * Nobody user. The Nobody UserPrincipal is used to indicate a partial state
+     * of authentication. A request with a Nobody UserPrincipal will be allowed
+     * past all authentication constraints - but will not be considered an
+     * authenticated request. It can be used by Authenticators such as
+     * FormAuthenticator to allow access to logon and error pages within an
+     * authenticated URI tree.
+     */
+    public static Principal __NOBODY = new Principal()
+    {
+        public String getName()
+        {
+            return "Nobody";
+        }
+
+        @Override
+        public String toString()
+        {
+            return getName();
+        }
+    };
+
+}
diff --git a/src/java/org/eclipse/jetty/security/ServerAuthException.java b/src/java/org/eclipse/jetty/security/ServerAuthException.java
new file mode 100644
index 0000000..85f532f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/ServerAuthException.java
@@ -0,0 +1,47 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $
+ */
+public class ServerAuthException extends GeneralSecurityException
+{
+
+    public ServerAuthException()
+    {
+    }
+
+    public ServerAuthException(String s)
+    {
+        super(s);
+    }
+
+    public ServerAuthException(String s, Throwable throwable)
+    {
+        super(s, throwable);
+    }
+
+    public ServerAuthException(Throwable throwable)
+    {
+        super(throwable);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/SpnegoLoginService.java b/src/java/org/eclipse/jetty/security/SpnegoLoginService.java
new file mode 100644
index 0000000..2a2a5ad
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/SpnegoLoginService.java
@@ -0,0 +1,185 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.util.Properties;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.B64Code;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+public class SpnegoLoginService extends AbstractLifeCycle implements LoginService
+{
+    private static final Logger LOG = Log.getLogger(SpnegoLoginService.class);
+
+    protected IdentityService _identityService;// = new LdapIdentityService();
+    protected String _name;
+    private String _config;
+    
+    private String _targetName;
+
+    public SpnegoLoginService()
+    {
+        
+    }
+    
+    public SpnegoLoginService( String name )
+    {
+        setName(name);
+    }
+    
+    public SpnegoLoginService( String name, String config )
+    {
+        setName(name);
+        setConfig(config);
+    }
+    
+    public String getName()
+    {
+        return _name;
+    }
+
+    public void setName(String name)
+    {
+        if (isRunning())
+        {
+            throw new IllegalStateException("Running");
+        }
+        
+        _name = name;
+    }
+    
+    public String getConfig()
+    {
+        return _config;
+    }
+    
+    public void setConfig( String config )
+    {
+        if (isRunning())
+        {
+            throw new IllegalStateException("Running");
+        }
+        
+        _config = config;
+    }
+    
+    
+    
+    @Override
+    protected void doStart() throws Exception
+    {
+        Properties properties = new Properties();
+        Resource resource = Resource.newResource(_config);
+        properties.load(resource.getInputStream());
+        
+        _targetName = properties.getProperty("targetName");
+        
+        LOG.debug("Target Name {}", _targetName);
+        
+        super.doStart();
+    }
+
+    /**
+     * username will be null since the credentials will contain all the relevant info
+     */
+    public UserIdentity login(String username, Object credentials)
+    {
+        String encodedAuthToken = (String)credentials;
+        
+        byte[] authToken = B64Code.decode(encodedAuthToken);
+        
+        GSSManager manager = GSSManager.getInstance();
+        try
+        {
+            Oid krb5Oid = new Oid("1.3.6.1.5.5.2"); // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
+            GSSName gssName = manager.createName(_targetName,null);
+            GSSCredential serverCreds = manager.createCredential(gssName,GSSCredential.INDEFINITE_LIFETIME,krb5Oid,GSSCredential.ACCEPT_ONLY);
+            GSSContext gContext = manager.createContext(serverCreds);
+
+            if (gContext == null)
+            {
+                LOG.debug("SpnegoUserRealm: failed to establish GSSContext");
+            }
+            else
+            {
+                while (!gContext.isEstablished())
+                {
+                    authToken = gContext.acceptSecContext(authToken,0,authToken.length);
+                }
+                if (gContext.isEstablished())
+                {
+                    String clientName = gContext.getSrcName().toString();
+                    String role = clientName.substring(clientName.indexOf('@') + 1);
+                    
+                    LOG.debug("SpnegoUserRealm: established a security context");
+                    LOG.debug("Client Principal is: " + gContext.getSrcName());
+                    LOG.debug("Server Principal is: " + gContext.getTargName());
+                    LOG.debug("Client Default Role: " + role);
+
+                    SpnegoUserPrincipal user = new SpnegoUserPrincipal(clientName,authToken);
+
+                    Subject subject = new Subject();
+                    subject.getPrincipals().add(user);
+                    
+                    return _identityService.newUserIdentity(subject,user, new String[]{role});
+                }
+            }
+
+        }
+        catch (GSSException gsse)
+        {
+            LOG.warn(gsse);
+        }
+
+        return null;
+    }
+
+    public boolean validate(UserIdentity user)
+    {
+        return false;
+    }
+
+    public IdentityService getIdentityService()
+    {
+        return _identityService;
+    }
+
+    public void setIdentityService(IdentityService service)
+    {
+        _identityService = service;
+    }
+
+	public void logout(UserIdentity user) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
diff --git a/src/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/src/java/org/eclipse/jetty/security/SpnegoUserIdentity.java
new file mode 100644
index 0000000..fd93b1a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/SpnegoUserIdentity.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.server.UserIdentity;
+
+public class SpnegoUserIdentity implements UserIdentity
+{
+    private Subject _subject;
+    private Principal _principal;
+    private List<String> _roles;
+    
+    public SpnegoUserIdentity( Subject subject, Principal principal, List<String> roles )
+    {
+        _subject = subject;
+        _principal = principal;
+        _roles = roles;
+    }
+    
+    
+    public Subject getSubject()
+    {
+        return _subject;
+    }
+
+    public Principal getUserPrincipal()
+    {
+        return _principal;
+    }
+
+    public boolean isUserInRole(String role, Scope scope)
+    {
+        return _roles.contains(role);
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/src/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java
new file mode 100644
index 0000000..cedd370
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java
@@ -0,0 +1,65 @@
+//
+//  ========================================================================
+//  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.security;
+
+import java.security.Principal;
+
+import org.eclipse.jetty.util.security.B64Code;
+
+public class SpnegoUserPrincipal implements Principal
+{
+    private final String _name;
+    private byte[] _token;
+    private String _encodedToken;
+    
+    public SpnegoUserPrincipal( String name, String encodedToken )
+    {
+        _name = name;
+        _encodedToken = encodedToken;
+    }
+    
+    public SpnegoUserPrincipal( String name, byte[] token )
+    {
+        _name = name;
+        _token = token;
+    }
+    
+    public String getName()
+    {
+        return _name;
+    }
+
+    public byte[] getToken()
+    {
+        if ( _token == null )
+        {
+            _token = B64Code.decode(_encodedToken);
+        }
+        return _token;
+    }
+    
+    public String getEncodedToken()
+    {
+        if ( _encodedToken == null )
+        {
+            _encodedToken = new String(B64Code.encode(_token,true));
+        }
+        return _encodedToken;
+    }   
+}
diff --git a/src/java/org/eclipse/jetty/security/UserAuthentication.java b/src/java/org/eclipse/jetty/security/UserAuthentication.java
new file mode 100644
index 0000000..e84fa74
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/UserAuthentication.java
@@ -0,0 +1,67 @@
+//
+//  ========================================================================
+//  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.security;
+
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.UserIdentity.Scope;
+
+
+/**
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class UserAuthentication implements Authentication.User
+{
+    private final String _method;
+    private final UserIdentity _userIdentity;
+
+    public UserAuthentication(String method, UserIdentity userIdentity)
+    {
+        _method = method;
+        _userIdentity = userIdentity;
+    }
+    
+    public String getAuthMethod()
+    {
+        return _method;
+    }
+
+    public UserIdentity getUserIdentity()
+    {
+        return _userIdentity;
+    }
+
+    public boolean isUserInRole(Scope scope, String role)
+    {
+        return _userIdentity.isUserInRole(role, scope);
+    }
+    
+    @Override
+    public String toString()
+    {
+        return "{User,"+getAuthMethod()+","+_userIdentity+"}";
+    }
+
+    public void logout()
+    {
+        SecurityHandler security=SecurityHandler.getCurrentSecurityHandler();
+        if (security!=null)
+            security.logout(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/UserDataConstraint.java b/src/java/org/eclipse/jetty/security/UserDataConstraint.java
new file mode 100644
index 0000000..c288e1d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/UserDataConstraint.java
@@ -0,0 +1,40 @@
+//
+//  ========================================================================
+//  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.security;
+
+/**
+ * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $
+ */
+public enum UserDataConstraint
+{
+    None, Integral, Confidential;
+
+    public static UserDataConstraint get(int dataConstraint)
+    {
+        if (dataConstraint < -1 || dataConstraint > 2) throw new IllegalArgumentException("Expected -1, 0, 1, or 2, not: " + dataConstraint);
+        if (dataConstraint == -1) return None;
+        return values()[dataConstraint];
+    }
+
+    public UserDataConstraint combine(UserDataConstraint other)
+    {
+        if (this.compareTo(other) < 0) return this;
+        return other;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
new file mode 100644
index 0000000..f9a6c7c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java
@@ -0,0 +1,118 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.security.Constraint;
+
+/**
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class BasicAuthenticator extends LoginAuthenticator 
+{   
+    /* ------------------------------------------------------------ */
+    public BasicAuthenticator()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.Authenticator#getAuthMethod()
+     */
+    public String getAuthMethod()
+    {
+        return Constraint.__BASIC_AUTH;
+    }
+
+ 
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.Authenticator#validateRequest(javax.servlet.ServletRequest, javax.servlet.ServletResponse, boolean)
+     */
+    public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
+    {
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        String credentials = request.getHeader(HttpHeaders.AUTHORIZATION);
+
+        try
+        {
+            if (!mandatory)
+                return new DeferredAuthentication(this);
+
+            if (credentials != null)
+            {                 
+                int space=credentials.indexOf(' ');
+                if (space>0)
+                {
+                    String method=credentials.substring(0,space);
+                    if ("basic".equalsIgnoreCase(method))
+                    {
+                        credentials = credentials.substring(space+1);
+                        credentials = B64Code.decode(credentials,StringUtil.__ISO_8859_1);
+                        int i = credentials.indexOf(':');
+                        if (i>0)
+                        {
+                            String username = credentials.substring(0,i);
+                            String password = credentials.substring(i+1);
+
+                            UserIdentity user = login (username, password, request);
+                            if (user!=null)
+                            {
+                                return new UserAuthentication(getAuthMethod(),user);
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (DeferredAuthentication.isDeferred(response))
+                return Authentication.UNAUTHENTICATED;
+            
+            response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "basic realm=\"" + _loginService.getName() + '"');
+            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            return Authentication.SEND_CONTINUE;
+        }
+        catch (IOException e)
+        {
+            throw new ServerAuthException(e);
+        }
+    }
+
+    public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
new file mode 100644
index 0000000..7c24fcc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java
@@ -0,0 +1,368 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.cert.CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.security.CertificateUtils;
+import org.eclipse.jetty.util.security.CertificateValidator;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
+
+/**
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class ClientCertAuthenticator extends LoginAuthenticator
+{
+    /** String name of keystore password property. */
+    private static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
+
+    /** Truststore path */
+    private String _trustStorePath;
+    /** Truststore provider name */
+    private String _trustStoreProvider;
+    /** Truststore type */
+    private String _trustStoreType = "JKS";
+    /** Truststore password */
+    private transient Password _trustStorePassword;
+
+    /** Set to true if SSL certificate validation is required */
+    private boolean _validateCerts;
+    /** Path to file that contains Certificate Revocation List */
+    private String _crlPath;
+    /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
+    private int _maxCertPathLength = -1;
+    /** CRL Distribution Points (CRLDP) support */
+    private boolean _enableCRLDP = false;
+    /** On-Line Certificate Status Protocol (OCSP) support */
+    private boolean _enableOCSP = false;
+    /** Location of OCSP Responder */
+    private String _ocspResponderURL;
+    
+    public ClientCertAuthenticator()
+    {
+        super();
+    }
+
+    public String getAuthMethod()
+    {
+        return Constraint.__CERT_AUTH;
+    }
+    
+    
+
+    /**
+     * @return Authentication for request
+     * @throws ServerAuthException
+     */
+    public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
+    {
+        if (!mandatory)
+            return new DeferredAuthentication(this);
+
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
+
+        try
+        {
+            // Need certificates.
+            if (certs != null && certs.length > 0)
+            {
+                
+                if (_validateCerts)
+                {
+                    KeyStore trustStore = getKeyStore(null,
+                            _trustStorePath, _trustStoreType, _trustStoreProvider,
+                            _trustStorePassword == null ? null :_trustStorePassword.toString());
+                    Collection<? extends CRL> crls = loadCRL(_crlPath);
+                    CertificateValidator validator = new CertificateValidator(trustStore, crls);
+                    validator.validate(certs);
+                }
+                
+                for (X509Certificate cert: certs)
+                {
+                    if (cert==null)
+                        continue;
+
+                    Principal principal = cert.getSubjectDN();
+                    if (principal == null) principal = cert.getIssuerDN();
+                    final String username = principal == null ? "clientcert" : principal.getName();
+
+                    final char[] credential = B64Code.encode(cert.getSignature());
+
+                    UserIdentity user = login(username, credential, req);
+                    if (user!=null)
+                    {
+                        return new UserAuthentication(getAuthMethod(),user);
+                    }
+                }
+            }
+
+            if (!DeferredAuthentication.isDeferred(response))
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return Authentication.SEND_FAILURE;
+            }
+            
+            return Authentication.UNAUTHENTICATED;
+        }
+        catch (Exception e)
+        {
+            throw new ServerAuthException(e.getMessage());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads keystore using an input stream or a file path in the same
+     * order of precedence.
+     *
+     * Required for integrations to be able to override the mechanism
+     * used to load a keystore in order to provide their own implementation.
+     *
+     * @param storeStream keystore input stream
+     * @param storePath path of keystore file
+     * @param storeType keystore type
+     * @param storeProvider keystore provider
+     * @param storePassword keystore password
+     * @return created keystore
+     * @throws Exception
+     */
+    protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
+    {
+        return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads certificate revocation list (CRL) from a file.
+     *
+     * Required for integrations to be able to override the mechanism used to
+     * load CRL in order to provide their own implementation.
+     *
+     * @param crlPath path of certificate revocation list file
+     * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the
+     *         input stream.
+     * @throws Exception
+     */
+    protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
+    {
+        return CertificateUtils.loadCRL(crlPath);
+    }
+
+    public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if SSL certificate has to be validated
+     */
+    public boolean isValidateCerts()
+    {
+        return _validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param validateCerts
+     *            true if SSL certificates have to be validated
+     */
+    public void setValidateCerts(boolean validateCerts)
+    {
+        _validateCerts = validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file name or URL of the trust store location
+     */
+    public String getTrustStore()
+    {
+        return _trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStorePath
+     *            The file name or URL of the trust store location
+     */
+    public void setTrustStore(String trustStorePath)
+    {
+        _trustStorePath = trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The provider of the trust store
+     */
+    public String getTrustStoreProvider()
+    {
+        return _trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreProvider
+     *            The provider of the trust store
+     */
+    public void setTrustStoreProvider(String trustStoreProvider)
+    {
+        _trustStoreProvider = trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the trust store (default "JKS")
+     */
+    public String getTrustStoreType()
+    {
+        return _trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreType
+     *            The type of the trust store (default "JKS")
+     */
+    public void setTrustStoreType(String trustStoreType)
+    {
+        _trustStoreType = trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password
+     *            The password for the trust store
+     */
+    public void setTrustStorePassword(String password)
+    {
+        _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the crlPath.
+     * @return the crlPath
+     */
+    public String getCrlPath()
+    {
+        return _crlPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the crlPath.
+     * @param crlPath the crlPath to set
+     */
+    public void setCrlPath(String crlPath)
+    {
+        _crlPath = crlPath;
+    }
+
+    /**
+     * @return Maximum number of intermediate certificates in
+     * the certification path (-1 for unlimited)
+     */
+    public int getMaxCertPathLength()
+    {
+        return _maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxCertPathLength
+     *            maximum number of intermediate certificates in
+     *            the certification path (-1 for unlimited)
+     */
+    public void setMaxCertPathLength(int maxCertPathLength)
+    {
+        _maxCertPathLength = maxCertPathLength;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return true if CRL Distribution Points support is enabled
+     */
+    public boolean isEnableCRLDP()
+    {
+        return _enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables CRL Distribution Points Support
+     * @param enableCRLDP true - turn on, false - turns off
+     */
+    public void setEnableCRLDP(boolean enableCRLDP)
+    {
+        _enableCRLDP = enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return true if On-Line Certificate Status Protocol support is enabled
+     */
+    public boolean isEnableOCSP()
+    {
+        return _enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables On-Line Certificate Status Protocol support
+     * @param enableOCSP true - turn on, false - turn off
+     */
+    public void setEnableOCSP(boolean enableOCSP)
+    {
+        _enableOCSP = enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Location of the OCSP Responder
+     */
+    public String getOcspResponderURL()
+    {
+        return _ocspResponderURL;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the location of the OCSP Responder.
+     * @param ocspResponderURL location of the OCSP Responder
+     */
+    public void setOcspResponderURL(String ocspResponderURL)
+    {
+        _ocspResponderURL = ocspResponderURL;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/src/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java
new file mode 100644
index 0000000..854c62d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java
@@ -0,0 +1,335 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.security.Authenticator;
+import org.eclipse.jetty.security.IdentityService;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class DeferredAuthentication implements Authentication.Deferred
+{
+    private static final Logger LOG = Log.getLogger(DeferredAuthentication.class);
+    protected final LoginAuthenticator _authenticator;
+    private Object _previousAssociation;
+
+    /* ------------------------------------------------------------ */
+    public DeferredAuthentication(LoginAuthenticator authenticator)
+    {
+        if (authenticator == null)
+            throw new NullPointerException("No Authenticator");
+        this._authenticator = authenticator;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(ServletRequest)
+     */
+    public Authentication authenticate(ServletRequest request)
+    {
+        try
+        {
+            Authentication authentication = _authenticator.validateRequest(request,__deferredResponse,true);
+            
+            if (authentication!=null && (authentication instanceof Authentication.User) && !(authentication instanceof Authentication.ResponseSent))
+            {
+                LoginService login_service= _authenticator.getLoginService();
+                IdentityService identity_service=login_service.getIdentityService();
+                
+                if (identity_service!=null)
+                    _previousAssociation=identity_service.associate(((Authentication.User)authentication).getUserIdentity());
+                
+                return authentication;
+            }
+        }
+        catch (ServerAuthException e)
+        {
+            LOG.debug(e);
+        }
+
+        return this;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    public Authentication authenticate(ServletRequest request, ServletResponse response)
+    {
+        try
+        {
+            LoginService login_service= _authenticator.getLoginService();
+            IdentityService identity_service=login_service.getIdentityService();
+            
+            Authentication authentication = _authenticator.validateRequest(request,response,true);
+            if (authentication instanceof Authentication.User && identity_service!=null)
+                _previousAssociation=identity_service.associate(((Authentication.User)authentication).getUserIdentity());
+            return authentication;
+        }
+        catch (ServerAuthException e)
+        {
+            LOG.debug(e);
+        }
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.Authentication.Deferred#login(java.lang.String, java.lang.String)
+     */
+    public Authentication login(String username, Object password, ServletRequest request)
+    {
+        UserIdentity identity = _authenticator.login(username, password, request);
+        if (identity != null)
+        {
+            IdentityService identity_service = _authenticator.getLoginService().getIdentityService();
+            UserAuthentication authentication = new UserAuthentication("API",identity);
+            if (identity_service != null)
+                _previousAssociation=identity_service.associate(identity);
+            return authentication;
+        }
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object getPreviousAssociation()
+    {
+        return _previousAssociation;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param response
+     * @return true if this response is from a deferred call to {@link #authenticate(ServletRequest)}
+     */
+    public static boolean isDeferred(HttpServletResponse response)
+    {
+        return response==__deferredResponse;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    final static HttpServletResponse __deferredResponse = new HttpServletResponse()
+    {
+        public void addCookie(Cookie cookie)
+        {
+        }
+
+        public void addDateHeader(String name, long date)
+        {
+        }
+
+        public void addHeader(String name, String value)
+        {
+        }
+
+        public void addIntHeader(String name, int value)
+        {
+        }
+
+        public boolean containsHeader(String name)
+        {
+            return false;
+        }
+
+        public String encodeRedirectURL(String url)
+        {
+            return null;
+        }
+
+        public String encodeRedirectUrl(String url)
+        {
+            return null;
+        }
+
+        public String encodeURL(String url)
+        {
+            return null;
+        }
+
+        public String encodeUrl(String url)
+        {
+            return null;
+        }
+
+        public void sendError(int sc) throws IOException
+        {
+        }
+
+        public void sendError(int sc, String msg) throws IOException
+        {
+        }
+
+        public void sendRedirect(String location) throws IOException
+        {
+        }
+
+        public void setDateHeader(String name, long date)
+        {
+        }
+
+        public void setHeader(String name, String value)
+        {
+        }
+
+        public void setIntHeader(String name, int value)
+        {
+        }
+
+        public void setStatus(int sc)
+        {
+        }
+
+        public void setStatus(int sc, String sm)
+        {
+        }
+
+        public void flushBuffer() throws IOException
+        {
+        }
+
+        public int getBufferSize()
+        {
+            return 1024;
+        }
+
+        public String getCharacterEncoding()
+        {
+            return null;
+        }
+
+        public String getContentType()
+        {
+            return null;
+        }
+
+        public Locale getLocale()
+        {
+            return null;
+        }
+
+        public ServletOutputStream getOutputStream() throws IOException
+        {
+            return __nullOut;
+        }
+
+        public PrintWriter getWriter() throws IOException
+        {
+            return IO.getNullPrintWriter();
+        }
+
+        public boolean isCommitted()
+        {
+            return true;
+        }
+
+        public void reset()
+        {
+        }
+
+        public void resetBuffer()
+        {
+        }
+
+        public void setBufferSize(int size)
+        {
+        }
+
+        public void setCharacterEncoding(String charset)
+        {
+        }
+
+        public void setContentLength(int len)
+        {
+        }
+
+        public void setContentType(String type)
+        {
+        }
+
+        public void setLocale(Locale loc)
+        {
+        }
+
+	public Collection<String> getHeaderNames()
+	{
+	    return Collections.emptyList();
+	}
+
+	@Override
+	public String getHeader(String arg0)
+	{
+	    return null;
+	}
+
+	@Override
+	public Collection<String> getHeaders(String arg0)
+	{
+            return Collections.emptyList();
+	}
+
+	@Override
+	public int getStatus()
+	{
+	    return 0;
+	}
+
+    };
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static ServletOutputStream __nullOut = new ServletOutputStream()
+    {
+        public void write(int b) throws IOException
+        {
+        }
+
+        public void print(String s) throws IOException
+        {
+        }
+
+        public void println(String s) throws IOException
+        {
+        }
+    };
+
+    
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
new file mode 100644
index 0000000..4cd279e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java
@@ -0,0 +1,412 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.BitSet;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Credential;
+
+/**
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ * 
+ * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} 
+ * using the name "maxNonceAge"
+ */
+public class DigestAuthenticator extends LoginAuthenticator
+{
+    private static final Logger LOG = Log.getLogger(DigestAuthenticator.class);
+    SecureRandom _random = new SecureRandom();
+    private long _maxNonceAgeMs = 60*1000;
+    private int _maxNC=1024;
+    private ConcurrentMap<String, Nonce> _nonceMap = new ConcurrentHashMap<String, Nonce>();
+    private Queue<Nonce> _nonceQueue = new ConcurrentLinkedQueue<Nonce>();
+    private static class Nonce
+    {
+        final String _nonce;
+        final long _ts;
+        final BitSet _seen; 
+
+        public Nonce(String nonce, long ts, int size)
+        {
+            _nonce=nonce;
+            _ts=ts;
+            _seen = new BitSet(size);
+        }
+
+        public boolean seen(int count)
+        {
+            synchronized (this)
+            {
+                if (count>=_seen.size())
+                    return true;
+                boolean s=_seen.get(count);
+                _seen.set(count);
+                return s;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public DigestAuthenticator()
+    {
+        super();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.authentication.LoginAuthenticator#setConfiguration(org.eclipse.jetty.security.Authenticator.AuthConfiguration)
+     */
+    @Override
+    public void setConfiguration(AuthConfiguration configuration)
+    {
+        super.setConfiguration(configuration);
+        
+        String mna=configuration.getInitParameter("maxNonceAge");
+        if (mna!=null)
+        {
+            _maxNonceAgeMs=Long.valueOf(mna);
+        }
+    }
+
+   
+    /* ------------------------------------------------------------ */
+    public int getMaxNonceCount()
+    {
+        return _maxNC;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxNonceCount(int maxNC)
+    {
+        _maxNC = maxNC;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setMaxNonceAge(long maxNonceAgeInMillis)
+    {
+        _maxNonceAgeMs = maxNonceAgeInMillis;
+    }
+
+    /* ------------------------------------------------------------ */
+    public long getMaxNonceAge()
+    {
+        return _maxNonceAgeMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getAuthMethod()
+    {
+        return Constraint.__DIGEST_AUTH;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+    
+
+
+    /* ------------------------------------------------------------ */
+    public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
+    {
+        if (!mandatory)
+            return new DeferredAuthentication(this);
+
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        String credentials = request.getHeader(HttpHeaders.AUTHORIZATION);
+
+        try
+        {
+            boolean stale = false;
+            if (credentials != null)
+            {
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("Credentials: " + credentials);
+                QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(credentials, "=, ", true, false);
+                final Digest digest = new Digest(request.getMethod());
+                String last = null;
+                String name = null;
+
+                while (tokenizer.hasMoreTokens())
+                {
+                    String tok = tokenizer.nextToken();
+                    char c = (tok.length() == 1) ? tok.charAt(0) : '\0';
+
+                    switch (c)
+                    {
+                        case '=':
+                            name = last;
+                            last = tok;
+                            break;
+                        case ',':
+                            name = null;
+                            break;
+                        case ' ':
+                            break;
+
+                        default:
+                            last = tok;
+                            if (name != null)
+                            {
+                                if ("username".equalsIgnoreCase(name))
+                                    digest.username = tok;
+                                else if ("realm".equalsIgnoreCase(name))
+                                    digest.realm = tok;
+                                else if ("nonce".equalsIgnoreCase(name))
+                                    digest.nonce = tok;
+                                else if ("nc".equalsIgnoreCase(name))
+                                    digest.nc = tok;
+                                else if ("cnonce".equalsIgnoreCase(name))
+                                    digest.cnonce = tok;
+                                else if ("qop".equalsIgnoreCase(name))
+                                    digest.qop = tok;
+                                else if ("uri".equalsIgnoreCase(name))
+                                    digest.uri = tok;
+                                else if ("response".equalsIgnoreCase(name)) 
+                                    digest.response = tok;
+                                name=null;
+                            }
+                    }
+                }
+
+                int n = checkNonce(digest,(Request)request);
+
+                if (n > 0)
+                {
+                    //UserIdentity user = _loginService.login(digest.username,digest);
+                    UserIdentity user = login(digest.username, digest, req);
+                    if (user!=null)
+                    {
+                        return new UserAuthentication(getAuthMethod(),user);
+                    }
+                }
+                else if (n == 0) 
+                    stale = true;
+
+            }
+
+            if (!DeferredAuthentication.isDeferred(response))
+            {
+                String domain = request.getContextPath();
+                if (domain == null) 
+                    domain = "/";
+                response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"" + _loginService.getName()
+                        + "\", domain=\""
+                        + domain
+                        + "\", nonce=\""
+                        + newNonce((Request)request)
+                        + "\", algorithm=MD5, qop=\"auth\","
+                        + " stale=" + stale);
+                response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+
+                return Authentication.SEND_CONTINUE;
+            }
+
+            return Authentication.UNAUTHENTICATED;
+        }
+        catch (IOException e)
+        {
+            throw new ServerAuthException(e);
+        }
+
+    }
+
+    /* ------------------------------------------------------------ */
+    public String newNonce(Request request)
+    {
+        Nonce nonce;
+        
+        do
+        {
+            byte[] nounce = new byte[24];
+            _random.nextBytes(nounce);
+
+            nonce = new Nonce(new String(B64Code.encode(nounce)),request.getTimeStamp(),_maxNC);
+        }
+        while (_nonceMap.putIfAbsent(nonce._nonce,nonce)!=null);
+        _nonceQueue.add(nonce);
+               
+        return nonce._nonce;
+    }
+
+    /**
+     * @param nstring nonce to check
+     * @param request
+     * @return -1 for a bad nonce, 0 for a stale none, 1 for a good nonce
+     */
+    /* ------------------------------------------------------------ */
+    private int checkNonce(Digest digest, Request request)
+    {
+        // firstly let's expire old nonces
+        long expired = request.getTimeStamp()-_maxNonceAgeMs;
+        Nonce nonce=_nonceQueue.peek();
+        while (nonce!=null && nonce._ts<expired)
+        {
+            _nonceQueue.remove(nonce);
+            _nonceMap.remove(nonce._nonce);
+            nonce=_nonceQueue.peek();
+        }
+        
+        // Now check the requested nonce
+        try
+        {
+            nonce = _nonceMap.get(digest.nonce);
+            if (nonce==null)
+                return 0;
+         
+            long count = Long.parseLong(digest.nc,16);
+            if (count>=_maxNC)
+                return 0;
+            if (nonce.seen((int)count))
+                return -1;
+            return 1;
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class Digest extends Credential
+    {
+        private static final long serialVersionUID = -2484639019549527724L;
+        final String method;
+        String username = "";
+        String realm = "";
+        String nonce = "";
+        String nc = "";
+        String cnonce = "";
+        String qop = "";
+        String uri = "";
+        String response = "";
+
+        /* ------------------------------------------------------------ */
+        Digest(String m)
+        {
+            method = m;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public boolean check(Object credentials)
+        {
+            if (credentials instanceof char[])
+                credentials=new String((char[])credentials);
+            String password = (credentials instanceof String) ? (String) credentials : credentials.toString();
+
+            try
+            {
+                MessageDigest md = MessageDigest.getInstance("MD5");
+                byte[] ha1;
+                if (credentials instanceof Credential.MD5)
+                {
+                    // Credentials are already a MD5 digest - assume it's in
+                    // form user:realm:password (we have no way to know since
+                    // it's a digest, alright?)
+                    ha1 = ((Credential.MD5) credentials).getDigest();
+                }
+                else
+                {
+                    // calc A1 digest
+                    md.update(username.getBytes(StringUtil.__ISO_8859_1));
+                    md.update((byte) ':');
+                    md.update(realm.getBytes(StringUtil.__ISO_8859_1));
+                    md.update((byte) ':');
+                    md.update(password.getBytes(StringUtil.__ISO_8859_1));
+                    ha1 = md.digest();
+                }
+                // calc A2 digest
+                md.reset();
+                md.update(method.getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(uri.getBytes(StringUtil.__ISO_8859_1));
+                byte[] ha2 = md.digest();
+
+                // calc digest
+                // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":"
+                // nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" H(A2) )
+                // <">
+                // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2)
+                // ) > <">
+
+                md.update(TypeUtil.toString(ha1, 16).getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(nonce.getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(nc.getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(cnonce.getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(qop.getBytes(StringUtil.__ISO_8859_1));
+                md.update((byte) ':');
+                md.update(TypeUtil.toString(ha2, 16).getBytes(StringUtil.__ISO_8859_1));
+                byte[] digest = md.digest();
+
+                // check digest
+                return (TypeUtil.toString(digest, 16).equalsIgnoreCase(response));
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+            }
+
+            return false;
+        }
+
+        @Override
+        public String toString()
+        {
+            return username + "," + response;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
new file mode 100644
index 0000000..abc74d0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java
@@ -0,0 +1,502 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Constraint;
+
+/**
+ * FORM Authenticator.
+ * 
+ * <p>This authenticator implements form authentication will use dispatchers to
+ * the login page if the {@link #__FORM_DISPATCH} init parameter is set to true.
+ * Otherwise it will redirect.</p>
+ * 
+ * <p>The form authenticator redirects unauthenticated requests to a log page
+ * which should use a form to gather username/password from the user and send them
+ * to the /j_security_check URI within the context.  FormAuthentication uses 
+ * {@link SessionAuthentication} to wrap Authentication results so that they
+ * are  associated with the session.</p>
+ *  
+ * 
+ */
+public class FormAuthenticator extends LoginAuthenticator
+{
+    private static final Logger LOG = Log.getLogger(FormAuthenticator.class);
+
+    public final static String __FORM_LOGIN_PAGE="org.eclipse.jetty.security.form_login_page";
+    public final static String __FORM_ERROR_PAGE="org.eclipse.jetty.security.form_error_page";
+    public final static String __FORM_DISPATCH="org.eclipse.jetty.security.dispatch";
+    public final static String __J_URI = "org.eclipse.jetty.security.form_URI";
+    public final static String __J_POST = "org.eclipse.jetty.security.form_POST";
+    public final static String __J_SECURITY_CHECK = "/j_security_check";
+    public final static String __J_USERNAME = "j_username";
+    public final static String __J_PASSWORD = "j_password";
+
+    private String _formErrorPage;
+    private String _formErrorPath;
+    private String _formLoginPage;
+    private String _formLoginPath;
+    private boolean _dispatch;
+    private boolean _alwaysSaveUri;
+
+    public FormAuthenticator()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public FormAuthenticator(String login,String error,boolean dispatch)
+    {
+        this();
+        if (login!=null)
+            setLoginPage(login);
+        if (error!=null)
+            setErrorPage(error);
+        _dispatch=dispatch;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * If true, uris that cause a redirect to a login page will always
+     * be remembered. If false, only the first uri that leads to a login
+     * page redirect is remembered.
+     * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=379909
+     * @param alwaysSave
+     */
+    public void setAlwaysSaveUri (boolean alwaysSave)
+    {
+        _alwaysSaveUri = alwaysSave;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public boolean getAlwaysSaveUri ()
+    {
+        return _alwaysSaveUri;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.security.authentication.LoginAuthenticator#setConfiguration(org.eclipse.jetty.security.Authenticator.AuthConfiguration)
+     */
+    @Override
+    public void setConfiguration(AuthConfiguration configuration)
+    {
+        super.setConfiguration(configuration);
+        String login=configuration.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE);
+        if (login!=null)
+            setLoginPage(login);
+        String error=configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE);
+        if (error!=null)
+            setErrorPage(error);
+        String dispatch=configuration.getInitParameter(FormAuthenticator.__FORM_DISPATCH);
+        _dispatch = dispatch==null?_dispatch:Boolean.valueOf(dispatch);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getAuthMethod()
+    {
+        return Constraint.__FORM_AUTH;
+    }
+
+    /* ------------------------------------------------------------ */
+    private void setLoginPage(String path)
+    {
+        if (!path.startsWith("/"))
+        {
+            LOG.warn("form-login-page must start with /");
+            path = "/" + path;
+        }
+        _formLoginPage = path;
+        _formLoginPath = path;
+        if (_formLoginPath.indexOf('?') > 0) 
+            _formLoginPath = _formLoginPath.substring(0, _formLoginPath.indexOf('?'));
+    }
+
+    /* ------------------------------------------------------------ */
+    private void setErrorPage(String path)
+    {
+        if (path == null || path.trim().length() == 0)
+        {
+            _formErrorPath = null;
+            _formErrorPage = null;
+        }
+        else
+        {
+            if (!path.startsWith("/"))
+            {
+                LOG.warn("form-error-page must start with /");
+                path = "/" + path;
+            }
+            _formErrorPage = path;
+            _formErrorPath = path;
+
+            if (_formErrorPath.indexOf('?') > 0) 
+                _formErrorPath = _formErrorPath.substring(0, _formErrorPath.indexOf('?'));
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public UserIdentity login(String username, Object password, ServletRequest request)
+    {
+        
+        UserIdentity user = super.login(username,password,request);
+        if (user!=null)
+        {
+            HttpSession session = ((HttpServletRequest)request).getSession(true);
+            Authentication cached=new SessionAuthentication(getAuthMethod(),user,password);
+            session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, cached);
+        }
+        return user;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
+    {   
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        String uri = request.getRequestURI();
+        if (uri==null)
+            uri=URIUtil.SLASH;
+
+        mandatory|=isJSecurityCheck(uri);
+        if (!mandatory)
+            return new DeferredAuthentication(this);
+
+        if (isLoginOrErrorPage(URIUtil.addPaths(request.getServletPath(),request.getPathInfo())) &&!DeferredAuthentication.isDeferred(response))
+            return new DeferredAuthentication(this);
+
+        HttpSession session = request.getSession(true);
+            
+        try
+        {
+            // Handle a request for authentication.
+            if (isJSecurityCheck(uri))
+            {
+                final String username = request.getParameter(__J_USERNAME);
+                final String password = request.getParameter(__J_PASSWORD);
+                
+                UserIdentity user = login(username, password, request);
+                session = request.getSession(true);
+                if (user!=null)
+                {                    
+                    // Redirect to original request
+                    String nuri;
+                    synchronized(session)
+                    {
+                        nuri = (String) session.getAttribute(__J_URI);
+
+                        if (nuri == null || nuri.length() == 0)
+                        {
+                            nuri = request.getContextPath();
+                            if (nuri.length() == 0) 
+                                nuri = URIUtil.SLASH;
+                        }
+                    }
+                    response.setContentLength(0);   
+                    response.sendRedirect(response.encodeRedirectURL(nuri));
+                    
+                    return new FormAuthentication(getAuthMethod(),user);
+                }
+                
+                // not authenticated
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("Form authentication FAILED for " + StringUtil.printable(username));
+                if (_formErrorPage == null)
+                {
+                    if (response != null) 
+                        response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                }
+                else if (_dispatch)
+                {
+                    RequestDispatcher dispatcher = request.getRequestDispatcher(_formErrorPage);
+                    response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
+                    response.setDateHeader(HttpHeaders.EXPIRES,1);
+                    dispatcher.forward(new FormRequest(request), new FormResponse(response));
+                }
+                else
+                {
+                    response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formErrorPage)));
+                }
+                
+                return Authentication.SEND_FAILURE;
+            }
+            
+            // Look for cached authentication
+            Authentication authentication = (Authentication) session.getAttribute(SessionAuthentication.__J_AUTHENTICATED);
+            if (authentication != null) 
+            {
+                // Has authentication been revoked?
+                if (authentication instanceof Authentication.User && 
+                    _loginService!=null &&
+                    !_loginService.validate(((Authentication.User)authentication).getUserIdentity()))
+                {
+                
+                    session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED);
+                }
+                else
+                {
+                    String j_uri=(String)session.getAttribute(__J_URI);
+                    if (j_uri!=null)
+                    {
+                        MultiMap<String> j_post = (MultiMap<String>)session.getAttribute(__J_POST);
+                        if (j_post!=null)
+                        {
+                            StringBuffer buf = request.getRequestURL();
+                            if (request.getQueryString() != null)
+                                buf.append("?").append(request.getQueryString());
+
+                            if (j_uri.equals(buf.toString()))
+                            {
+                                // This is a retry of an original POST request
+                                // so restore method and parameters
+
+                                session.removeAttribute(__J_POST);                        
+                                Request base_request = (req instanceof Request)?(Request)req:AbstractHttpConnection.getCurrentConnection().getRequest();
+                                base_request.setMethod(HttpMethods.POST);
+                                base_request.setParameters(j_post);
+                            }
+                        }
+                        else
+                            session.removeAttribute(__J_URI);
+                            
+                    }
+                    return authentication;
+                }
+            }
+
+            // if we can't send challenge
+            if (DeferredAuthentication.isDeferred(response))
+            {
+                LOG.debug("auth deferred {}",session.getId());
+                return Authentication.UNAUTHENTICATED;
+            }
+
+            // remember the current URI
+            synchronized (session)
+            {
+                // But only if it is not set already, or we save every uri that leads to a login form redirect
+                if (session.getAttribute(__J_URI)==null || _alwaysSaveUri)
+                {  
+                    StringBuffer buf = request.getRequestURL();
+                    if (request.getQueryString() != null)
+                        buf.append("?").append(request.getQueryString());
+                    session.setAttribute(__J_URI, buf.toString());
+                    
+                    if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(req.getContentType()) && HttpMethods.POST.equals(request.getMethod()))
+                    {
+                        Request base_request = (req instanceof Request)?(Request)req:AbstractHttpConnection.getCurrentConnection().getRequest();
+                        base_request.extractParameters();                        
+                        session.setAttribute(__J_POST, new MultiMap<String>(base_request.getParameters()));
+                    }
+                }
+            }
+            
+            // send the the challenge
+            if (_dispatch)
+            {
+                RequestDispatcher dispatcher = request.getRequestDispatcher(_formLoginPage);
+                response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
+                response.setDateHeader(HttpHeaders.EXPIRES,1);
+                dispatcher.forward(new FormRequest(request), new FormResponse(response));
+            }
+            else
+            {
+                response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formLoginPage)));
+            }
+            return Authentication.SEND_CONTINUE;
+            
+         
+        }
+        catch (IOException e)
+        {
+            throw new ServerAuthException(e);
+        }
+        catch (ServletException e)
+        {
+            throw new ServerAuthException(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isJSecurityCheck(String uri)
+    {
+        int jsc = uri.indexOf(__J_SECURITY_CHECK);
+        
+        if (jsc<0)
+            return false;
+        int e=jsc+__J_SECURITY_CHECK.length();
+        if (e==uri.length())
+            return true;
+        char c = uri.charAt(e);
+        return c==';'||c=='#'||c=='/'||c=='?';
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isLoginOrErrorPage(String pathInContext)
+    {
+        return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected static class FormRequest extends HttpServletRequestWrapper
+    {
+        public FormRequest(HttpServletRequest request)
+        {
+            super(request);
+        }
+
+        @Override
+        public long getDateHeader(String name)
+        {
+            if (name.toLowerCase(Locale.ENGLISH).startsWith("if-"))
+                return -1;
+            return super.getDateHeader(name);
+        }
+        
+        @Override
+        public String getHeader(String name)
+        {
+            if (name.toLowerCase(Locale.ENGLISH).startsWith("if-"))
+                return null;
+            return super.getHeader(name);
+        }
+
+        @Override
+        public Enumeration getHeaderNames()
+        {
+            return Collections.enumeration(Collections.list(super.getHeaderNames()));
+        }
+
+        @Override
+        public Enumeration getHeaders(String name)
+        {
+            if (name.toLowerCase(Locale.ENGLISH).startsWith("if-"))
+                return Collections.enumeration(Collections.EMPTY_LIST);
+            return super.getHeaders(name);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected static class FormResponse extends HttpServletResponseWrapper
+    {
+        public FormResponse(HttpServletResponse response)
+        {
+            super(response);
+        }
+
+        @Override
+        public void addDateHeader(String name, long date)
+        {
+            if (notIgnored(name))
+                super.addDateHeader(name,date);
+        }
+
+        @Override
+        public void addHeader(String name, String value)
+        {
+            if (notIgnored(name))
+                super.addHeader(name,value);
+        }
+
+        @Override
+        public void setDateHeader(String name, long date)
+        {
+            if (notIgnored(name))
+                super.setDateHeader(name,date);
+        }
+        
+        @Override
+        public void setHeader(String name, String value)
+        {
+            if (notIgnored(name))
+                super.setHeader(name,value);
+        }
+        
+        private boolean notIgnored(String name)
+        {
+            if (HttpHeaders.CACHE_CONTROL.equalsIgnoreCase(name) ||
+                HttpHeaders.PRAGMA.equalsIgnoreCase(name) ||
+                HttpHeaders.ETAG.equalsIgnoreCase(name) ||
+                HttpHeaders.EXPIRES.equalsIgnoreCase(name) ||
+                HttpHeaders.LAST_MODIFIED.equalsIgnoreCase(name) ||
+                HttpHeaders.AGE.equalsIgnoreCase(name))
+                return false;
+            return true;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** This Authentication represents a just completed Form authentication.
+     * Subsequent requests from the same user are authenticated by the presents 
+     * of a {@link SessionAuthentication} instance in their session.
+     */
+    public static class FormAuthentication extends UserAuthentication implements Authentication.ResponseSent
+    {
+        public FormAuthentication(String method, UserIdentity userIdentity)
+        {
+            super(method,userIdentity);
+        }
+        
+        @Override
+        public String toString()
+        {
+            return "Form"+super.toString();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
new file mode 100644
index 0000000..442bb6a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
@@ -0,0 +1,98 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.security.Authenticator;
+import org.eclipse.jetty.security.IdentityService;
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.session.AbstractSessionManager;
+
+public abstract class LoginAuthenticator implements Authenticator
+{
+    protected LoginService _loginService;
+    protected IdentityService _identityService;
+    private boolean _renewSession;
+
+    protected LoginAuthenticator()
+    {
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public UserIdentity login(String username, Object password, ServletRequest request)
+    {
+        UserIdentity user = _loginService.login(username,password);
+        if (user!=null)
+        {
+            renewSession((HttpServletRequest)request, null);
+            return user;
+        }
+        return null;
+    }
+
+
+    public void setConfiguration(AuthConfiguration configuration)
+    {
+        _loginService=configuration.getLoginService();
+        if (_loginService==null)
+            throw new IllegalStateException("No LoginService for "+this+" in "+configuration);
+        _identityService=configuration.getIdentityService();
+        if (_identityService==null)
+            throw new IllegalStateException("No IdentityService for "+this+" in "+configuration);
+        _renewSession=configuration.isSessionRenewedOnAuthentication();
+    }
+    
+    public LoginService getLoginService()
+    {
+        return _loginService;
+    }
+    
+    /** Change the session id.
+     * The session is changed to a new instance with a new ID if and only if:<ul>
+     * <li>A session exists.
+     * <li>The {@link AuthConfiguration#isSessionRenewedOnAuthentication()} returns true.
+     * <li>The session ID has been given to unauthenticated responses
+     * </ul>
+     * @param request
+     * @param response
+     * @return The new session.
+     */
+    protected HttpSession renewSession(HttpServletRequest request, HttpServletResponse response)
+    {
+        HttpSession httpSession = request.getSession(false);
+       
+        //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users
+        //(indicated by SESSION_SECURED not being set on the session) then we should change id
+        if (_renewSession && httpSession!=null && httpSession.getAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED)!=Boolean.TRUE)
+        {
+            synchronized (this)
+            {
+                httpSession = AbstractSessionManager.renewSession(request, httpSession,true);
+            }
+        }
+        return httpSession;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/src/java/org/eclipse/jetty/security/authentication/LoginCallback.java
new file mode 100644
index 0000000..0d56e01
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/LoginCallback.java
@@ -0,0 +1,55 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+
+/**
+ * This is similar to the jaspi PasswordValidationCallback but includes user
+ * principal and group info as well.
+ * 
+ * @version $Rev: 4792 $ $Date: 2009-03-18 22:55:52 +0100 (Wed, 18 Mar 2009) $
+ */
+public interface LoginCallback
+{
+    public Subject getSubject();
+
+    public String getUserName();
+
+    public Object getCredential();
+ 
+    public boolean isSuccess();
+
+    public void setSuccess(boolean success);
+
+    public Principal getUserPrincipal();
+
+    public void setUserPrincipal(Principal userPrincipal);
+
+    public String[] getRoles();
+    
+    public void setRoles(String[] roles);
+  
+    public void clearPassword();
+   
+
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/src/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java
new file mode 100644
index 0000000..c0cd219
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java
@@ -0,0 +1,109 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.jetty.security.IdentityService;
+
+/**
+ * This is similar to the jaspi PasswordValidationCallback but includes user
+ * principal and group info as well.
+ * 
+ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
+ */
+public class LoginCallbackImpl implements LoginCallback
+{
+    // initial data
+    private final Subject subject;
+
+    private final String userName;
+
+    private Object credential;
+
+    private boolean success;
+
+    private Principal userPrincipal;
+
+    private String[] roles = IdentityService.NO_ROLES;
+
+    //TODO could use Credential instance instead of Object if Basic/Form create a Password object
+    public LoginCallbackImpl (Subject subject, String userName, Object credential)
+    {
+        this.subject = subject;
+        this.userName = userName;
+        this.credential = credential;
+    }
+
+    public Subject getSubject()
+    {
+        return subject;
+    }
+
+    public String getUserName()
+    {
+        return userName;
+    }
+
+    public Object getCredential()
+    {
+        return credential;
+    }
+
+    public boolean isSuccess()
+    {
+        return success;
+    }
+
+    public void setSuccess(boolean success)
+    {
+        this.success = success;
+    }
+
+    public Principal getUserPrincipal()
+    {
+        return userPrincipal;
+    }
+
+    public void setUserPrincipal(Principal userPrincipal)
+    {
+        this.userPrincipal = userPrincipal;
+    }
+
+    public String[] getRoles()
+    {
+        return roles;
+    }
+
+    public void setRoles(String[] groups)
+    {
+        this.roles = groups;
+    }
+
+    public void clearPassword()
+    {
+        if (credential != null)
+        {
+            credential = null;
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/src/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
new file mode 100644
index 0000000..0f2db6d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
@@ -0,0 +1,146 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
+
+import org.eclipse.jetty.security.LoginService;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.UserIdentity.Scope;
+import org.eclipse.jetty.server.session.AbstractSessionManager;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class SessionAuthentication implements Authentication.User, Serializable, HttpSessionActivationListener, HttpSessionBindingListener
+{
+    private static final Logger LOG = Log.getLogger(SessionAuthentication.class);
+
+    private static final long serialVersionUID = -4643200685888258706L;
+
+    
+
+    public final static String __J_AUTHENTICATED="org.eclipse.jetty.security.UserIdentity";
+
+    private final String _method;
+    private final String _name;
+    private final Object _credentials;
+    
+    private transient UserIdentity _userIdentity;
+    private transient HttpSession _session;
+    
+    public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials)
+    {
+        _method = method;
+        _userIdentity = userIdentity;
+        _name=_userIdentity.getUserPrincipal().getName();
+        _credentials=credentials;
+    }
+
+    public String getAuthMethod()
+    {
+        return _method;
+    }
+
+    public UserIdentity getUserIdentity()
+    {
+        return _userIdentity;
+    }
+
+    public boolean isUserInRole(Scope scope, String role)
+    {
+        return _userIdentity.isUserInRole(role, scope);
+    }
+
+    private void readObject(ObjectInputStream stream) 
+        throws IOException, ClassNotFoundException 
+    {
+        stream.defaultReadObject();
+        
+        SecurityHandler security=SecurityHandler.getCurrentSecurityHandler();
+        if (security==null)
+            throw new IllegalStateException("!SecurityHandler");
+        LoginService login_service=security.getLoginService();
+        if (login_service==null)
+            throw new IllegalStateException("!LoginService");
+        
+        _userIdentity=login_service.login(_name,_credentials);
+        LOG.debug("Deserialized and relogged in {}",this);
+    }
+    
+    public void logout()
+    {
+        if (_session!=null && _session.getAttribute(__J_AUTHENTICATED)!=null)
+            _session.removeAttribute(__J_AUTHENTICATED);
+
+        doLogout();
+    }
+    
+    private void doLogout()
+    {
+        SecurityHandler security=SecurityHandler.getCurrentSecurityHandler();
+        if (security!=null)
+            security.logout(this);
+        if (_session!=null)
+            _session.removeAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED);
+    }
+        
+    @Override
+    public String toString()
+    {
+        return "Session"+super.toString();
+    }
+
+    public void sessionWillPassivate(HttpSessionEvent se)
+    {
+       
+    }
+
+    public void sessionDidActivate(HttpSessionEvent se)
+    {
+        if (_session==null)
+        {
+            _session=se.getSession();
+        }
+    }
+
+    public void valueBound(HttpSessionBindingEvent event)
+    {
+        if (_session==null)
+        {
+            _session=event.getSession();
+        }
+    }
+
+    public void valueUnbound(HttpSessionBindingEvent event)
+    {
+        doLogout();
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java b/src/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
new file mode 100644
index 0000000..7d933bd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java
@@ -0,0 +1,117 @@
+//
+//  ========================================================================
+//  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.security.authentication;
+
+import java.io.IOException;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.UserAuthentication;
+import org.eclipse.jetty.server.Authentication;
+import org.eclipse.jetty.server.Authentication.User;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.security.Constraint;
+
+public class SpnegoAuthenticator extends LoginAuthenticator
+{
+    private static final Logger LOG = Log.getLogger(SpnegoAuthenticator.class);
+    
+    private String _authMethod = Constraint.__SPNEGO_AUTH;
+    
+    public SpnegoAuthenticator()
+    {
+    	
+    }
+    
+    /**
+     * Allow for a custom authMethod value to be set for instances where SPENGO may not be appropriate
+     * @param authMethod
+     */
+    public SpnegoAuthenticator( String authMethod )
+    {
+    	_authMethod = authMethod;
+    }
+    
+    public String getAuthMethod()
+    {
+        return _authMethod;
+    }
+
+
+
+    public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException
+    {        
+        HttpServletRequest req = (HttpServletRequest)request;
+        HttpServletResponse res = (HttpServletResponse)response;
+        
+        String header = req.getHeader(HttpHeaders.AUTHORIZATION);
+
+        if (!mandatory)
+        {
+            return new DeferredAuthentication(this);
+        }
+        
+        // check to see if we have authorization headers required to continue
+        if ( header == null )
+        {
+            try
+            {
+            	 if (DeferredAuthentication.isDeferred(res))
+            	 {
+                     return Authentication.UNAUTHENTICATED;
+            	 }
+            	 
+                LOG.debug("SpengoAuthenticator: sending challenge");
+                res.setHeader(HttpHeaders.WWW_AUTHENTICATE, HttpHeaders.NEGOTIATE);
+                res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+                return Authentication.SEND_CONTINUE;
+            } 
+            catch (IOException ioe)
+            {
+                throw new ServerAuthException(ioe);
+            }       
+        }
+        else if (header != null && header.startsWith(HttpHeaders.NEGOTIATE))
+        {
+            String spnegoToken = header.substring(10);
+            
+            UserIdentity user = login(null,spnegoToken, request);
+            
+            if ( user != null )
+            {
+                return new UserAuthentication(getAuthMethod(),user);
+            }
+        }
+        
+        return Authentication.UNAUTHENTICATED;
+    }
+
+    public boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException
+    {
+        return true;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/AbstractConnector.java b/src/java/org/eclipse/jetty/server/AbstractConnector.java
new file mode 100644
index 0000000..2226242
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -0,0 +1,1222 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.servlet.ServletRequest;
+
+import org.eclipse.jetty.http.HttpBuffers;
+import org.eclipse.jetty.http.HttpBuffersImpl;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Buffers.Type;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.statistic.CounterStatistic;
+import org.eclipse.jetty.util.statistic.SampleStatistic;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/**
+ * Abstract Connector implementation. This abstract implementation of the Connector interface provides:
+ * <ul>
+ * <li>AbstractLifeCycle implementation</li>
+ * <li>Implementations for connector getters and setters</li>
+ * <li>Buffer management</li>
+ * <li>Socket configuration</li>
+ * <li>Base acceptor thread</li>
+ * <li>Optional reverse proxy headers checking</li>
+ * </ul>
+ */
+public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable
+{
+    private static final Logger LOG = Log.getLogger(AbstractConnector.class);
+
+    private String _name;
+
+    private Server _server;
+    private ThreadPool _threadPool;
+    private String _host;
+    private int _port = 0;
+    private String _integralScheme = HttpSchemes.HTTPS;
+    private int _integralPort = 0;
+    private String _confidentialScheme = HttpSchemes.HTTPS;
+    private int _confidentialPort = 0;
+    private int _acceptQueueSize = 0;
+    private int _acceptors = 1;
+    private int _acceptorPriorityOffset = 0;
+    private boolean _useDNS;
+    private boolean _forwarded;
+    private String _hostHeader;
+
+    private String _forwardedHostHeader = HttpHeaders.X_FORWARDED_HOST;
+    private String _forwardedServerHeader = HttpHeaders.X_FORWARDED_SERVER;
+    private String _forwardedForHeader = HttpHeaders.X_FORWARDED_FOR;
+    private String _forwardedProtoHeader = HttpHeaders.X_FORWARDED_PROTO;
+    private String _forwardedCipherSuiteHeader;
+    private String _forwardedSslSessionIdHeader;
+    private boolean _reuseAddress = true;
+
+    protected int _maxIdleTime = 200000;
+    protected int _lowResourceMaxIdleTime = -1;
+    protected int _soLingerTime = -1;
+
+    private transient Thread[] _acceptorThreads;
+
+    private final AtomicLong _statsStartedAt = new AtomicLong(-1L);
+
+    /** connections to server */
+    private final CounterStatistic _connectionStats = new CounterStatistic();
+    /** requests per connection */
+    private final SampleStatistic _requestStats = new SampleStatistic();
+    /** duration of a connection */
+    private final SampleStatistic _connectionDurationStats = new SampleStatistic();
+
+    protected final HttpBuffersImpl _buffers = new HttpBuffersImpl();
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public AbstractConnector()
+    {
+        addBean(_buffers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public Server getServer()
+    {
+        return _server;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setServer(Server server)
+    {
+        _server = server;
+    }
+
+    /* ------------------------------------------------------------ */
+    public ThreadPool getThreadPool()
+    {
+        return _threadPool;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the ThreadPool.
+     * The threadpool passed is added via {@link #addBean(Object)} so that 
+     * it's lifecycle may be managed as a {@link AggregateLifeCycle}.
+     * @param pool the threadPool to set
+     */
+    public void setThreadPool(ThreadPool pool)
+    {
+        removeBean(_threadPool);
+        _threadPool = pool;
+        addBean(_threadPool);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void setHost(String host)
+    {
+        _host = host;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public String getHost()
+    {
+        return _host;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setPort(int port)
+    {
+        _port = port;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getPort()
+    {
+        return _port;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the maxIdleTime.
+     */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations
+     * other mechanisms may be used to implement the timeout. The max idle time is applied:
+     * <ul>
+     * <li>When waiting for a new request to be received on a connection</li>
+     * <li>When reading the headers and content of a request</li>
+     * <li>When writing the headers and content of a response</li>
+     * </ul>
+     * Jetty interprets this value as the maximum time between some progress being made on the connection. So if a single byte is read or written, then the
+     * timeout (if implemented by jetty) is reset. However, in many instances, the reading/writing is delegated to the JVM, and the semantic is more strictly
+     * enforced as the maximum time a single read/write operation can take. Note, that as Jetty supports writes of memory mapped file buffers, then a write may
+     * take many 10s of seconds for large content written to a slow device.
+     * <p>
+     * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so
+     * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand).
+     *
+     * @param maxIdleTime
+     *            The maxIdleTime to set.
+     */
+    public void setMaxIdleTime(int maxIdleTime)
+    {
+        _maxIdleTime = maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the maxIdleTime when resources are low.
+     */
+    public int getLowResourcesMaxIdleTime()
+    {
+        return _lowResourceMaxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxIdleTime
+     *            The maxIdleTime to set when resources are low.
+     */
+    public void setLowResourcesMaxIdleTime(int maxIdleTime)
+    {
+        _lowResourceMaxIdleTime = maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the maxIdleTime when resources are low.
+     * @deprecated
+     */
+    @Deprecated
+    public final int getLowResourceMaxIdleTime()
+    {
+        return getLowResourcesMaxIdleTime();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxIdleTime
+     *            The maxIdleTime to set when resources are low.
+     * @deprecated
+     */
+    @Deprecated
+    public final void setLowResourceMaxIdleTime(int maxIdleTime)
+    {
+        setLowResourcesMaxIdleTime(maxIdleTime);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the soLingerTime.
+     */
+    public int getSoLingerTime()
+    {
+        return _soLingerTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the acceptQueueSize.
+     */
+    public int getAcceptQueueSize()
+    {
+        return _acceptQueueSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param acceptQueueSize
+     *            The acceptQueueSize to set.
+     */
+    public void setAcceptQueueSize(int acceptQueueSize)
+    {
+        _acceptQueueSize = acceptQueueSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the number of acceptor threads.
+     */
+    public int getAcceptors()
+    {
+        return _acceptors;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param acceptors
+     *            The number of acceptor threads to set.
+     */
+    public void setAcceptors(int acceptors)
+    {
+        if (acceptors > 2 * Runtime.getRuntime().availableProcessors())
+            LOG.warn("Acceptors should be <=2*availableProcessors: " + this);
+        _acceptors = acceptors;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param soLingerTime
+     *            The soLingerTime to set or -1 to disable.
+     */
+    public void setSoLingerTime(int soLingerTime)
+    {
+        _soLingerTime = soLingerTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_server == null)
+            throw new IllegalStateException("No server");
+
+        // open listener port
+        open();
+
+        if (_threadPool == null)
+        {
+            _threadPool = _server.getThreadPool();
+            addBean(_threadPool,false);
+        }
+
+        super.doStart();
+
+        // Start selector thread
+        synchronized (this)
+        {
+            _acceptorThreads = new Thread[getAcceptors()];
+
+            for (int i = 0; i < _acceptorThreads.length; i++)
+                if (!_threadPool.dispatch(new Acceptor(i)))
+                    throw new IllegalStateException("!accepting");
+            if (_threadPool.isLowOnThreads())
+                LOG.warn("insufficient threads configured for {}",this);
+        }
+
+        LOG.info("Started {}",this);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        try
+        {
+            close();
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+
+        super.doStop();
+
+        Thread[] acceptors;
+        synchronized (this)
+        {
+            acceptors = _acceptorThreads;
+            _acceptorThreads = null;
+        }
+        if (acceptors != null)
+        {
+            for (Thread thread : acceptors)
+            {
+                if (thread != null)
+                    thread.interrupt();
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void join() throws InterruptedException
+    {
+        Thread[] threads;
+        synchronized(this)
+        {
+            threads=_acceptorThreads;
+        }
+        if (threads != null)
+            for (Thread thread : threads)
+                if (thread != null)
+                    thread.join();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void configure(Socket socket) throws IOException
+    {
+        try
+        {
+            socket.setTcpNoDelay(true);
+            if (_soLingerTime >= 0)
+                socket.setSoLinger(true,_soLingerTime / 1000);
+            else
+                socket.setSoLinger(false,0);
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void customize(EndPoint endpoint, Request request) throws IOException
+    {
+        if (isForwarded())
+            checkForwardedHeaders(endpoint,request);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void checkForwardedHeaders(EndPoint endpoint, Request request) throws IOException
+    {
+        HttpFields httpFields = request.getConnection().getRequestFields();
+
+        // Do SSL first
+        if (getForwardedCipherSuiteHeader()!=null)
+        {
+            String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader());
+            if (cipher_suite!=null)
+                request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite);
+        }
+        if (getForwardedSslSessionIdHeader()!=null)
+        {
+            String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader());
+            if(ssl_session_id!=null)
+            {
+                request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id);
+                request.setScheme(HttpSchemes.HTTPS);
+            }
+        }
+
+        // Retrieving headers from the request
+        String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
+        String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
+        String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
+        String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
+
+        if (_hostHeader != null)
+        {
+            // Update host header
+            httpFields.put(HttpHeaders.HOST_BUFFER,_hostHeader);
+            request.setServerName(null);
+            request.setServerPort(-1);
+            request.getServerName();
+        }
+        else if (forwardedHost != null)
+        {
+            // Update host header
+            httpFields.put(HttpHeaders.HOST_BUFFER,forwardedHost);
+            request.setServerName(null);
+            request.setServerPort(-1);
+            request.getServerName();
+        }
+        else if (forwardedServer != null)
+        {
+            // Use provided server name
+            request.setServerName(forwardedServer);
+        }
+
+        if (forwardedFor != null)
+        {
+            request.setRemoteAddr(forwardedFor);
+            InetAddress inetAddress = null;
+
+            if (_useDNS)
+            {
+                try
+                {
+                    inetAddress = InetAddress.getByName(forwardedFor);
+                }
+                catch (UnknownHostException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+
+            request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName());
+        }
+
+        if (forwardedProto != null)
+        {
+            request.setScheme(forwardedProto);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected String getLeftMostFieldValue(HttpFields fields, String header)
+    {
+        if (header == null)
+            return null;
+
+        String headerValue = fields.getStringField(header);
+
+        if (headerValue == null)
+            return null;
+
+        int commaIndex = headerValue.indexOf(',');
+
+        if (commaIndex == -1)
+        {
+            // Single value
+            return headerValue;
+        }
+
+        // The left-most value is the farthest downstream client
+        return headerValue.substring(0,commaIndex);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void persist(EndPoint endpoint) throws IOException
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
+     */
+    public int getConfidentialPort()
+    {
+        return _confidentialPort;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#getConfidentialScheme()
+     */
+    public String getConfidentialScheme()
+    {
+        return _confidentialScheme;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server .Request)
+     */
+    public boolean isIntegral(Request request)
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
+     */
+    public int getIntegralPort()
+    {
+        return _integralPort;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#getIntegralScheme()
+     */
+    public String getIntegralScheme()
+    {
+        return _integralScheme;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request)
+     */
+    public boolean isConfidential(Request request)
+    {
+        return _forwarded && request.getScheme().equalsIgnoreCase(HttpSchemes.HTTPS);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param confidentialPort
+     *            The confidentialPort to set.
+     */
+    public void setConfidentialPort(int confidentialPort)
+    {
+        _confidentialPort = confidentialPort;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param confidentialScheme
+     *            The confidentialScheme to set.
+     */
+    public void setConfidentialScheme(String confidentialScheme)
+    {
+        _confidentialScheme = confidentialScheme;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param integralPort
+     *            The integralPort to set.
+     */
+    public void setIntegralPort(int integralPort)
+    {
+        _integralPort = integralPort;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param integralScheme
+     *            The integralScheme to set.
+     */
+    public void setIntegralScheme(String integralScheme)
+    {
+        _integralScheme = integralScheme;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected abstract void accept(int acceptorID) throws IOException, InterruptedException;
+
+    /* ------------------------------------------------------------ */
+    public void stopAccept(int acceptorID) throws Exception
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getResolveNames()
+    {
+        return _useDNS;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setResolveNames(boolean resolve)
+    {
+        _useDNS = resolve;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Is reverse proxy handling on?
+     *
+     * @return true if this connector is checking the x-forwarded-for/host/server headers
+     */
+    public boolean isForwarded()
+    {
+        return _forwarded;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol,
+     * host, server and client ip.
+     *
+     * @param check
+     *            true if this connector is checking the x-forwarded-for/host/server headers
+     * @see #setForwardedForHeader(String)
+     * @see #setForwardedHostHeader(String)
+     * @see #setForwardedProtoHeader(String)
+     * @see #setForwardedServerHeader(String)
+     */
+    public void setForwarded(boolean check)
+    {
+        if (check)
+            LOG.debug("{} is forwarded",this);
+        _forwarded = check;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getHostHeader()
+    {
+        return _hostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
+     * This value is only used if {@link #isForwarded()} is true.
+     *
+     * @param hostHeader
+     *            The value of the host header to force.
+     */
+    public void setHostHeader(String hostHeader)
+    {
+        _hostHeader = hostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     *
+     * @see #setForwarded(boolean)
+     */
+    public String getForwardedHostHeader()
+    {
+        return _forwardedHostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forwardedHostHeader
+     *            The header name for forwarded hosts (default x-forwarded-host)
+     * @see #setForwarded(boolean)
+     */
+    public void setForwardedHostHeader(String forwardedHostHeader)
+    {
+        _forwardedHostHeader = forwardedHostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the header name for forwarded server.
+     * @see #setForwarded(boolean)
+     */
+    public String getForwardedServerHeader()
+    {
+        return _forwardedServerHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forwardedServerHeader
+     *            The header name for forwarded server (default x-forwarded-server)
+     * @see #setForwarded(boolean)
+     */
+    public void setForwardedServerHeader(String forwardedServerHeader)
+    {
+        _forwardedServerHeader = forwardedServerHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see #setForwarded(boolean)
+     */
+    public String getForwardedForHeader()
+    {
+        return _forwardedForHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forwardedRemoteAddressHeader
+     *            The header name for forwarded for (default x-forwarded-for)
+     * @see #setForwarded(boolean)
+     */
+    public void setForwardedForHeader(String forwardedRemoteAddressHeader)
+    {
+        _forwardedForHeader = forwardedRemoteAddressHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the forwardedProtoHeader.
+     *
+     * @return the forwardedProtoHeader (default X-Forwarded-For)
+     * @see #setForwarded(boolean)
+     */
+    public String getForwardedProtoHeader()
+    {
+        return _forwardedProtoHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the forwardedProtoHeader.
+     *
+     * @param forwardedProtoHeader
+     *            the forwardedProtoHeader to set (default X-Forwarded-For)
+     * @see #setForwarded(boolean)
+     */
+    public void setForwardedProtoHeader(String forwardedProtoHeader)
+    {
+        _forwardedProtoHeader = forwardedProtoHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The header name holding a forwarded cipher suite (default null)
+     */
+    public String getForwardedCipherSuiteHeader()
+    {
+        return _forwardedCipherSuiteHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forwardedCipherSuite
+     *            The header name holding a forwarded cipher suite (default null)
+     */
+    public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
+    {
+        _forwardedCipherSuiteHeader = forwardedCipherSuite;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The header name holding a forwarded SSL Session ID (default null)
+     */
+    public String getForwardedSslSessionIdHeader()
+    {
+        return _forwardedSslSessionIdHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forwardedSslSessionId
+     *            The header name holding a forwarded SSL Session ID (default null)
+     */
+    public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
+    {
+        _forwardedSslSessionIdHeader = forwardedSslSessionId;
+    }
+
+    public int getRequestBufferSize()
+    {
+        return _buffers.getRequestBufferSize();
+    }
+
+    public void setRequestBufferSize(int requestBufferSize)
+    {
+        _buffers.setRequestBufferSize(requestBufferSize);
+    }
+
+    public int getRequestHeaderSize()
+    {
+        return _buffers.getRequestHeaderSize();
+    }
+
+    public void setRequestHeaderSize(int requestHeaderSize)
+    {
+        _buffers.setRequestHeaderSize(requestHeaderSize);
+    }
+
+    public int getResponseBufferSize()
+    {
+        return _buffers.getResponseBufferSize();
+    }
+
+    public void setResponseBufferSize(int responseBufferSize)
+    {
+        _buffers.setResponseBufferSize(responseBufferSize);
+    }
+
+    public int getResponseHeaderSize()
+    {
+        return _buffers.getResponseHeaderSize();
+    }
+
+    public void setResponseHeaderSize(int responseHeaderSize)
+    {
+        _buffers.setResponseHeaderSize(responseHeaderSize);
+    }
+
+    public Type getRequestBufferType()
+    {
+        return _buffers.getRequestBufferType();
+    }
+
+    public Type getRequestHeaderType()
+    {
+        return _buffers.getRequestHeaderType();
+    }
+
+    public Type getResponseBufferType()
+    {
+        return _buffers.getResponseBufferType();
+    }
+
+    public Type getResponseHeaderType()
+    {
+        return _buffers.getResponseHeaderType();
+    }
+
+    public void setRequestBuffers(Buffers requestBuffers)
+    {
+        _buffers.setRequestBuffers(requestBuffers);
+    }
+
+    public void setResponseBuffers(Buffers responseBuffers)
+    {
+        _buffers.setResponseBuffers(responseBuffers);
+    }
+
+    public Buffers getRequestBuffers()
+    {
+        return _buffers.getRequestBuffers();
+    }
+
+    public Buffers getResponseBuffers()
+    {
+        return _buffers.getResponseBuffers();
+    }
+
+    public void setMaxBuffers(int maxBuffers)
+    {
+        _buffers.setMaxBuffers(maxBuffers);
+    }
+
+    public int getMaxBuffers()
+    {
+        return _buffers.getMaxBuffers();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return String.format("%s@%s:%d",
+                getClass().getSimpleName(),
+                getHost()==null?"0.0.0.0":getHost(),
+                getLocalPort()<=0?getPort():getLocalPort());
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class Acceptor implements Runnable
+    {
+        int _acceptor = 0;
+
+        Acceptor(int id)
+        {
+            _acceptor = id;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void run()
+        {
+            Thread current = Thread.currentThread();
+            String name;
+            synchronized (AbstractConnector.this)
+            {
+                if (_acceptorThreads == null)
+                    return;
+
+                _acceptorThreads[_acceptor] = current;
+                name = _acceptorThreads[_acceptor].getName();
+                current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this);
+            }
+            int old_priority = current.getPriority();
+
+            try
+            {
+                current.setPriority(old_priority - _acceptorPriorityOffset);
+                while (isRunning() && getConnection() != null)
+                {
+                    try
+                    {
+                        accept(_acceptor);
+                    }
+                    catch (EofException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (IOException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (InterruptedException x)
+                    {
+                        // Connector has been stopped
+                        LOG.ignore(x);
+                    }
+                    catch (Throwable e)
+                    {
+                        LOG.warn(e);
+                    }
+                }
+            }
+            finally
+            {
+                current.setPriority(old_priority);
+                current.setName(name);
+
+                synchronized (AbstractConnector.this)
+                {
+                    if (_acceptorThreads != null)
+                        _acceptorThreads[_acceptor] = null;
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getName()
+    {
+        if (_name == null)
+            _name = (getHost() == null?"0.0.0.0":getHost()) + ":" + (getLocalPort() <= 0?getPort():getLocalPort());
+        return _name;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Get the number of requests handled by this connector since last call of statsReset(). If setStatsOn(false) then this is undefined.
+     */
+    public int getRequests()
+    {
+        return (int)_requestStats.getTotal();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the connectionsDurationTotal.
+     */
+    public long getConnectionsDurationTotal()
+    {
+        return _connectionDurationStats.getTotal();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Number of connections accepted by the server since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnections()
+    {
+        return (int)_connectionStats.getTotal();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Number of connections currently open that were opened since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsOpen()
+    {
+        return (int)_connectionStats.getCurrent();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Maximum number of connections opened simultaneously since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsOpenMax()
+    {
+        return (int)_connectionStats.getMax();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Mean duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsDurationMean()
+    {
+        return _connectionDurationStats.getMean();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Maximum duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public long getConnectionsDurationMax()
+    {
+        return _connectionDurationStats.getMax();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Standard deviation of duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsDurationStdDev()
+    {
+        return _connectionDurationStats.getStdDev();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Mean number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsRequestsMean()
+    {
+        return _requestStats.getMean();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Maximum number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsRequestsMax()
+    {
+        return (int)_requestStats.getMax();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Standard deviation of number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsRequestsStdDev()
+    {
+        return _requestStats.getStdDev();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Reset statistics.
+     */
+    public void statsReset()
+    {
+        updateNotEqual(_statsStartedAt,-1,System.currentTimeMillis());
+
+        _requestStats.reset();
+        _connectionStats.reset();
+        _connectionDurationStats.reset();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setStatsOn(boolean on)
+    {
+        if (on && _statsStartedAt.get() != -1)
+            return;
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("Statistics on = " + on + " for " + this);
+
+        statsReset();
+        _statsStartedAt.set(on?System.currentTimeMillis():-1);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if statistics collection is turned on.
+     */
+    public boolean getStatsOn()
+    {
+        return _statsStartedAt.get() != -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Timestamp stats were started at.
+     */
+    public long getStatsOnMs()
+    {
+        long start = _statsStartedAt.get();
+
+        return (start != -1)?(System.currentTimeMillis() - start):0;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void connectionOpened(Connection connection)
+    {
+        if (_statsStartedAt.get() == -1)
+            return;
+
+        _connectionStats.increment();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void connectionUpgraded(Connection oldConnection, Connection newConnection)
+    {
+        _requestStats.set((oldConnection instanceof AbstractHttpConnection)?((AbstractHttpConnection)oldConnection).getRequests():0);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void connectionClosed(Connection connection)
+    {
+        connection.onClose();
+
+        if (_statsStartedAt.get() == -1)
+            return;
+
+        long duration = System.currentTimeMillis() - connection.getTimeStamp();
+        int requests = (connection instanceof AbstractHttpConnection)?((AbstractHttpConnection)connection).getRequests():0;
+        _requestStats.set(requests);
+        _connectionStats.decrement();
+        _connectionDurationStats.set(duration);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the acceptorPriority
+     */
+    public int getAcceptorPriorityOffset()
+    {
+        return _acceptorPriorityOffset;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the priority offset of the acceptor threads. The priority is adjusted by this amount (default 0) to either favour the acceptance of new threads and
+     * newly active connections or to favour the handling of already dispatched connections.
+     *
+     * @param offset
+     *            the amount to alter the priority of the acceptor threads.
+     */
+    public void setAcceptorPriorityOffset(int offset)
+    {
+        _acceptorPriorityOffset = offset;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the the server socket will be opened in SO_REUSEADDR mode.
+     */
+    public boolean getReuseAddress()
+    {
+        return _reuseAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param reuseAddress
+     *            True if the the server socket will be opened in SO_REUSEADDR mode.
+     */
+    public void setReuseAddress(boolean reuseAddress)
+    {
+        _reuseAddress = reuseAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isLowResources()
+    {
+        if (_threadPool != null)
+            return _threadPool.isLowOnThreads();
+        return _server.getThreadPool().isLowOnThreads();
+    }
+
+    /* ------------------------------------------------------------ */
+    private void updateNotEqual(AtomicLong valueHolder, long compare, long value)
+    {
+        long oldValue = valueHolder.get();
+        while (compare != oldValue)
+        {
+            if (valueHolder.compareAndSet(oldValue,value))
+                break;
+            oldValue = valueHolder.get();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/src/java/org/eclipse/jetty/server/AbstractHttpConnection.java
new file mode 100644
index 0000000..4cdc132
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/AbstractHttpConnection.java
@@ -0,0 +1,1273 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.ContinuationThrowable;
+import org.eclipse.jetty.http.EncodedHttpURI;
+import org.eclipse.jetty.http.Generator;
+import org.eclipse.jetty.http.HttpBuffers;
+import org.eclipse.jetty.http.HttpContent;
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpGenerator;
+import org.eclipse.jetty.http.HttpHeaderValues;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.HttpVersions;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.http.Parser;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.RuntimeIOException;
+import org.eclipse.jetty.io.UncheckedPrintWriter;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.server.nio.NIOConnector;
+import org.eclipse.jetty.server.ssl.SslConnector;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * <p>A HttpConnection represents the connection of a HTTP client to the server
+ * and is created by an instance of a {@link Connector}. It's prime function is
+ * to associate {@link Request} and {@link Response} instances with a {@link EndPoint}.
+ * </p>
+ * <p>
+ * A connection is also the prime mechanism used by jetty to recycle objects without
+ * pooling.  The {@link Request},  {@link Response}, {@link HttpParser}, {@link HttpGenerator}
+ * and {@link HttpFields} instances are all recycled for the duraction of
+ * a connection. Where appropriate, allocated buffers are also kept associated
+ * with the connection via the parser and/or generator.
+ * </p>
+ * <p>
+ * The connection state is held by 3 separate state machines: The request state, the
+ * response state and the continuation state.  All three state machines must be driven
+ * to completion for every request, and all three can complete in any order.
+ * </p>
+ * <p>
+ * The HttpConnection support protocol upgrade.  If on completion of a request, the
+ * response code is 101 (switch protocols), then the org.eclipse.jetty.io.Connection
+ * request attribute is checked to see if there is a new Connection instance. If so,
+ * the new connection is returned from {@link #handle()} and is used for future
+ * handling of the underlying connection.   Note that for switching protocols that
+ * don't use 101 responses (eg CONNECT), the response should be sent and then the
+ * status code changed to 101 before returning from the handler.  Implementors
+ * of new Connection types should be careful to extract any buffered data from
+ * (HttpParser)http.getParser()).getHeaderBuffer() and
+ * (HttpParser)http.getParser()).getBodyBuffer() to initialise their new connection.
+ * </p>
+ *
+ */
+public abstract class AbstractHttpConnection  extends AbstractConnection
+{
+    private static final Logger LOG = Log.getLogger(AbstractHttpConnection.class);
+
+    private static final int UNKNOWN = -2;
+    private static final ThreadLocal<AbstractHttpConnection> __currentConnection = new ThreadLocal<AbstractHttpConnection>();
+
+    private int _requests;
+
+    protected final Connector _connector;
+    protected final Server _server;
+    protected final HttpURI _uri;
+
+    protected final Parser _parser;
+    protected final HttpFields _requestFields;
+    protected final Request _request;
+    protected volatile ServletInputStream _in;
+
+    protected final Generator _generator;
+    protected final HttpFields _responseFields;
+    protected final Response _response;
+    protected volatile Output _out;
+    protected volatile OutputWriter _writer;
+    protected volatile PrintWriter _printWriter;
+
+    int _include;
+
+    private Object _associatedObject; // associated object
+
+    private int _version = UNKNOWN;
+
+    private String _charset;
+    private boolean _expect = false;
+    private boolean _expect100Continue = false;
+    private boolean _expect102Processing = false;
+    private boolean _head = false;
+    private boolean _host = false;
+    private boolean _delayedHandling=false;
+    private boolean _earlyEOF = false;
+
+    /* ------------------------------------------------------------ */
+    public static AbstractHttpConnection getCurrentConnection()
+    {
+        return __currentConnection.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected static void setCurrentConnection(AbstractHttpConnection connection)
+    {
+        __currentConnection.set(connection);
+    }
+
+    /* ------------------------------------------------------------ */
+    public AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server)
+    {
+        super(endpoint);
+        _uri = StringUtil.__UTF8.equals(URIUtil.__CHARSET)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
+        _connector = connector;
+        HttpBuffers ab = (HttpBuffers)_connector;
+        _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler());
+        _requestFields = new HttpFields();
+        _responseFields = new HttpFields();
+        _request = new Request(this);
+        _response = new Response(this);
+        _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint);
+        _generator.setSendServerVersion(server.getSendServerVersion());
+        _server = server;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected AbstractHttpConnection(Connector connector, EndPoint endpoint, Server server,
+            Parser parser, Generator generator, Request request)
+    {
+        super(endpoint);
+
+        _uri = URIUtil.__CHARSET.equals(StringUtil.__UTF8)?new HttpURI():new EncodedHttpURI(URIUtil.__CHARSET);
+        _connector = connector;
+        _parser = parser;
+        _requestFields = new HttpFields();
+        _responseFields = new HttpFields();
+        _request = request;
+        _response = new Response(this);
+        _generator = generator;
+        _generator.setSendServerVersion(server.getSendServerVersion());
+        _server = server;
+    }
+
+    protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endpoint, HttpParser.EventHandler requestHandler)
+    {
+        return new HttpParser(requestBuffers, endpoint, requestHandler);
+    }
+
+    protected HttpGenerator newHttpGenerator(Buffers responseBuffers, EndPoint endPoint)
+    {
+        return new HttpGenerator(responseBuffers, endPoint);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the parser used by this connection
+     */
+    public Parser getParser()
+    {
+        return _parser;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the number of requests handled by this connection
+     */
+    public int getRequests()
+    {
+        return _requests;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Server getServer()
+    {
+        return _server;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the associatedObject.
+     */
+    public Object getAssociatedObject()
+    {
+        return _associatedObject;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param associatedObject The associatedObject to set.
+     */
+    public void setAssociatedObject(Object associatedObject)
+    {
+        _associatedObject = associatedObject;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the connector.
+     */
+    public Connector getConnector()
+    {
+        return _connector;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the requestFields.
+     */
+    public HttpFields getRequestFields()
+    {
+        return _requestFields;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the responseFields.
+     */
+    public HttpFields getResponseFields()
+    {
+        return _responseFields;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Find out if the request supports CONFIDENTIAL security.
+     * @param request the incoming HTTP request
+     * @return the result of calling {@link Connector#isConfidential(Request)}, or false
+     * if there is no connector
+     */
+    public boolean isConfidential(Request request)
+    {
+        return _connector != null && _connector.isConfidential(request);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Find out if the request supports INTEGRAL security.
+     * @param request the incoming HTTP request
+     * @return the result of calling {@link Connector#isIntegral(Request)}, or false
+     * if there is no connector
+     */
+    public boolean isIntegral(Request request)
+    {
+        return _connector != null && _connector.isIntegral(request);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return <code>false</code> (this method is not yet implemented)
+     */
+    public boolean getResolveNames()
+    {
+        return _connector.getResolveNames();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the request.
+     */
+    public Request getRequest()
+    {
+        return _request;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the response.
+     */
+    public Response getResponse()
+    {
+        return _response;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the inputStream from the connection.
+     * <p>
+     * If the associated response has the Expect header set to 100 Continue,
+     * then accessing the input stream indicates that the handler/servlet
+     * is ready for the request body and thus a 100 Continue response is sent.
+     *
+     * @return The input stream for this connection.
+     * The stream will be created if it does not already exist.
+     * @throws IOException if the input stream cannot be retrieved
+     */
+    public ServletInputStream getInputStream() throws IOException
+    {
+        // If the client is expecting 100 CONTINUE, then send it now.
+        if (_expect100Continue)
+        {
+            // is content missing?
+            if (((HttpParser)_parser).getHeaderBuffer()==null || ((HttpParser)_parser).getHeaderBuffer().length()<2)
+            {
+                if (_generator.isCommitted())
+                    throw new IllegalStateException("Committed before 100 Continues");
+
+                ((HttpGenerator)_generator).send1xx(HttpStatus.CONTINUE_100);
+            }
+            _expect100Continue=false;
+        }
+
+        if (_in == null)
+            _in = new HttpInput(AbstractHttpConnection.this);
+        return _in;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The output stream for this connection. The stream will be created if it does not already exist.
+     */
+    public ServletOutputStream getOutputStream()
+    {
+        if (_out == null)
+            _out = new Output();
+        return _out;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param encoding the PrintWriter encoding
+     * @return A {@link PrintWriter} wrapping the {@link #getOutputStream output stream}. The writer is created if it
+     *    does not already exist.
+     */
+    public PrintWriter getPrintWriter(String encoding)
+    {
+        getOutputStream();
+        if (_writer==null)
+        {
+            _writer=new OutputWriter();
+            if (_server.isUncheckedPrintWriter())
+                _printWriter=new UncheckedPrintWriter(_writer);
+            else
+                _printWriter = new PrintWriter(_writer)
+                {
+                    public void close()
+                    {
+                        synchronized (lock)
+                        {
+                            try
+                            {
+                                out.close();
+                            }
+                            catch (IOException e)
+                            {
+                                setError();
+                            }
+                        }
+                    }
+                };
+        }
+        _writer.setCharacterEncoding(encoding);
+        return _printWriter;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isResponseCommitted()
+    {
+        return _generator.isCommitted();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isEarlyEOF()
+    {
+        return _earlyEOF;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void reset()
+    {
+        _parser.reset();
+        _parser.returnBuffers(); // TODO maybe only on unhandle
+        _requestFields.clear();
+        _request.recycle();
+        _generator.reset();
+        _generator.returnBuffers();// TODO maybe only on unhandle
+        _responseFields.clear();
+        _response.recycle();
+        _uri.clear();
+        _writer=null;
+        _earlyEOF = false;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void handleRequest() throws IOException
+    {
+        boolean error = false;
+
+        String threadName=null;
+        Throwable async_exception=null;
+        try
+        {
+            if (LOG.isDebugEnabled())
+            {
+                threadName=Thread.currentThread().getName();
+                Thread.currentThread().setName(threadName+" - "+_uri);
+            }
+
+
+            // Loop here to handle async request redispatches.
+            // The loop is controlled by the call to async.unhandle in the
+            // finally block below.  If call is from a non-blocking connector,
+            // then the unhandle will return false only if an async dispatch has
+            // already happened when unhandle is called.   For a blocking connector,
+            // the wait for the asynchronous dispatch or timeout actually happens
+            // within the call to unhandle().
+
+            final Server server=_server;
+            boolean was_continuation=_request._async.isContinuation();
+            boolean handling=_request._async.handling() && server!=null && server.isRunning();
+            while (handling)
+            {
+                _request.setHandled(false);
+
+                String info=null;
+                try
+                {
+                    _uri.getPort();
+                    String path = null;
+
+                    try
+                    {
+                        path = _uri.getDecodedPath();
+                    }
+                    catch (Exception e)
+                    {
+                        LOG.warn("Failed UTF-8 decode for request path, trying ISO-8859-1");
+                        LOG.ignore(e);
+                        path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
+                    }
+
+                    info=URIUtil.canonicalPath(path);
+                    if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
+                    {
+                        if (path==null && _uri.getScheme()!=null && _uri.getHost()!=null)
+                        {
+                            info="/";
+                            _request.setRequestURI("");
+                        }
+                        else
+                            throw new HttpException(400);
+                    }
+                    _request.setPathInfo(info);
+
+                    if (_out!=null)
+                        _out.reopen();
+
+                    if (_request._async.isInitial())
+                    {
+                        _request.setDispatcherType(DispatcherType.REQUEST);
+                        _connector.customize(_endp, _request);
+                        server.handle(this);
+                    }
+                    else
+                    {
+                        if (_request._async.isExpired()&&!was_continuation)
+                        {
+                            async_exception = (Throwable)_request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+                            _response.setStatus(500,async_exception==null?"Async Timeout":"Async Exception");
+                            _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
+                            _request.setAttribute(RequestDispatcher.ERROR_MESSAGE, _response.getReason());
+                            _request.setDispatcherType(DispatcherType.ERROR);
+                            
+                            ErrorHandler eh = _request._async.getContextHandler().getErrorHandler();
+                            if (eh instanceof ErrorHandler.ErrorPageMapper)
+                            {
+                                String error_page=((ErrorHandler.ErrorPageMapper)eh).getErrorPage((HttpServletRequest)_request._async.getRequest());
+                                if (error_page!=null)
+                                { 
+                                    AsyncContinuation.AsyncEventState state = _request._async.getAsyncEventState();
+                                    state.setPath(error_page);
+                                }
+                            }
+                        }
+                        else
+                            _request.setDispatcherType(DispatcherType.ASYNC);
+                        server.handleAsync(this);
+                    }
+                }
+                catch (ContinuationThrowable e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (EofException e)
+                {
+                    async_exception=e;
+                    LOG.debug(e);
+                    error=true;
+                    _request.setHandled(true);
+                    if (!_response.isCommitted())
+                        _generator.sendError(500, null, null, true);
+                }
+                catch (RuntimeIOException e)
+                {
+                    async_exception=e;
+                    LOG.debug(e);
+                    error=true;
+                    _request.setHandled(true);
+                }
+                catch (HttpException e)
+                {
+                    LOG.debug(e);
+                    error=true;
+                    _request.setHandled(true);
+                    _response.sendError(e.getStatus(), e.getReason());
+                }
+                catch (Throwable e)
+                {
+                    async_exception=e;
+                    LOG.warn(String.valueOf(_uri),e);
+                    error=true;
+                    _request.setHandled(true);
+                    _generator.sendError(info==null?400:500, null, null, true);
+                    
+                }
+                finally
+                {
+                    // Complete async requests 
+                    if (error && _request.isAsyncStarted())
+                        _request.getAsyncContinuation().errorComplete();
+                        
+                    was_continuation=_request._async.isContinuation();
+                    handling = !_request._async.unhandle() && server.isRunning() && _server!=null;
+                }
+            }
+        }
+        finally
+        {
+            if (threadName!=null)
+                Thread.currentThread().setName(threadName);
+
+            if (_request._async.isUncompleted())
+            {
+                
+                _request._async.doComplete(async_exception);
+
+                if (_expect100Continue)
+                {
+                    LOG.debug("100 continues not sent");
+                    // We didn't send 100 continues, but the latest interpretation
+                    // of the spec (see httpbis) is that the client will either
+                    // send the body anyway, or close.  So we no longer need to
+                    // do anything special here other than make the connection not persistent
+                    _expect100Continue = false;
+                    if (!_response.isCommitted())
+                        _generator.setPersistent(false);
+                }
+
+                if(_endp.isOpen())
+                {
+                    if (error)
+                    {
+                        _endp.shutdownOutput();
+                        _generator.setPersistent(false);
+                        if (!_generator.isComplete())
+                            _response.complete();
+                    }
+                    else
+                    {
+                        if (!_response.isCommitted() && !_request.isHandled())
+                            _response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                        _response.complete();
+                        if (_generator.isPersistent())
+                            _connector.persist(_endp);
+                    }
+                }
+                else
+                {
+                    _response.complete();
+                }
+
+                _request.setHandled(true);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public abstract Connection handle() throws IOException;
+
+    /* ------------------------------------------------------------ */
+    public void commitResponse(boolean last) throws IOException
+    {
+        if (!_generator.isCommitted())
+        {
+            _generator.setResponse(_response.getStatus(), _response.getReason());
+            try
+            {
+                // If the client was expecting 100 continues, but we sent something
+                // else, then we need to close the connection
+                if (_expect100Continue && _response.getStatus()!=100)
+                    _generator.setPersistent(false);
+                _generator.completeHeader(_responseFields, last);
+            }
+            catch(RuntimeException e)
+            {
+                LOG.warn("header full: " + e);
+
+                _response.reset();
+                _generator.reset();
+                _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
+                _generator.completeHeader(_responseFields,Generator.LAST);
+                _generator.complete();
+                throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
+            }
+
+        }
+        if (last)
+            _generator.complete();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void completeResponse() throws IOException
+    {
+        if (!_generator.isCommitted())
+        {
+            _generator.setResponse(_response.getStatus(), _response.getReason());
+            try
+            {
+                _generator.completeHeader(_responseFields, Generator.LAST);
+            }
+            catch(RuntimeException e)
+            {
+                LOG.warn("header full: "+e);
+                LOG.debug(e);
+
+                _response.reset();
+                _generator.reset();
+                _generator.setResponse(HttpStatus.INTERNAL_SERVER_ERROR_500,null);
+                _generator.completeHeader(_responseFields,Generator.LAST);
+                _generator.complete();
+                throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR_500);
+            }
+        }
+
+        _generator.complete();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void flushResponse() throws IOException
+    {
+        try
+        {
+            commitResponse(Generator.MORE);
+            _generator.flushBuffer();
+        }
+        catch(IOException e)
+        {
+            throw (e instanceof EofException) ? e:new EofException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Generator getGenerator()
+    {
+        return _generator;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIncluding()
+    {
+        return _include>0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void include()
+    {
+        _include++;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void included()
+    {
+        _include--;
+        if (_out!=null)
+            _out.reopen();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _generator.isIdle() && (_parser.isIdle() || _delayedHandling);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.Connection#isSuspended()
+     */
+    public boolean isSuspended()
+    {
+        return _request.getAsyncContinuation().isSuspended();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        LOG.debug("closed {}",this);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isExpecting100Continues()
+    {
+        return _expect100Continue;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isExpecting102Processing()
+    {
+        return _expect102Processing;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxIdleTime()
+    {
+        if (_connector.isLowResources() && _endp.getMaxIdleTime()==_connector.getMaxIdleTime())
+            return _connector.getLowResourceMaxIdleTime();
+        if (_endp.getMaxIdleTime()>0)
+            return _endp.getMaxIdleTime();
+        return _connector.getMaxIdleTime();
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return String.format("%s,g=%s,p=%s,r=%d",
+                super.toString(),
+                _generator,
+                _parser,
+                _requests);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
+    {
+        uri=uri.asImmutableBuffer();
+
+        _host = false;
+        _expect = false;
+        _expect100Continue=false;
+        _expect102Processing=false;
+        _delayedHandling=false;
+        _charset=null;
+
+        if(_request.getTimeStamp()==0)
+            _request.setTimeStamp(System.currentTimeMillis());
+        _request.setMethod(method.toString());
+
+        try
+        {
+            _head=false;
+            switch (HttpMethods.CACHE.getOrdinal(method))
+            {
+              case HttpMethods.CONNECT_ORDINAL:
+                  _uri.parseConnect(uri.array(), uri.getIndex(), uri.length());
+                  break;
+
+              case HttpMethods.HEAD_ORDINAL:
+                  _head=true;
+                  _uri.parse(uri.array(), uri.getIndex(), uri.length());
+                  break;
+
+              default:
+                  _uri.parse(uri.array(), uri.getIndex(), uri.length());
+            }
+
+            _request.setUri(_uri);
+
+            if (version==null)
+            {
+                _request.setProtocol(HttpVersions.HTTP_0_9);
+                _version=HttpVersions.HTTP_0_9_ORDINAL;
+            }
+            else
+            {
+                version= HttpVersions.CACHE.get(version);
+                if (version==null)
+                    throw new HttpException(HttpStatus.BAD_REQUEST_400,null);
+                _version = HttpVersions.CACHE.getOrdinal(version);
+                if (_version <= 0) _version = HttpVersions.HTTP_1_0_ORDINAL;
+                _request.setProtocol(version.toString());
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.debug(e);
+            if (e instanceof HttpException)
+                throw (HttpException)e;
+            throw new HttpException(HttpStatus.BAD_REQUEST_400,null,e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void parsedHeader(Buffer name, Buffer value) throws IOException
+    {
+        int ho = HttpHeaders.CACHE.getOrdinal(name);
+        switch (ho)
+        {
+            case HttpHeaders.HOST_ORDINAL:
+                // TODO check if host matched a host in the URI.
+                _host = true;
+                break;
+
+            case HttpHeaders.EXPECT_ORDINAL:
+                if (_version>=HttpVersions.HTTP_1_1_ORDINAL)
+                {
+                    value = HttpHeaderValues.CACHE.lookup(value);
+                    switch(HttpHeaderValues.CACHE.getOrdinal(value))
+                    {
+                        case HttpHeaderValues.CONTINUE_ORDINAL:
+                            _expect100Continue=_generator instanceof HttpGenerator;
+                            break;
+
+                        case HttpHeaderValues.PROCESSING_ORDINAL:
+                            _expect102Processing=_generator instanceof HttpGenerator;
+                            break;
+
+                        default:
+                            String[] values = value.toString().split(",");
+                            for  (int i=0;values!=null && i<values.length;i++)
+                            {
+                                CachedBuffer cb=HttpHeaderValues.CACHE.get(values[i].trim());
+                                if (cb==null)
+                                    _expect=true;
+                                else
+                                {
+                                    switch(cb.getOrdinal())
+                                    {
+                                        case HttpHeaderValues.CONTINUE_ORDINAL:
+                                            _expect100Continue=_generator instanceof HttpGenerator;
+                                            break;
+                                        case HttpHeaderValues.PROCESSING_ORDINAL:
+                                            _expect102Processing=_generator instanceof HttpGenerator;
+                                            break;
+                                        default:
+                                            _expect=true;
+                                    }
+                                }
+                            }
+                    }
+                }
+                break;
+
+            case HttpHeaders.ACCEPT_ENCODING_ORDINAL:
+            case HttpHeaders.USER_AGENT_ORDINAL:
+                value = HttpHeaderValues.CACHE.lookup(value);
+                break;
+
+            case HttpHeaders.CONTENT_TYPE_ORDINAL:
+                value = MimeTypes.CACHE.lookup(value);
+                _charset=MimeTypes.getCharsetFromContentType(value);
+                break;
+        }
+
+        _requestFields.add(name, value);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void headerComplete() throws IOException
+    {
+        // Handle idle race
+        if (_endp.isOutputShutdown())
+        {
+            _endp.close();
+            return;
+        }
+        
+        _requests++;
+        _generator.setVersion(_version);
+        switch (_version)
+        {
+            case HttpVersions.HTTP_0_9_ORDINAL:
+                break;
+            case HttpVersions.HTTP_1_0_ORDINAL:
+                _generator.setHead(_head);
+                if (_parser.isPersistent())
+                {
+                    _responseFields.add(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.KEEP_ALIVE_BUFFER);
+                    _generator.setPersistent(true);
+                }
+                else if (HttpMethods.CONNECT.equals(_request.getMethod()))
+                {
+                    _generator.setPersistent(true);
+                    _parser.setPersistent(true);
+                }
+
+                if (_server.getSendDateHeader())
+                    _generator.setDate(_request.getTimeStampBuffer());
+                break;
+
+            case HttpVersions.HTTP_1_1_ORDINAL:
+                _generator.setHead(_head);
+
+                if (!_parser.isPersistent())
+                {
+                    _responseFields.add(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
+                    _generator.setPersistent(false);
+                }
+                if (_server.getSendDateHeader())
+                    _generator.setDate(_request.getTimeStampBuffer());
+
+                if (!_host)
+                {
+                    LOG.debug("!host {}",this);
+                    _generator.setResponse(HttpStatus.BAD_REQUEST_400, null);
+                    _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+                    _generator.completeHeader(_responseFields, true);
+                    _generator.complete();
+                    return;
+                }
+
+                if (_expect)
+                {
+                    LOG.debug("!expectation {}",this);
+                    _generator.setResponse(HttpStatus.EXPECTATION_FAILED_417, null);
+                    _responseFields.put(HttpHeaders.CONNECTION_BUFFER, HttpHeaderValues.CLOSE_BUFFER);
+                    _generator.completeHeader(_responseFields, true);
+                    _generator.complete();
+                    return;
+                }
+
+                break;
+            default:
+        }
+
+        if(_charset!=null)
+            _request.setCharacterEncodingUnchecked(_charset);
+
+        // Either handle now or wait for first content
+        if ((((HttpParser)_parser).getContentLength()<=0 && !((HttpParser)_parser).isChunking())||_expect100Continue)
+            handleRequest();
+        else
+            _delayedHandling=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void content(Buffer buffer) throws IOException
+    {
+        if (_delayedHandling)
+        {
+            _delayedHandling=false;
+            handleRequest();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void messageComplete(long contentLength) throws IOException
+    {
+        if (_delayedHandling)
+        {
+            _delayedHandling=false;
+            handleRequest();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void earlyEOF()
+    {
+        _earlyEOF = true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class RequestHandler extends HttpParser.EventHandler
+    {
+        /*
+         *
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startRequest(org.eclipse.io.Buffer,
+         *      org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+         */
+        @Override
+        public void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
+        {
+            AbstractHttpConnection.this.startRequest(method, uri, version);
+        }
+
+        /*
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#parsedHeaderValue(org.eclipse.io.Buffer)
+         */
+        @Override
+        public void parsedHeader(Buffer name, Buffer value) throws IOException
+        {
+            AbstractHttpConnection.this.parsedHeader(name, value);
+        }
+
+        /*
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#headerComplete()
+         */
+        @Override
+        public void headerComplete() throws IOException
+        {
+            AbstractHttpConnection.this.headerComplete();
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#content(int, org.eclipse.io.Buffer)
+         */
+        @Override
+        public void content(Buffer ref) throws IOException
+        {
+            AbstractHttpConnection.this.content(ref);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * (non-Javadoc)
+         *
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#messageComplete(int)
+         */
+        @Override
+        public void messageComplete(long contentLength) throws IOException
+        {
+            AbstractHttpConnection.this.messageComplete(contentLength);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * (non-Javadoc)
+         *
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#startResponse(org.eclipse.io.Buffer, int,
+         *      org.eclipse.io.Buffer)
+         */
+        @Override
+        public void startResponse(Buffer version, int status, Buffer reason)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("Bad request!: "+version+" "+status+" "+reason);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * (non-Javadoc)
+         *
+         * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF()
+         */
+        @Override
+        public void earlyEOF()
+        {
+            AbstractHttpConnection.this.earlyEOF();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class Output extends HttpOutput
+    {
+        Output()
+        {
+            super(AbstractHttpConnection.this);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see java.io.OutputStream#close()
+         */
+        @Override
+        public void close() throws IOException
+        {
+            if (isClosed())
+                return;
+
+            if (!isIncluding() && !super._generator.isCommitted())
+                commitResponse(Generator.LAST);
+            else
+                flushResponse();
+
+            super.close();
+        }
+
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see java.io.OutputStream#flush()
+         */
+        @Override
+        public void flush() throws IOException
+        {
+            if (!super._generator.isCommitted())
+                commitResponse(Generator.MORE);
+            super.flush();
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletOutputStream#print(java.lang.String)
+         */
+        @Override
+        public void print(String s) throws IOException
+        {
+            if (isClosed())
+                throw new IOException("Closed");
+            PrintWriter writer=getPrintWriter(null);
+            writer.print(s);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendResponse(Buffer response) throws IOException
+        {
+            ((HttpGenerator)super._generator).sendResponse(response);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendContent(Object content) throws IOException
+        {
+            Resource resource=null;
+
+            if (isClosed())
+                throw new IOException("Closed");
+
+            if (super._generator.isWritten())
+                throw new IllegalStateException("!empty");
+
+            // Convert HTTP content to content
+            if (content instanceof HttpContent)
+            {
+                HttpContent httpContent = (HttpContent) content;
+                Buffer contentType = httpContent.getContentType();
+                if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER))
+                {
+                    String enc = _response.getSetCharacterEncoding();
+                    if(enc==null)
+                        _responseFields.add(HttpHeaders.CONTENT_TYPE_BUFFER, contentType);
+                    else
+                    {
+                        if(contentType instanceof CachedBuffer)
+                        {
+                            CachedBuffer content_type = ((CachedBuffer)contentType).getAssociate(enc);
+                            if(content_type!=null)
+                                _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, content_type);
+                            else
+                            {
+                                _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
+                                        contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
+                            }
+                        }
+                        else
+                        {
+                            _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER,
+                                    contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(enc,";= "));
+                        }
+                    }
+                }
+                if (httpContent.getContentLength() > 0)
+                    _responseFields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength());
+                Buffer lm = httpContent.getLastModified();
+                long lml=httpContent.getResource().lastModified();
+                if (lm != null)
+                {
+                    _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm);
+                }
+                else if (httpContent.getResource()!=null)
+                {
+                    if (lml!=-1)
+                        _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml);
+                }
+                
+                Buffer etag=httpContent.getETag();
+                if (etag!=null)
+                    _responseFields.put(HttpHeaders.ETAG_BUFFER,etag);
+
+                
+                boolean direct=_connector instanceof NIOConnector && ((NIOConnector)_connector).getUseDirectBuffers() && !(_connector instanceof SslConnector);
+                content = direct?httpContent.getDirectBuffer():httpContent.getIndirectBuffer();
+                if (content==null)
+                    content=httpContent.getInputStream();
+            }
+            else if (content instanceof Resource)
+            {
+                resource=(Resource)content;
+                _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified());
+                content=resource.getInputStream();
+            }
+
+            // Process content.
+            if (content instanceof Buffer)
+            {
+                super._generator.addContent((Buffer) content, Generator.LAST);
+                commitResponse(Generator.LAST);
+            }
+            else if (content instanceof InputStream)
+            {
+                InputStream in = (InputStream)content;
+
+                try
+                {
+                    int max = super._generator.prepareUncheckedAddContent();
+                    Buffer buffer = super._generator.getUncheckedBuffer();
+
+                    int len=buffer.readFrom(in,max);
+
+                    while (len>=0)
+                    {
+                        super._generator.completeUncheckedAddContent();
+                        _out.flush();
+
+                        max = super._generator.prepareUncheckedAddContent();
+                        buffer = super._generator.getUncheckedBuffer();
+                        len=buffer.readFrom(in,max);
+                    }
+                    super._generator.completeUncheckedAddContent();
+                    _out.flush();
+                }
+                finally
+                {
+                    if (resource!=null)
+                        resource.release();
+                    else
+                        in.close();
+                }
+            }
+            else
+                throw new IllegalArgumentException("unknown content type?");
+
+
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class OutputWriter extends HttpWriter
+    {
+        OutputWriter()
+        {
+            super(AbstractHttpConnection.this._out);
+        }
+    }
+
+
+}
diff --git a/src/java/org/eclipse/jetty/server/AsyncContinuation.java b/src/java/org/eclipse/jetty/server/AsyncContinuation.java
new file mode 100644
index 0000000..d364156
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/AsyncContinuation.java
@@ -0,0 +1,1160 @@
+//
+//  ========================================================================
+//  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 javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationThrowable;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout;
+
+/* ------------------------------------------------------------ */
+/** Implementation of Continuation and AsyncContext interfaces
+ * 
+ */
+public class AsyncContinuation implements AsyncContext, Continuation
+{
+    private static final Logger LOG = Log.getLogger(AsyncContinuation.class);
+
+    private final static long DEFAULT_TIMEOUT=30000L;
+    
+    private final static ContinuationThrowable __exception = new ContinuationThrowable();
+    
+    // STATES:
+    //               handling()    suspend()     unhandle()    resume()       complete()  doComplete()
+    //                             startAsync()                dispatch()   
+    // IDLE          DISPATCHED      
+    // DISPATCHED                  ASYNCSTARTED  UNCOMPLETED
+    // ASYNCSTARTED                              ASYNCWAIT     REDISPATCHING  COMPLETING
+    // REDISPATCHING                             REDISPATCHED  
+    // ASYNCWAIT                                               REDISPATCH     COMPLETING
+    // REDISPATCH    REDISPATCHED
+    // REDISPATCHED                ASYNCSTARTED  UNCOMPLETED
+    // COMPLETING    UNCOMPLETED                 UNCOMPLETED
+    // UNCOMPLETED                                                                        COMPLETED
+    // COMPLETED
+    private static final int __IDLE=0;         // Idle request
+    private static final int __DISPATCHED=1;   // Request dispatched to filter/servlet
+    private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container
+    private static final int __REDISPATCHING=3;// resumed while dispatched
+    private static final int __ASYNCWAIT=4;    // Suspended and parked
+    private static final int __REDISPATCH=5;   // Has been scheduled
+    private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet
+    private static final int __COMPLETING=7;   // complete while dispatched
+    private static final int __UNCOMPLETED=8;  // Request is completable
+    private static final int __COMPLETED=9;    // Request is complete
+    
+    /* ------------------------------------------------------------ */
+    protected AbstractHttpConnection _connection;
+    private List<AsyncListener> _lastAsyncListeners;
+    private List<AsyncListener> _asyncListeners;
+    private List<ContinuationListener> _continuationListeners;
+
+    /* ------------------------------------------------------------ */
+    private int _state;
+    private boolean _initial;
+    private boolean _resumed;
+    private boolean _expired;
+    private volatile boolean _responseWrapped;
+    private long _timeoutMs=DEFAULT_TIMEOUT;
+    private AsyncEventState _event;
+    private volatile long _expireAt;    
+    private volatile boolean _continuation;
+    
+    /* ------------------------------------------------------------ */
+    protected AsyncContinuation()
+    {
+        _state=__IDLE;
+        _initial=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void setConnection(final AbstractHttpConnection connection)
+    {
+        synchronized(this)
+        {
+            _connection=connection;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addListener(AsyncListener listener)
+    {
+        synchronized(this)
+        {
+            if (_asyncListeners==null)
+                _asyncListeners=new ArrayList<AsyncListener>();
+            _asyncListeners.add(listener);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addListener(AsyncListener listener,ServletRequest request, ServletResponse response)
+    {
+        synchronized(this)
+        {
+            // TODO handle the request/response ???
+            if (_asyncListeners==null)
+                _asyncListeners=new ArrayList<AsyncListener>();
+            _asyncListeners.add(listener);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addContinuationListener(ContinuationListener listener)
+    {
+        synchronized(this)
+        {
+            if (_continuationListeners==null)
+                _continuationListeners=new ArrayList<ContinuationListener>();
+            _continuationListeners.add(listener);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setTimeout(long ms)
+    {
+        synchronized(this)
+        {
+            _timeoutMs=ms;
+        }
+    } 
+
+    /* ------------------------------------------------------------ */
+    public long getTimeout()
+    {
+        synchronized(this)
+        {
+            return _timeoutMs;
+        }
+    } 
+
+    /* ------------------------------------------------------------ */
+    public AsyncEventState getAsyncEventState()
+    {
+        synchronized(this)
+        {
+            return _event;
+        }
+    } 
+   
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#keepWrappers()
+     */
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped()
+     */
+    public boolean isResponseWrapped()
+    {
+        return _responseWrapped;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#isInitial()
+     */
+    public boolean isInitial()
+    {
+        synchronized(this)
+        {
+            return _initial;
+        }
+    }
+    
+    public boolean isContinuation()
+    {
+        return _continuation;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#isSuspended()
+     */
+    public boolean isSuspended()
+    {
+        synchronized(this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                case __REDISPATCHING:
+                case __COMPLETING:
+                case __ASYNCWAIT:
+                    return true;
+                    
+                default:
+                    return false;   
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isSuspending()
+    {
+        synchronized(this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                case __ASYNCWAIT:
+                    return true;
+                    
+                default:
+                    return false;   
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isDispatchable()
+    {
+        synchronized(this)
+        {
+            switch(_state)
+            {
+                case __REDISPATCH:
+                case __REDISPATCHED:
+                case __REDISPATCHING:
+                case __COMPLETING:
+                    return true;
+                    
+                default:
+                    return false;   
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        synchronized (this)
+        {
+            return super.toString()+"@"+getStatusString();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getStatusString()
+    {
+        synchronized (this)
+        {
+            return
+            ((_state==__IDLE)?"IDLE":
+                (_state==__DISPATCHED)?"DISPATCHED":
+                    (_state==__ASYNCSTARTED)?"ASYNCSTARTED":
+                        (_state==__ASYNCWAIT)?"ASYNCWAIT":
+                            (_state==__REDISPATCHING)?"REDISPATCHING":
+                                (_state==__REDISPATCH)?"REDISPATCH":
+                                    (_state==__REDISPATCHED)?"REDISPATCHED":
+                                        (_state==__COMPLETING)?"COMPLETING":
+                                            (_state==__UNCOMPLETED)?"UNCOMPLETED":
+                                                (_state==__COMPLETED)?"COMPLETE":
+                                                    ("UNKNOWN?"+_state))+
+            (_initial?",initial":"")+
+            (_resumed?",resumed":"")+
+            (_expired?",expired":"");
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return false if the handling of the request should not proceed
+     */
+    protected boolean handling()
+    {
+        synchronized (this)
+        {
+            _continuation=false;
+            
+            switch(_state)
+            {
+                case __IDLE:
+                    _initial=true;
+                    _state=__DISPATCHED;
+                    if (_lastAsyncListeners!=null)
+                        _lastAsyncListeners.clear();
+                    if (_asyncListeners!=null)
+                        _asyncListeners.clear();
+                    else
+                    {
+                        _asyncListeners=_lastAsyncListeners;
+                        _lastAsyncListeners=null;
+                    }
+                    return true;
+                    
+                case __COMPLETING:
+                    _state=__UNCOMPLETED;
+                    return false;
+
+                case __ASYNCWAIT:
+                    return false;
+                    
+                case __REDISPATCH:
+                    _state=__REDISPATCHED;
+                    return true;
+
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#suspend(long)
+     */
+    private void doSuspend(final ServletContext context,
+            final ServletRequest request,
+            final ServletResponse response)
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __DISPATCHED:
+                case __REDISPATCHED:
+                    _resumed=false;
+                    _expired=false;
+
+                    if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext())
+                        _event=new AsyncEventState(context,request,response);
+                    else
+                    {
+                        _event._dispatchContext=null;
+                        _event._pathInContext=null;
+                    }
+                    _state=__ASYNCSTARTED;
+                    List<AsyncListener> recycle=_lastAsyncListeners;
+                    _lastAsyncListeners=_asyncListeners;
+                    _asyncListeners=recycle;
+                    if (_asyncListeners!=null)
+                        _asyncListeners.clear();
+                    break;
+
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+        
+        if (_lastAsyncListeners!=null)
+        {
+            for (AsyncListener listener : _lastAsyncListeners)
+            {
+                try
+                {
+                    listener.onStartAsync(_event);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn(e);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Signal that the HttpConnection has finished handling the request.
+     * For blocking connectors, this call may block if the request has
+     * been suspended (startAsync called).
+     * @return true if handling is complete, false if the request should 
+     * be handled again (eg because of a resume that happened before unhandle was called)
+     */
+    protected boolean unhandle()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __REDISPATCHED:
+                case __DISPATCHED:
+                    _state=__UNCOMPLETED;
+                    return true;
+
+                case __IDLE:
+                    throw new IllegalStateException(this.getStatusString());
+
+                case __ASYNCSTARTED:
+                    _initial=false;
+                    _state=__ASYNCWAIT;
+                    scheduleTimeout(); // could block and change state.
+                    if (_state==__ASYNCWAIT)
+                        return true;
+                    else if (_state==__COMPLETING)
+                    {
+                        _state=__UNCOMPLETED;
+                        return true;
+                    }         
+                    _initial=false;
+                    _state=__REDISPATCHED;
+                    return false; 
+
+                case __REDISPATCHING:
+                    _initial=false;
+                    _state=__REDISPATCHED;
+                    return false; 
+
+                case __COMPLETING:
+                    _initial=false;
+                    _state=__UNCOMPLETED;
+                    return true;
+
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dispatch()
+    {
+        boolean dispatch=false;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                    _state=__REDISPATCHING;
+                    _resumed=true;
+                    return;
+
+                case __ASYNCWAIT:
+                    dispatch=!_expired;
+                    _state=__REDISPATCH;
+                    _resumed=true;
+                    break;
+                    
+                case __REDISPATCH:
+                    return;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+        
+        if (dispatch)
+        {
+            cancelTimeout();
+            scheduleDispatch();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void expired()
+    {
+        final List<ContinuationListener> cListeners;
+        final List<AsyncListener> aListeners;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                case __ASYNCWAIT:
+                    cListeners=_continuationListeners;
+                    aListeners=_asyncListeners;
+                    break;
+                default:
+                    cListeners=null;
+                    aListeners=null;
+                    return;
+            }
+            _expired=true;
+        }
+        
+        if (aListeners!=null)
+        {
+            for (AsyncListener listener : aListeners)
+            {
+                try
+                {
+                    listener.onTimeout(_event);
+                }
+                catch(Exception e)
+                {
+                    LOG.debug(e);
+                    _connection.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
+                    break;
+                }
+            }
+        }
+        if (cListeners!=null)
+        {
+            for (ContinuationListener listener : cListeners)
+            {
+                try
+                {
+                    listener.onTimeout(this);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn(e);
+                }
+            }
+        }
+        
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                case __ASYNCWAIT:
+                    dispatch();
+                    break;
+                    
+                default:
+                    if (!_continuation)
+                        _expired=false;
+            }
+        }
+
+        scheduleDispatch();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#complete()
+     */
+    public void complete()
+    {
+        // just like resume, except don't set _resumed=true;
+        boolean dispatch=false;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __DISPATCHED:
+                case __REDISPATCHED:
+                    throw new IllegalStateException(this.getStatusString());
+
+                case __ASYNCSTARTED:
+                    _state=__COMPLETING;
+                    return;
+                    
+                case __ASYNCWAIT:
+                    _state=__COMPLETING;
+                    dispatch=!_expired;
+                    break;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+        
+        if (dispatch)
+        {
+            cancelTimeout();
+            scheduleDispatch();
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#complete()
+     */
+    public void errorComplete()
+    {
+        // just like complete except can overrule a prior dispatch call;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __REDISPATCHING:
+                case __ASYNCSTARTED:
+                    _state=__COMPLETING;
+                    _resumed=false;
+                    return;
+                    
+                case __COMPLETING:
+                    return;
+                    
+                default:
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException 
+    {
+        try
+        {
+            // TODO inject
+            return clazz.newInstance();
+        }
+        catch(Exception e)
+        {
+            throw new ServletException(e);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.ServletRequest#complete()
+     */
+    protected void doComplete(Throwable ex)
+    {
+        final List<ContinuationListener> cListeners;
+        final List<AsyncListener> aListeners;
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __UNCOMPLETED:
+                    _state=__COMPLETED;
+                    cListeners=_continuationListeners;
+                    aListeners=_asyncListeners;
+                    break;
+                    
+                default:
+                    cListeners=null;
+                    aListeners=null;
+                    throw new IllegalStateException(this.getStatusString());
+            }
+        }
+        
+        if (aListeners!=null)
+        {
+            for (AsyncListener listener : aListeners)
+            {
+                try
+                {
+                    if (ex!=null)
+                    {
+                        _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex);
+                        _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE,ex.getMessage());
+                        listener.onError(_event);
+                    }
+                    else
+                        listener.onComplete(_event);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn(e);
+                }
+            }
+        }
+        if (cListeners!=null)
+        {
+            for (ContinuationListener listener : cListeners)
+            {
+                try
+                {
+                    listener.onComplete(this);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn(e);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void recycle()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __DISPATCHED:
+                case __REDISPATCHED:
+                    throw new IllegalStateException(getStatusString());
+                default:
+                    _state=__IDLE;
+            }
+            _initial = true;
+            _resumed=false;
+            _expired=false;
+            _responseWrapped=false;
+            cancelTimeout();
+            _timeoutMs=DEFAULT_TIMEOUT;
+            _continuationListeners=null;
+        }
+    }    
+    
+    /* ------------------------------------------------------------ */
+    public void cancel()
+    {
+        synchronized (this)
+        {
+            cancelTimeout();
+            _continuationListeners=null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void scheduleDispatch()
+    {
+        EndPoint endp=_connection.getEndPoint();
+        if (!endp.isBlocking())
+        {
+            ((AsyncEndPoint)endp).asyncDispatch();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void scheduleTimeout()
+    {
+        EndPoint endp=_connection.getEndPoint();
+        if (_timeoutMs>0)
+        {
+            if (endp.isBlocking())
+            {
+                synchronized(this)
+                {
+                    _expireAt = System.currentTimeMillis()+_timeoutMs;
+                    long wait=_timeoutMs;
+                    while (_expireAt>0 && wait>0 && _connection.getServer().isRunning())
+                    {
+                        try
+                        {
+                            this.wait(wait);
+                        }
+                        catch (InterruptedException e)
+                        {
+                            LOG.ignore(e);
+                        }
+                        wait=_expireAt-System.currentTimeMillis();
+                    }
+
+                    if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning())
+                    {
+                        expired();
+                    }
+                }            
+            }
+            else
+            {
+                ((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void cancelTimeout()
+    {
+        EndPoint endp=_connection.getEndPoint();
+        if (endp.isBlocking())
+        {
+            synchronized(this)
+            {
+                _expireAt=0;
+                this.notifyAll();
+            }
+        }
+        else 
+        {
+            final AsyncEventState event=_event;
+            if (event!=null)
+            {
+                ((AsyncEndPoint)endp).cancelTimeout(event._timeout);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isCompleting()
+    {
+        synchronized (this)
+        {
+            return _state==__COMPLETING;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    boolean isUncompleted()
+    {
+        synchronized (this)
+        {
+            return _state==__UNCOMPLETED;
+        }
+    } 
+    
+    /* ------------------------------------------------------------ */
+    public boolean isComplete()
+    {
+        synchronized (this)
+        {
+            return _state==__COMPLETED;
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isAsyncStarted()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __ASYNCSTARTED:
+                case __REDISPATCHING:
+                case __REDISPATCH:
+                case __ASYNCWAIT:
+                    return true;
+
+                default:
+                    return false;
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isAsync()
+    {
+        synchronized (this)
+        {
+            switch(_state)
+            {
+                case __IDLE:
+                case __DISPATCHED:
+                case __UNCOMPLETED:
+                case __COMPLETED:
+                    return false;
+
+                default:
+                    return true;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dispatch(ServletContext context, String path)
+    {
+        _event._dispatchContext=context;
+        _event.setPath(path);
+        dispatch();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dispatch(String path)
+    {
+        _event.setPath(path);
+        dispatch();
+    }
+
+    /* ------------------------------------------------------------ */
+    public Request getBaseRequest()
+    {
+        return _connection.getRequest();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ServletRequest getRequest()
+    {
+        if (_event!=null)
+            return _event.getSuppliedRequest();
+        return _connection.getRequest();
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletResponse getResponse()
+    {
+        if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
+            return _event.getSuppliedResponse();
+        return _connection.getResponse();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void start(final Runnable run)
+    {
+        final AsyncEventState event=_event;
+        if (event!=null)
+        {
+            _connection.getServer().getThreadPool().dispatch(new Runnable()
+            {
+                public void run()
+                {
+                    ((Context)event.getServletContext()).getContextHandler().handle(run);
+                }
+            });
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean hasOriginalRequestAndResponse()
+    {
+        synchronized (this)
+        {
+            return (_event!=null && _event.getSuppliedRequest()==_connection._request && _event.getSuppliedResponse()==_connection._response);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public ContextHandler getContextHandler()
+    {
+        final AsyncEventState event=_event;
+        if (event!=null)
+            return ((Context)event.getServletContext()).getContextHandler();
+        return null;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Continuation#isResumed()
+     */
+    public boolean isResumed()
+    {
+        synchronized (this)
+        {
+            return _resumed;
+        }
+    }
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Continuation#isExpired()
+     */
+    public boolean isExpired()
+    {
+        synchronized (this)
+        {
+            return _expired;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Continuation#resume()
+     */
+    public void resume()
+    {
+        dispatch();
+    }
+    
+
+
+    /* ------------------------------------------------------------ */
+    protected void startAsync(final ServletContext context,
+            final ServletRequest request,
+            final ServletResponse response)
+    {
+        synchronized (this)
+        {
+            _responseWrapped=!(response instanceof Response);
+            doSuspend(context,request,response);
+            if (request instanceof HttpServletRequest)
+            {
+                _event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void startAsync()
+    {
+        _responseWrapped=false;
+        _continuation=false;
+        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());  
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Continuation#suspend()
+     */
+    public void suspend(ServletResponse response)
+    {
+        _continuation=true;
+        _responseWrapped=!(response instanceof Response);
+        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); 
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Continuation#suspend()
+     */
+    public void suspend()
+    {
+        _responseWrapped=false;
+        _continuation=true;
+        doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse());       
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getServletResponse()
+     */
+    public ServletResponse getServletResponse()
+    {
+        if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null)
+            return _event.getSuppliedResponse();
+        return _connection.getResponse();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _connection.getRequest().getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _connection.getRequest().removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _connection.getRequest().setAttribute(name,attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.continuation.Continuation#undispatch()
+     */
+    public void undispatch()
+    {
+        if (isSuspended())
+        {
+            if (LOG.isDebugEnabled())
+                throw new ContinuationThrowable();
+            else
+                throw __exception;
+        }
+        throw new IllegalStateException("!suspended");
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class AsyncTimeout extends Timeout.Task implements Runnable
+    {
+            @Override
+            public void expired()
+            {
+                AsyncContinuation.this.expired();
+            }
+
+            @Override
+            public void run()
+            {
+                AsyncContinuation.this.expired();
+            }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public class AsyncEventState extends AsyncEvent
+    {
+        private final ServletContext _suspendedContext;
+        private ServletContext _dispatchContext;
+        private String _pathInContext;
+        private Timeout.Task _timeout=  new AsyncTimeout();
+        
+        public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response)
+        {
+            super(AsyncContinuation.this, request,response);
+            _suspendedContext=context;
+            // Get the base request So we can remember the initial paths
+            Request r=_connection.getRequest();
+ 
+            // If we haven't been async dispatched before
+            if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null)
+            {
+                // We are setting these attributes during startAsync, when the spec implies that 
+                // they are only available after a call to AsyncContext.dispatch(...);
+                
+                // have we been forwarded before?
+                String uri=(String)r.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
+                if (uri!=null)
+                {
+                    r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri);
+                    r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
+                    r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH));
+                    r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getAttribute(RequestDispatcher.FORWARD_PATH_INFO));
+                    r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING));
+                }
+                else
+                {
+                    r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI());
+                    r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath());
+                    r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath());
+                    r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo());
+                    r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString());
+                }
+            }
+        }
+        
+        public ServletContext getSuspendedContext()
+        {
+            return _suspendedContext;
+        }
+        
+        public ServletContext getDispatchContext()
+        {
+            return _dispatchContext;
+        }
+        
+        public ServletContext getServletContext()
+        {
+            return _dispatchContext==null?_suspendedContext:_dispatchContext;
+        }
+        
+        public void setPath(String path)
+        {
+            _pathInContext=path;
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * @return The path in the context
+         */
+        public String getPath()
+        {
+            return _pathInContext;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/AsyncHttpConnection.java b/src/java/org/eclipse/jetty/server/AsyncHttpConnection.java
new file mode 100644
index 0000000..1feeabd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/AsyncHttpConnection.java
@@ -0,0 +1,220 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** Asychronous Server HTTP connection
+ *
+ */
+public class AsyncHttpConnection extends AbstractHttpConnection implements AsyncConnection
+{
+    private final static int NO_PROGRESS_INFO = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_INFO",100);
+    private final static int NO_PROGRESS_CLOSE = Integer.getInteger("org.mortbay.jetty.NO_PROGRESS_CLOSE",200);
+
+    private static final Logger LOG = Log.getLogger(AsyncHttpConnection.class);
+    private int _total_no_progress;
+    private final AsyncEndPoint _asyncEndp;
+    private boolean _readInterested = true;
+
+    public AsyncHttpConnection(Connector connector, EndPoint endpoint, Server server)
+    {
+        super(connector,endpoint,server);
+        _asyncEndp=(AsyncEndPoint)endpoint;
+    }
+
+    @Override
+    public Connection handle() throws IOException
+    {
+        Connection connection = this;
+        boolean some_progress=false;
+        boolean progress=true;
+
+        try
+        {
+            setCurrentConnection(this);
+
+            // don't check for idle while dispatched (unless blocking IO is done).
+            _asyncEndp.setCheckForIdle(false);
+
+
+            // While progress and the connection has not changed
+            while (progress && connection==this)
+            {
+                progress=false;
+                try
+                {
+                    // Handle resumed request
+                    if (_request._async.isAsync())
+                    {
+                       if (_request._async.isDispatchable())
+                           handleRequest();
+                    }
+                    // else Parse more input
+                    else if (!_parser.isComplete() && _parser.parseAvailable())
+                        progress=true;
+
+                    // Generate more output
+                    if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown() && !_request.getAsyncContinuation().isAsyncStarted())
+                        if (_generator.flushBuffer()>0)
+                            progress=true;
+
+                    // Flush output
+                    _endp.flush();
+
+                    // Has any IO been done by the endpoint itself since last loop
+                    if (_asyncEndp.hasProgressed())
+                        progress=true;
+                }
+                catch (HttpException e)
+                {
+                    if (LOG.isDebugEnabled())
+                    {
+                        LOG.debug("uri="+_uri);
+                        LOG.debug("fields="+_requestFields);
+                        LOG.debug(e);
+                    }
+                    progress=true;
+                    _generator.sendError(e.getStatus(), e.getReason(), null, true);
+                }
+                finally
+                {
+                    some_progress|=progress;
+                    //  Is this request/response round complete and are fully flushed?
+                    boolean parserComplete = _parser.isComplete();
+                    boolean generatorComplete = _generator.isComplete();
+                    boolean complete = parserComplete && generatorComplete;
+                    if (parserComplete)
+                    {
+                        if (generatorComplete)
+                        {
+                            // Reset the parser/generator
+                            progress=true;
+
+                            // look for a switched connection instance?
+                            if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
+                            {
+                                Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
+                                if (switched!=null)
+                                    connection=switched;
+                            }
+
+                            reset();
+
+                            // TODO Is this still required?
+                            if (!_generator.isPersistent() && !_endp.isOutputShutdown())
+                            {
+                                LOG.warn("Safety net oshut!!!  IF YOU SEE THIS, PLEASE RAISE BUGZILLA");
+                                _endp.shutdownOutput();
+                            }
+                        }
+                        else
+                        {
+                            // We have finished parsing, but not generating so
+                            // we must not be interested in reading until we
+                            // have finished generating and we reset the generator
+                            _readInterested = false;
+                            LOG.debug("Disabled read interest while writing response {}", _endp);
+                        }
+                    }
+
+                    if (!complete && _request.getAsyncContinuation().isAsyncStarted())
+                    {
+                        // The request is suspended, so even though progress has been made,
+                        // exit the while loop by setting progress to false
+                        LOG.debug("suspended {}",this);
+                        progress=false;
+                    }
+                }
+            }
+        }
+        finally
+        {
+            setCurrentConnection(null);
+
+            // If we are not suspended
+            if (!_request.getAsyncContinuation().isAsyncStarted())
+            {
+                // return buffers
+                _parser.returnBuffers();
+                _generator.returnBuffers();
+
+                // reenable idle checking unless request is suspended
+                _asyncEndp.setCheckForIdle(true);
+            }
+
+            // Safety net to catch spinning
+            if (some_progress)
+                _total_no_progress=0;
+            else
+            {
+                _total_no_progress++;
+                if (NO_PROGRESS_INFO>0 && _total_no_progress%NO_PROGRESS_INFO==0 && (NO_PROGRESS_CLOSE<=0 || _total_no_progress< NO_PROGRESS_CLOSE))
+                    LOG.info("EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this);
+                if (NO_PROGRESS_CLOSE>0 && _total_no_progress==NO_PROGRESS_CLOSE)
+                {
+                    LOG.warn("Closing EndPoint making no progress: "+_total_no_progress+" "+_endp+" "+this);
+                    if (_endp instanceof SelectChannelEndPoint)
+                        ((SelectChannelEndPoint)_endp).getChannel().close();
+                }
+            }
+        }
+        return connection;
+    }
+
+    public void onInputShutdown() throws IOException
+    {
+        // If we don't have a committed response and we are not suspended
+        if (_generator.isIdle() && !_request.getAsyncContinuation().isSuspended())
+        {
+            // then no more can happen, so close.
+            _endp.close();
+        }
+
+        // Make idle parser seek EOF
+        if (_parser.isIdle())
+            _parser.setPersistent(false);
+    }
+
+    @Override
+    public void reset()
+    {
+        _readInterested = true;
+        LOG.debug("Enabled read interest {}", _endp);
+        super.reset();
+    }
+
+    @Override
+    public boolean isSuspended()
+    {
+        return !_readInterested || super.isSuspended();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java b/src/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java
new file mode 100644
index 0000000..e9acf9b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/AsyncNCSARequestLog.java
@@ -0,0 +1,130 @@
+//
+//  ========================================================================
+//  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 org.eclipse.jetty.util.BlockingArrayQueue;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * An asynchronously writing NCSA Request Log
+ */
+public class AsyncNCSARequestLog extends NCSARequestLog
+{
+    private static final Logger LOG = Log.getLogger(AsyncNCSARequestLog.class);
+    private final BlockingQueue<String> _queue;
+    private transient WriterThread _thread;
+    private boolean _warnedFull;
+
+    public AsyncNCSARequestLog()
+    {
+        this(null,null);
+    }
+    
+    public AsyncNCSARequestLog(BlockingQueue<String> queue)
+    {
+        this(null,queue);
+    }
+
+    public AsyncNCSARequestLog(String filename)
+    {
+        this(filename,null);
+    }
+    
+    public AsyncNCSARequestLog(String filename,BlockingQueue<String> queue)
+    {
+        super(filename);
+        if (queue==null)
+            queue=new BlockingArrayQueue<String>(1024);
+        _queue=queue;
+    }
+
+    private class WriterThread extends Thread
+    {
+        WriterThread()
+        {
+            setName("AsyncNCSARequestLog@"+Integer.toString(AsyncNCSARequestLog.this.hashCode(),16));
+        }
+        
+        @Override
+        public void run()
+        {
+            while (isRunning())
+            {
+                try
+                {
+                    String log = _queue.poll(10,TimeUnit.SECONDS);
+                    if (log!=null)
+                        AsyncNCSARequestLog.super.write(log);
+                    
+                    while(!_queue.isEmpty())
+                    {
+                        log=_queue.poll();
+                        if (log!=null)
+                            AsyncNCSARequestLog.super.write(log);
+                    }
+                }
+                catch (IOException e)
+                {
+                    LOG.warn(e);
+                }
+                catch (InterruptedException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected synchronized void doStart() throws Exception
+    {
+        super.doStart();
+        _thread = new WriterThread();
+        _thread.start();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        _thread.interrupt();
+        _thread.join();
+        super.doStop();
+        _thread=null;
+    }
+
+    @Override
+    protected void write(String log) throws IOException
+    {
+        if (!_queue.offer(log))
+        {
+            if (_warnedFull)
+                LOG.warn("Log Queue overflow");
+            _warnedFull=true;
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/Authentication.java b/src/java/org/eclipse/jetty/server/Authentication.java
new file mode 100644
index 0000000..4729005
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Authentication.java
@@ -0,0 +1,155 @@
+//
+//  ========================================================================
+//  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 javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/* ------------------------------------------------------------ */
+/** The Authentication state of a request.
+ * <p>
+ * The Authentication state can be one of several sub-types that
+ * reflects where the request is in the many different authentication
+ * cycles. Authentication might not yet be checked or it might be checked
+ * and failed, checked and deferred or succeeded. 
+ * 
+ */
+public interface Authentication
+{
+    /* ------------------------------------------------------------ */
+    /** A successful Authentication with User information.
+     */
+    public interface User extends Authentication
+    {
+        String getAuthMethod();
+        UserIdentity getUserIdentity(); 
+        boolean isUserInRole(UserIdentity.Scope scope,String role);
+        void logout();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** A wrapped authentication with methods provide the
+     * wrapped request/response for use by the application
+     */
+    public interface Wrapped extends Authentication
+    {
+        HttpServletRequest getHttpServletRequest();
+        HttpServletResponse getHttpServletResponse();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** A deferred authentication with methods to progress 
+     * the authentication process.
+     */
+    public interface Deferred extends Authentication
+    {
+        /* ------------------------------------------------------------ */
+        /** Authenticate if possible without sending a challenge.
+         * This is used to check credentials that have been sent for 
+         * non-manditory authentication.
+         * @return The new Authentication state.
+         */
+        Authentication authenticate(ServletRequest request);
+
+        /* ------------------------------------------------------------ */
+        /** Authenticate and possibly send a challenge.
+         * This is used to initiate authentication for previously 
+         * non-manditory authentication.
+         * @return The new Authentication state.
+         */
+        Authentication authenticate(ServletRequest request,ServletResponse response);
+        
+        
+        /* ------------------------------------------------------------ */
+        /** Login with the LOGIN authenticator
+         * @param username
+         * @param password
+         * @return The new Authentication state
+         */
+        Authentication login(String username,Object password,ServletRequest request);
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /** Authentication Response sent state.
+     * Responses are sent by authenticators either to issue an
+     * authentication challenge or on successful authentication in
+     * order to redirect the user to the original URL.
+     */
+    public interface ResponseSent extends Authentication
+    { 
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** An Authentication Challenge has been sent.
+     */
+    public interface Challenge extends ResponseSent
+    { 
+    }
+
+    /* ------------------------------------------------------------ */
+    /** An Authentication Failure has been sent.
+     */
+    public interface Failure extends ResponseSent
+    { 
+    }
+
+    public interface SendSuccess extends ResponseSent
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Unauthenticated state.
+     * <p> 
+     * This convenience instance is for non mandatory authentication where credentials
+     * have been presented and checked, but failed authentication. 
+     */
+    public final static Authentication UNAUTHENTICATED = new Authentication(){@Override
+    public String toString(){return "UNAUTHENTICATED";}};
+
+    /* ------------------------------------------------------------ */
+    /** Authentication not checked
+     * <p>
+     * This convenience instance us for non mandatory authentication when no 
+     * credentials are present to be checked.
+     */
+    public final static Authentication NOT_CHECKED = new Authentication(){@Override
+    public String toString(){return "NOT CHECKED";}};
+
+    /* ------------------------------------------------------------ */
+    /** Authentication challenge sent.
+     * <p>
+     * This convenience instance is for when an authentication challenge has been sent.
+     */
+    public final static Authentication SEND_CONTINUE = new Authentication.Challenge(){@Override
+    public String toString(){return "CHALLENGE";}};
+
+    /* ------------------------------------------------------------ */
+    /** Authentication failure sent.
+     * <p>
+     * This convenience instance is for when an authentication failure has been sent.
+     */
+    public final static Authentication SEND_FAILURE = new Authentication.Failure(){@Override
+    public String toString(){return "FAILURE";}};
+    public final static Authentication SEND_SUCCESS = new SendSuccess(){@Override
+    public String toString(){return "SEND_SUCCESS";}};
+}
diff --git a/src/java/org/eclipse/jetty/server/BlockingHttpConnection.java b/src/java/org/eclipse/jetty/server/BlockingHttpConnection.java
new file mode 100644
index 0000000..cc0d7e1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/BlockingHttpConnection.java
@@ -0,0 +1,138 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+
+import org.eclipse.jetty.http.Generator;
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.Parser;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** Blocking Server HTTP Connection
+ */
+public class BlockingHttpConnection extends AbstractHttpConnection
+{
+    private static final Logger LOG = Log.getLogger(BlockingHttpConnection.class);
+
+    public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server)
+    {
+        super(connector,endpoint,server);
+    }
+
+    public BlockingHttpConnection(Connector connector, EndPoint endpoint, Server server, Parser parser, Generator generator, Request request)
+    {
+        super(connector,endpoint,server,parser,generator,request);
+    }
+
+    @Override
+    protected void handleRequest() throws IOException
+    {
+        super.handleRequest();
+    }
+
+    public Connection handle() throws IOException
+    {
+        Connection connection = this;
+
+        try
+        {
+            setCurrentConnection(this);
+
+            // do while the endpoint is open
+            // AND the connection has not changed
+            while (_endp.isOpen() && connection==this)
+            {
+                try
+                {
+                    // If we are not ended then parse available
+                    if (!_parser.isComplete() && !_endp.isInputShutdown())
+                        _parser.parseAvailable();
+
+                    // Do we have more generating to do?
+                    // Loop here because some writes may take multiple steps and
+                    // we need to flush them all before potentially blocking in the
+                    // next loop.
+                    if (_generator.isCommitted() && !_generator.isComplete() && !_endp.isOutputShutdown())
+                        _generator.flushBuffer();
+
+                    // Flush buffers
+                    _endp.flush();
+                }
+                catch (HttpException e)
+                {
+                    if (LOG.isDebugEnabled())
+                    {
+                        LOG.debug("uri="+_uri);
+                        LOG.debug("fields="+_requestFields);
+                        LOG.debug(e);
+                    }
+                    _generator.sendError(e.getStatus(), e.getReason(), null, true);
+                    _parser.reset();
+                    _endp.shutdownOutput();
+                }
+                finally
+                {
+                    //  Is this request/response round complete and are fully flushed?
+                    if (_parser.isComplete() && _generator.isComplete())
+                    {
+                        // Reset the parser/generator
+                        reset();
+
+                        // look for a switched connection instance?
+                        if (_response.getStatus()==HttpStatus.SWITCHING_PROTOCOLS_101)
+                        {
+                            Connection switched=(Connection)_request.getAttribute("org.eclipse.jetty.io.Connection");
+                            if (switched!=null)
+                                connection=switched;
+                        }
+
+                        // TODO Is this required?
+                        if (!_generator.isPersistent() && !_endp.isOutputShutdown())
+                        {
+                            LOG.warn("Safety net oshut!!! Please open a bugzilla");
+                            _endp.shutdownOutput();
+                        }
+                    }
+                    
+                    // If we don't have a committed response and we are not suspended
+                    if (_endp.isInputShutdown() && _generator.isIdle() && !_request.getAsyncContinuation().isSuspended())
+                    {
+                        // then no more can happen, so close.
+                        _endp.close();
+                    }
+                }
+            }
+
+            return connection;
+        }
+        finally
+        {
+            setCurrentConnection(null);
+            _parser.returnBuffers();
+            _generator.returnBuffers();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/Connector.java b/src/java/org/eclipse/jetty/server/Connector.java
new file mode 100644
index 0000000..11cc290
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Connector.java
@@ -0,0 +1,387 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/** HTTP Connector.
+ * Implementations of this interface provide connectors for the HTTP protocol.
+ * A connector receives requests (normally from a socket) and calls the 
+ * handle method of the Handler object.  These operations are performed using
+ * threads from the ThreadPool set on the connector.
+ * 
+ * When a connector is registered with an instance of Server, then the server
+ * will set itself as both the ThreadPool and the Handler.  Note that a connector
+ * can be used without a Server if a thread pool and handler are directly provided.
+ * 
+ * 
+ * 
+ */
+/**
+ * @author gregw
+ *
+ */
+public interface Connector extends LifeCycle
+{ 
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the name of the connector. Defaults to the HostName:port
+     */
+    String getName();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Opens the connector 
+     * @throws IOException
+     */
+    void open() throws IOException;
+
+    /* ------------------------------------------------------------ */
+    void close() throws IOException;
+
+    /* ------------------------------------------------------------ */
+    void setServer(Server server);
+    
+    /* ------------------------------------------------------------ */
+    Server getServer();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the request header buffer size in bytes.
+     */
+    int getRequestHeaderSize();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the size of the buffer to be used for request headers.
+     * @param size The size in bytes.
+     */
+    void setRequestHeaderSize(int size);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the response header buffer size in bytes.
+     */
+    int getResponseHeaderSize();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the size of the buffer to be used for request headers.
+     * @param size The size in bytes.
+     */
+    void setResponseHeaderSize(int size);
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return factory for request buffers
+     */
+    Buffers getRequestBuffers();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return factory for response buffers
+     */
+    Buffers getResponseBuffers();
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the requestBufferSize.
+     */
+    int getRequestBufferSize();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the size of the content buffer for receiving requests. 
+     * These buffers are only used for active connections that have
+     * requests with bodies that will not fit within the header buffer.
+     * @param requestBufferSize The requestBufferSize to set.
+     */
+    void setRequestBufferSize(int requestBufferSize);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the responseBufferSize.
+     */
+    int getResponseBufferSize();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the size of the content buffer for sending responses. 
+     * These buffers are only used for active connections that are sending 
+     * responses with bodies that will not fit within the header buffer.
+     * @param responseBufferSize The responseBufferSize to set.
+     */
+    void setResponseBufferSize(int responseBufferSize);
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The port to use when redirecting a request if a data constraint of integral is 
+     * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
+     */
+    int getIntegralPort();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The schema to use when redirecting a request if a data constraint of integral is 
+     * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
+     */
+    String getIntegralScheme();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param request A request
+     * @return true if the request is integral. This normally means the https schema has been used.
+     */
+    boolean isIntegral(Request request);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The port to use when redirecting a request if a data constraint of confidential is 
+     * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
+     */
+    int getConfidentialPort();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The schema to use when redirecting a request if a data constraint of confidential is 
+     * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
+     */
+    String getConfidentialScheme();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param request A request
+     * @return true if the request is confidential. This normally means the https schema has been used.
+     */
+    boolean isConfidential(Request request);
+
+    /* ------------------------------------------------------------ */
+    /** Customize a request for an endpoint.
+     * Called on every request to allow customization of the request for
+     * the particular endpoint (eg security properties from a SSL connection).
+     * @param endpoint
+     * @param request
+     * @throws IOException
+     */
+    void customize(EndPoint endpoint, Request request) throws IOException;
+
+    /* ------------------------------------------------------------ */
+    /** Persist an endpoint.
+     * Called after every request if the connection is to remain open.
+     * @param endpoint
+     * @throws IOException
+     */
+    void persist(EndPoint endpoint) throws IOException;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The hostname representing the interface to which 
+     * this connector will bind, or null for all interfaces.
+     */
+    String getHost();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the hostname of the interface to bind to.
+     * @param hostname The hostname representing the interface to which 
+     * this connector will bind, or null for all interfaces.
+     */
+    void setHost(String hostname);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param port The port to listen of for connections or 0 if any available
+     * port may be used.
+     */
+    void setPort(int port);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The configured port for the connector or 0 if any available
+     * port may be used.
+     */
+    int getPort();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The actual port the connector is listening on or
+     * -1 if it has not been opened, or -2 if it has been closed.
+     */
+    int getLocalPort();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Max Idle time for connections in milliseconds
+     */
+    int getMaxIdleTime();
+    
+    /**
+     * @param ms Max Idle time for connections in milliseconds
+     */
+    void setMaxIdleTime(int ms);
+    
+    /* ------------------------------------------------------------ */
+    int getLowResourceMaxIdleTime();
+    void setLowResourceMaxIdleTime(int ms);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the underlying socket, channel, buffer etc. for the connector.
+     */
+    Object getConnection();
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if names resolution should be done.
+     */
+    boolean getResolveNames();
+    
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Get the number of requests handled by this connector
+     * since last call of statsReset(). If setStatsOn(false) then this
+     * is undefined.
+     */
+    public int getRequests();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the connectionsDurationTotal.
+     */
+    public long getConnectionsDurationTotal();
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Number of connections accepted by the server since
+     * statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnections() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Number of connections currently open that were opened
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsOpen() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Maximum number of connections opened simultaneously
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsOpenMax() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Maximum duration in milliseconds of an open connection
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public long getConnectionsDurationMax();
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Mean duration in milliseconds of open connections
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsDurationMean() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Standard deviation of duration in milliseconds of
+     * open connections since statsReset() called. Undefined if
+     * setStatsOn(false).
+     */
+    public double getConnectionsDurationStdDev() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Mean number of requests per connection
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsRequestsMean() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Standard Deviation of number of requests per connection
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public double getConnectionsRequestsStdDev() ;
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Maximum number of requests per connection
+     * since statsReset() called. Undefined if setStatsOn(false).
+     */
+    public int getConnectionsRequestsMax();
+
+    /* ------------------------------------------------------------ */
+    /** Reset statistics.
+     */
+    public void statsReset();
+    
+    /* ------------------------------------------------------------ */
+    public void setStatsOn(boolean on);
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return True if statistics collection is turned on.
+     */
+    public boolean getStatsOn();
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Timestamp stats were started at.
+     */
+    public long getStatsOnMs();
+    
+
+    /* ------------------------------------------------------------ */
+    /** Check if low on resources.
+     * For most connectors, low resources is measured by calling 
+     * {@link ThreadPool#isLowOnThreads()} on the connector threadpool
+     * or the server threadpool if there is no connector threadpool.
+     * <p>
+     * For blocking connectors, low resources is used to trigger
+     * usage of {@link #getLowResourceMaxIdleTime()} for the timeout
+     * of an idle connection.
+     * <p>
+     * for non-blocking connectors, the number of connections is
+     * used instead of this method, to select the timeout of an 
+     * idle connection.
+     * <p>
+     * For all connectors, low resources is used to trigger the 
+     * usage of {@link #getLowResourceMaxIdleTime()} for read and 
+     * write operations.
+     * 
+     * @return true if this connector is low on resources.
+     */
+    public boolean isLowResources();
+}
diff --git a/src/java/org/eclipse/jetty/server/CookieCutter.java b/src/java/org/eclipse/jetty/server/CookieCutter.java
new file mode 100644
index 0000000..53d3773
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/CookieCutter.java
@@ -0,0 +1,335 @@
+//
+//  ========================================================================
+//  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.Locale;
+
+import javax.servlet.http.Cookie;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** Cookie parser
+ * <p>Optimized stateful cookie parser.  Cookies fields are added with the
+ * {@link #addCookieField(String)} method and parsed on the next subsequent
+ * call to {@link #getCookies()}.
+ * If the added fields are identical to those last added (as strings), then the 
+ * cookies are not re parsed.
+ * 
+ *
+ */
+public class CookieCutter
+{
+    private static final Logger LOG = Log.getLogger(CookieCutter.class);
+
+
+    private Cookie[] _cookies;
+    private Cookie[] _lastCookies;
+    Object _lazyFields;
+    int _fields;
+    
+    public CookieCutter()
+    {  
+    }
+    
+    public Cookie[] getCookies()
+    {
+        if (_cookies!=null)
+            return _cookies;
+        
+        if (_lastCookies!=null &&
+            _lazyFields!=null &&
+            _fields==LazyList.size(_lazyFields))
+            _cookies=_lastCookies;
+        else
+            parseFields();
+        _lastCookies=_cookies;
+        return _cookies;
+    }
+    
+    public void setCookies(Cookie[] cookies)
+    {
+        _cookies=cookies;
+        _lastCookies=null;
+        _lazyFields=null;
+        _fields=0;
+    }
+    
+    public void reset()
+    {
+        _cookies=null;
+        _fields=0;
+    }
+    
+    public void addCookieField(String f)
+    {
+        if (f==null)
+            return;
+        f=f.trim();
+        if (f.length()==0)
+            return;
+            
+        if (LazyList.size(_lazyFields)>_fields)
+        {
+            if (f.equals(LazyList.get(_lazyFields,_fields)))
+            {
+                _fields++;
+                return;
+            }
+            
+            while (LazyList.size(_lazyFields)>_fields)
+                _lazyFields=LazyList.remove(_lazyFields,_fields);
+        }
+        _cookies=null;
+        _lastCookies=null;
+        _lazyFields=LazyList.add(_lazyFields,_fields++,f);
+    }
+    
+    
+    protected void parseFields()
+    {
+        _lastCookies=null;
+        _cookies=null;
+        
+        Object cookies = null;
+
+        int version = 0;
+
+        // delete excess fields
+        while (LazyList.size(_lazyFields)>_fields)
+            _lazyFields=LazyList.remove(_lazyFields,_fields);
+        
+        // For each cookie field
+        for (int f=0;f<_fields;f++)
+        {
+            String hdr = LazyList.get(_lazyFields,f);
+            
+            // Parse the header
+            String name = null;
+            String value = null;
+
+            Cookie cookie = null;
+
+            boolean invalue=false;
+            boolean quoted=false;
+            boolean escaped=false;
+            int tokenstart=-1;
+            int tokenend=-1;
+            for (int i = 0, length = hdr.length(), last=length-1; i < length; i++)
+            {
+                char c = hdr.charAt(i);
+                
+                // Handle quoted values for name or value
+                if (quoted)
+                {
+                    if (escaped)
+                    {
+                        escaped=false;
+                        continue;
+                    }
+                    
+                    switch (c)
+                    {
+                        case '"':
+                            tokenend=i;
+                            quoted=false;
+
+                            // handle quote as last character specially
+                            if (i==last)
+                            {
+                                if (invalue)
+                                    value = hdr.substring(tokenstart, tokenend+1);
+                                else
+                                {
+                                    name = hdr.substring(tokenstart, tokenend+1);
+                                    value = "";
+                                }
+                            }
+                            break;
+                            
+                        case '\\':
+                            escaped=true;
+                            continue;
+                        default:
+                            continue;
+                    }
+                }
+                else
+                {
+                    // Handle name and value state machines
+                    if (invalue)
+                    {
+                        // parse the value
+                        switch (c)
+                        {
+                            case ' ':
+                            case '\t':
+                                continue;
+                                
+                            case '"':
+                                if (tokenstart<0)
+                                {
+                                    quoted=true;
+                                    tokenstart=i;
+                                }
+                                tokenend=i;
+                                if (i==last)
+                                {
+                                    value = hdr.substring(tokenstart, tokenend+1);
+                                    break;
+                                }
+                                continue;
+
+                            case ';':
+                            // case ',':
+                                if (tokenstart>=0)
+                                    value = hdr.substring(tokenstart, tokenend+1);
+                                else
+                                    value="";
+                                tokenstart = -1;
+                                invalue=false;
+                                break;
+                                
+                            default:
+                                if (tokenstart<0)
+                                    tokenstart=i;
+                                tokenend=i;
+                                if (i==last)
+                                {
+                                    value = hdr.substring(tokenstart, tokenend+1);
+                                    break;
+                                }
+                                continue;
+                        }
+                    }
+                    else
+                    {
+                        // parse the name
+                        switch (c)
+                        {
+                            case ' ':
+                            case '\t':
+                                continue;
+                                
+                            case '"':
+                                if (tokenstart<0)
+                                {
+                                    quoted=true;
+                                    tokenstart=i;
+                                }
+                                tokenend=i;
+                                if (i==last)
+                                {
+                                    name = hdr.substring(tokenstart, tokenend+1);
+                                    value = "";
+                                    break;
+                                }
+                                continue;
+
+                            case ';':
+                            // case ',':
+                                if (tokenstart>=0)
+                                {
+                                    name = hdr.substring(tokenstart, tokenend+1);
+                                    value = "";
+                                }
+                                tokenstart = -1;
+                                break;
+
+                            case '=':
+                                if (tokenstart>=0)
+                                    name = hdr.substring(tokenstart, tokenend+1);
+                                tokenstart = -1;
+                                invalue=true;
+                                continue;
+                                
+                            default:
+                                if (tokenstart<0)
+                                    tokenstart=i;
+                                tokenend=i;
+                                if (i==last)
+                                {
+                                    name = hdr.substring(tokenstart, tokenend+1);
+                                    value = "";
+                                    break;
+                                }
+                                continue;
+                        }
+                    }
+                }
+
+                // If after processing the current character we have a value and a name, then it is a cookie
+                if (value!=null && name!=null)
+                {
+                    // TODO handle unquoting during parsing!  But quoting is uncommon
+                    name=QuotedStringTokenizer.unquoteOnly(name);
+                    value=QuotedStringTokenizer.unquoteOnly(value);
+                    
+                    try
+                    {
+                        if (name.startsWith("$"))
+                        {
+                            String lowercaseName = name.toLowerCase(Locale.ENGLISH);
+                            if ("$path".equals(lowercaseName))
+                            {
+                                if (cookie!=null)
+                                    cookie.setPath(value);
+                            }
+                            else if ("$domain".equals(lowercaseName))
+                            {
+                                if (cookie!=null)
+                                    cookie.setDomain(value);
+                            }
+                            else if ("$port".equals(lowercaseName))
+                            {
+                                if (cookie!=null)
+                                    cookie.setComment("$port="+value);
+                            }
+                            else if ("$version".equals(lowercaseName))
+                            {
+                                version = Integer.parseInt(value);
+                            }
+                        }
+                        else
+                        {
+                            cookie = new Cookie(name, value);
+                            if (version > 0)
+                                cookie.setVersion(version);
+                            cookies = LazyList.add(cookies, cookie);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        LOG.debug(e);
+                    }
+
+                    name = null;
+                    value = null;
+                }
+            }
+        }
+
+        _cookies = (Cookie[]) LazyList.toArray(cookies,Cookie.class);
+        _lastCookies=_cookies;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/Dispatcher.java b/src/java/org/eclipse/jetty/server/Dispatcher.java
new file mode 100644
index 0000000..7c058a8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Dispatcher.java
@@ -0,0 +1,550 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.UrlEncoded;
+
+/* ------------------------------------------------------------ */
+/** Servlet RequestDispatcher.
+ * 
+ * 
+ */
+public class Dispatcher implements RequestDispatcher
+{
+    /** Dispatch include attribute names */
+    public final static String __INCLUDE_PREFIX="javax.servlet.include.";
+
+    /** Dispatch include attribute names */
+    public final static String __FORWARD_PREFIX="javax.servlet.forward.";
+
+    /** JSP attributes */
+    public final static String __JSP_FILE="org.apache.catalina.jsp_file";
+
+    /* ------------------------------------------------------------ */
+    private final ContextHandler _contextHandler;
+    private final String _uri;
+    private final String _path;
+    private final String _dQuery;
+    private final String _named;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param contextHandler
+     * @param uri
+     * @param pathInContext
+     * @param query
+     */
+    public Dispatcher(ContextHandler contextHandler, String uri, String pathInContext, String query)
+    {
+        _contextHandler=contextHandler;
+        _uri=uri;
+        _path=pathInContext;
+        _dQuery=query;
+        _named=null;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param contextHandler
+     * @param name
+     */
+    public Dispatcher(ContextHandler contextHandler,String name)
+        throws IllegalStateException
+    {
+        _contextHandler=contextHandler;
+        _named=name;
+        _uri=null;
+        _path=null;
+        _dQuery=null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
+    {
+        forward(request, response, DispatcherType.FORWARD);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    public void error(ServletRequest request, ServletResponse response) throws ServletException, IOException
+    {
+        forward(request, response, DispatcherType.ERROR);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
+    {
+        Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+      
+        
+        if (!(request instanceof HttpServletRequest))
+            request = new ServletRequestHttpWrapper(request);
+        if (!(response instanceof HttpServletResponse))
+            response = new ServletResponseHttpWrapper(response);
+            
+        
+        // TODO - allow stream or writer????
+        
+        final DispatcherType old_type = baseRequest.getDispatcherType();
+        final Attributes old_attr=baseRequest.getAttributes();
+        MultiMap old_params=baseRequest.getParameters();
+        try
+        {
+            baseRequest.setDispatcherType(DispatcherType.INCLUDE);
+            baseRequest.getConnection().include();
+            if (_named!=null)
+                _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
+            else 
+            {
+                String query=_dQuery;
+                
+                if (query!=null)
+                {
+                    // force parameter extraction
+                    if (old_params==null)
+                    {
+                        baseRequest.extractParameters();
+                        old_params=baseRequest.getParameters();
+                    }
+                    
+                    MultiMap parameters=new MultiMap();
+                    UrlEncoded.decodeTo(query,parameters,baseRequest.getCharacterEncoding());
+                    
+                    if (old_params!=null && old_params.size()>0)
+                    {
+                        // Merge parameters.
+                        Iterator iter = old_params.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));
+                        }
+                    }
+                    baseRequest.setParameters(parameters);
+                }
+                
+                IncludeAttributes attr = new IncludeAttributes(old_attr); 
+                
+                attr._requestURI=_uri;
+                attr._contextPath=_contextHandler.getContextPath();
+                attr._servletPath=null; // set by ServletHandler
+                attr._pathInfo=_path;
+                attr._query=query;
+                
+                baseRequest.setAttributes(attr);
+                
+                _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
+            }
+        }
+        finally
+        {
+            baseRequest.setAttributes(old_attr);
+            baseRequest.getConnection().included();
+            baseRequest.setParameters(old_params);
+            baseRequest.setDispatcherType(old_type);
+        }
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException
+    {
+        Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+        Response base_response=baseRequest.getResponse();
+        response.resetBuffer();
+        base_response.fwdReset();
+       
+
+        if (!(request instanceof HttpServletRequest))
+            request = new ServletRequestHttpWrapper(request);
+        if (!(response instanceof HttpServletResponse))
+            response = new ServletResponseHttpWrapper(response);
+        
+        final boolean old_handled=baseRequest.isHandled();
+        final String old_uri=baseRequest.getRequestURI();
+        final String old_context_path=baseRequest.getContextPath();
+        final String old_servlet_path=baseRequest.getServletPath();
+        final String old_path_info=baseRequest.getPathInfo();
+        final String old_query=baseRequest.getQueryString();
+        final Attributes old_attr=baseRequest.getAttributes();
+        final DispatcherType old_type=baseRequest.getDispatcherType();
+        MultiMap<String> old_params=baseRequest.getParameters();
+        
+        try
+        {
+            baseRequest.setHandled(false);
+            baseRequest.setDispatcherType(dispatch);
+            
+            if (_named!=null)
+                _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
+            else 
+            {
+                
+                // process any query string from the dispatch URL
+                String query=_dQuery;
+                if (query!=null)
+                {
+                    // force parameter extraction
+                    if (old_params==null)
+                    {
+                        baseRequest.extractParameters();
+                        old_params=baseRequest.getParameters();
+                    }
+                    
+                    baseRequest.mergeQueryString(query);
+                }
+                
+                ForwardAttributes attr = new ForwardAttributes(old_attr); 
+                
+                //If we have already been forwarded previously, then keep using the established 
+                //original value. Otherwise, this is the first forward and we need to establish the values.
+                //Note: the established value on the original request for pathInfo and
+                //for queryString is allowed to be null, but cannot be null for the other values.
+                if (old_attr.getAttribute(FORWARD_REQUEST_URI) != null)
+                {
+                    attr._pathInfo=(String)old_attr.getAttribute(FORWARD_PATH_INFO);
+                    attr._query=(String)old_attr.getAttribute(FORWARD_QUERY_STRING);
+                    attr._requestURI=(String)old_attr.getAttribute(FORWARD_REQUEST_URI);
+                    attr._contextPath=(String)old_attr.getAttribute(FORWARD_CONTEXT_PATH);
+                    attr._servletPath=(String)old_attr.getAttribute(FORWARD_SERVLET_PATH);
+                }
+                else
+                {
+                    attr._pathInfo=old_path_info;
+                    attr._query=old_query;
+                    attr._requestURI=old_uri;
+                    attr._contextPath=old_context_path;
+                    attr._servletPath=old_servlet_path;
+                }     
+                
+                baseRequest.setRequestURI(_uri);
+                baseRequest.setContextPath(_contextHandler.getContextPath());
+                baseRequest.setServletPath(null);
+                baseRequest.setPathInfo(_uri);
+                baseRequest.setAttributes(attr);
+                
+                _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response);
+                
+                if (!baseRequest.getAsyncContinuation().isAsyncStarted())
+                    commitResponse(response,baseRequest);
+            }
+        }
+        finally
+        {
+            baseRequest.setHandled(old_handled);
+            baseRequest.setRequestURI(old_uri);
+            baseRequest.setContextPath(old_context_path);
+            baseRequest.setServletPath(old_servlet_path);
+            baseRequest.setPathInfo(old_path_info);
+            baseRequest.setAttributes(old_attr);
+            baseRequest.setParameters(old_params);
+            baseRequest.setQueryString(old_query);
+            baseRequest.setDispatcherType(old_type);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private void commitResponse(ServletResponse response, Request baseRequest) throws IOException
+    {
+        if (baseRequest.getResponse().isWriting())
+        {
+            try
+            {
+                response.getWriter().close();
+            }
+            catch (IllegalStateException e)
+            {
+                response.getOutputStream().close();
+            }
+        }
+        else
+        {
+            try
+            {
+                response.getOutputStream().close();
+            }
+            catch (IllegalStateException e)
+            {
+                response.getWriter().close();
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class ForwardAttributes implements Attributes
+    {
+        final Attributes _attr;
+        
+        String _requestURI;
+        String _contextPath;
+        String _servletPath;
+        String _pathInfo;
+        String _query;
+        
+        ForwardAttributes(Attributes attributes)
+        {
+            _attr=attributes;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public Object getAttribute(String key)
+        {
+            if (Dispatcher.this._named==null)
+            {
+                if (key.equals(FORWARD_PATH_INFO))    
+                    return _pathInfo;
+                if (key.equals(FORWARD_REQUEST_URI))  
+                    return _requestURI;
+                if (key.equals(FORWARD_SERVLET_PATH)) 
+                    return _servletPath;
+                if (key.equals(FORWARD_CONTEXT_PATH)) 
+                    return _contextPath;
+                if (key.equals(FORWARD_QUERY_STRING)) 
+                    return _query;
+            }
+            
+            if (key.startsWith(__INCLUDE_PREFIX))
+                return null;
+            
+            return _attr.getAttribute(key);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public Enumeration getAttributeNames()
+        {
+            HashSet set=new HashSet();
+            Enumeration e=_attr.getAttributeNames();
+            while(e.hasMoreElements())
+            {
+                String name=(String)e.nextElement();
+                if (!name.startsWith(__INCLUDE_PREFIX) &&
+                    !name.startsWith(__FORWARD_PREFIX))
+                    set.add(name);
+            }
+            
+            if (_named==null)
+            {
+                if (_pathInfo!=null)
+                    set.add(FORWARD_PATH_INFO);
+                else
+                    set.remove(FORWARD_PATH_INFO);
+                set.add(FORWARD_REQUEST_URI);
+                set.add(FORWARD_SERVLET_PATH);
+                set.add(FORWARD_CONTEXT_PATH);
+                if (_query!=null)
+                    set.add(FORWARD_QUERY_STRING);
+                else
+                    set.remove(FORWARD_QUERY_STRING);
+            }
+
+            return Collections.enumeration(set);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public void setAttribute(String key, Object value)
+        {
+            if (_named==null && key.startsWith("javax.servlet."))
+            {
+                if (key.equals(FORWARD_PATH_INFO))         
+                    _pathInfo=(String)value;
+                else if (key.equals(FORWARD_REQUEST_URI))  
+                    _requestURI=(String)value;
+                else if (key.equals(FORWARD_SERVLET_PATH)) 
+                    _servletPath=(String)value;
+                else if (key.equals(FORWARD_CONTEXT_PATH)) 
+                    _contextPath=(String)value;
+                else if (key.equals(FORWARD_QUERY_STRING)) 
+                    _query=(String)value;
+                
+                else if (value==null)
+                    _attr.removeAttribute(key);
+                else
+                    _attr.setAttribute(key,value); 
+            }
+            else if (value==null)
+                _attr.removeAttribute(key);
+            else
+                _attr.setAttribute(key,value);
+        }
+        
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString() 
+        {
+            return "FORWARD+"+_attr.toString();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void clearAttributes()
+        {
+            throw new IllegalStateException();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void removeAttribute(String name)
+        {
+            setAttribute(name,null);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private class IncludeAttributes implements Attributes
+    {
+        final Attributes _attr;
+        
+        String _requestURI;
+        String _contextPath;
+        String _servletPath;
+        String _pathInfo;
+        String _query;
+        
+        IncludeAttributes(Attributes attributes)
+        {
+            _attr=attributes;
+        }
+        
+        /* ------------------------------------------------------------ */
+        /* ------------------------------------------------------------ */
+        /* ------------------------------------------------------------ */
+        public Object getAttribute(String key)
+        {
+            if (Dispatcher.this._named==null)
+            {
+                if (key.equals(INCLUDE_PATH_INFO))    return _pathInfo;
+                if (key.equals(INCLUDE_SERVLET_PATH)) return _servletPath;
+                if (key.equals(INCLUDE_CONTEXT_PATH)) return _contextPath;
+                if (key.equals(INCLUDE_QUERY_STRING)) return _query;
+                if (key.equals(INCLUDE_REQUEST_URI))  return _requestURI;
+            }
+            else if (key.startsWith(__INCLUDE_PREFIX)) 
+                    return null;
+            
+            
+            return _attr.getAttribute(key);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public Enumeration getAttributeNames()
+        {
+            HashSet set=new HashSet();
+            Enumeration e=_attr.getAttributeNames();
+            while(e.hasMoreElements())
+            {
+                String name=(String)e.nextElement();
+                if (!name.startsWith(__INCLUDE_PREFIX))
+                    set.add(name);
+            }
+            
+            if (_named==null)
+            {
+                if (_pathInfo!=null)
+                    set.add(INCLUDE_PATH_INFO);
+                else
+                    set.remove(INCLUDE_PATH_INFO);
+                set.add(INCLUDE_REQUEST_URI);
+                set.add(INCLUDE_SERVLET_PATH);
+                set.add(INCLUDE_CONTEXT_PATH);
+                if (_query!=null)
+                    set.add(INCLUDE_QUERY_STRING);
+                else
+                    set.remove(INCLUDE_QUERY_STRING);
+            }
+            
+            return Collections.enumeration(set);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public void setAttribute(String key, Object value)
+        {
+            if (_named==null && key.startsWith("javax.servlet."))
+            {
+                if (key.equals(INCLUDE_PATH_INFO))         _pathInfo=(String)value;
+                else if (key.equals(INCLUDE_REQUEST_URI))  _requestURI=(String)value;
+                else if (key.equals(INCLUDE_SERVLET_PATH)) _servletPath=(String)value;
+                else if (key.equals(INCLUDE_CONTEXT_PATH)) _contextPath=(String)value;
+                else if (key.equals(INCLUDE_QUERY_STRING)) _query=(String)value;
+                else if (value==null)
+                    _attr.removeAttribute(key);
+                else
+                    _attr.setAttribute(key,value); 
+            }
+            else if (value==null)
+                _attr.removeAttribute(key);
+            else
+                _attr.setAttribute(key,value);
+        }
+        
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString() 
+        {
+            return "INCLUDE+"+_attr.toString();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void clearAttributes()
+        {
+            throw new IllegalStateException();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void removeAttribute(String name)
+        {
+            setAttribute(name,null);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/Handler.java b/src/java/org/eclipse/jetty/server/Handler.java
new file mode 100644
index 0000000..cf56498
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Handler.java
@@ -0,0 +1,72 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.util.component.Destroyable;
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/* ------------------------------------------------------------ */
+/** A Jetty Server Handler.
+ * 
+ * A Handler instance is required by a {@link Server} to handle incoming
+ * HTTP requests.  A Handler may: <ul>
+ * <li>Completely generate the HTTP Response</li>
+ * <li>Examine/modify the request and call another Handler (see {@link HandlerWrapper}).
+ * <li>Pass the request to one or more other Handlers (see {@link HandlerCollection}).
+ * </ul>
+ * 
+ * Handlers are passed the servlet API request and response object, but are 
+ * not Servlets.  The servlet container is implemented by handlers for 
+ * context, security, session and servlet that modify the request object 
+ * before passing it to the next stage of handling.
+ * 
+ */
+public interface Handler extends LifeCycle, Destroyable
+{
+    /* ------------------------------------------------------------ */
+    /** Handle a request.
+     * @param target The target of the request - either a URI or a name.
+     * @param baseRequest The original unwrapped request object.
+     * @param request The request either as the {@link Request}
+     * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()} 
+     * method can be used access the Request object if required.
+     * @param response The response as the {@link Response}
+     * object or a wrapper of that request. The {@link AbstractHttpConnection#getCurrentConnection()} 
+     * method can be used access the Response object if required.
+     * @throws IOException
+     * @throws ServletException
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException;
+    
+    public void setServer(Server server);
+    public Server getServer();
+    
+    public void destroy();
+    
+}
+
diff --git a/src/java/org/eclipse/jetty/server/HandlerContainer.java b/src/java/org/eclipse/jetty/server/HandlerContainer.java
new file mode 100644
index 0000000..4f9085e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/HandlerContainer.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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 org.eclipse.jetty.util.component.LifeCycle;
+
+/**
+ * A Handler that contains other Handlers.
+ * <p>
+ * The contained handlers may be one (see @{link {@link org.eclipse.jetty.server.handler.HandlerWrapper})
+ * or many (see {@link org.eclipse.jetty.server.handler.HandlerList} or {@link org.eclipse.jetty.server.handler.HandlerCollection}. 
+ *
+ */
+public interface HandlerContainer extends LifeCycle
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * @return array of handlers directly contained by this handler.
+     */
+    public Handler[] getHandlers();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return array of all handlers contained by this handler and it's children
+     */
+    public Handler[] getChildHandlers();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param byclass
+     * @return array of all handlers contained by this handler and it's children of the passed type.
+     */
+    public Handler[] getChildHandlersByClass(Class<?> byclass);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param byclass
+     * @return first handler of all handlers contained by this handler and it's children of the passed type.
+     */
+    public <T extends Handler> T getChildHandlerByClass(Class<T> byclass);
+}
diff --git a/src/java/org/eclipse/jetty/server/HttpInput.java b/src/java/org/eclipse/jetty/server/HttpInput.java
new file mode 100644
index 0000000..e0d48fc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/HttpInput.java
@@ -0,0 +1,75 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+
+import javax.servlet.ServletInputStream;
+
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EofException;
+
+public class HttpInput extends ServletInputStream
+{
+    protected final AbstractHttpConnection _connection;
+    protected final HttpParser _parser;
+
+    /* ------------------------------------------------------------ */
+    public HttpInput(AbstractHttpConnection connection)
+    {
+        _connection=connection;
+        _parser=(HttpParser)connection.getParser();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see java.io.InputStream#read()
+     */
+    @Override
+    public int read() throws IOException
+    {
+        byte[] bytes = new byte[1];
+        int read = read(bytes, 0, 1);
+        return read < 0 ? -1 : 0xff & bytes[0];
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see java.io.InputStream#read(byte[], int, int)
+     */
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException
+    {
+        int l=-1;
+        Buffer content=_parser.blockForContent(_connection.getMaxIdleTime());
+        if (content!=null)
+            l= content.get(b, off, len);
+        else if (_connection.isEarlyEOF())
+            throw new EofException("early EOF");
+        return l;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int available() throws IOException
+    {
+        return _parser.available();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/HttpOutput.java b/src/java/org/eclipse/jetty/server/HttpOutput.java
new file mode 100644
index 0000000..311594a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/HttpOutput.java
@@ -0,0 +1,183 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.Writer;
+
+import javax.servlet.ServletOutputStream;
+
+import org.eclipse.jetty.http.AbstractGenerator;
+import org.eclipse.jetty.http.Generator;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.ByteArrayOutputStream2;
+
+/** Output.
+ * 
+ * <p>
+ * Implements  {@link javax.servlet.ServletOutputStream} from the <code>javax.servlet</code> package.   
+ * </p>
+ * A {@link ServletOutputStream} implementation that writes content
+ * to a {@link AbstractGenerator}.   The class is designed to be reused
+ * and can be reopened after a close.
+ */
+public class HttpOutput extends ServletOutputStream 
+{
+    protected final AbstractHttpConnection _connection;
+    protected final AbstractGenerator _generator;
+    private boolean _closed;
+    private ByteArrayBuffer _onebyte;
+    
+    // These are held here for reuse by Writer
+    String _characterEncoding;
+    Writer _converter;
+    char[] _chars;
+    ByteArrayOutputStream2 _bytes;
+
+    /* ------------------------------------------------------------ */
+    public HttpOutput(AbstractHttpConnection connection)
+    {
+        _connection=connection;
+        _generator=(AbstractGenerator)connection.getGenerator();
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxIdleTime()
+    {
+        return _connection.getMaxIdleTime();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isWritten()
+    {
+        return _generator.getContentWritten()>0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see java.io.OutputStream#close()
+     */
+    @Override
+    public void close() throws IOException
+    {
+        _closed=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean isClosed()
+    {
+        return _closed;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void reopen()
+    {
+        _closed=false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void flush() throws IOException
+    {
+        _generator.flush(getMaxIdleTime());
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException
+    {
+        write(new ByteArrayBuffer(b,off,len));
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see java.io.OutputStream#write(byte[])
+     */
+    @Override
+    public void write(byte[] b) throws IOException
+    {
+        write(new ByteArrayBuffer(b));
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see java.io.OutputStream#write(int)
+     */
+    @Override
+    public void write(int b) throws IOException
+    {
+        if (_onebyte==null)
+            _onebyte=new ByteArrayBuffer(1);
+        else
+            _onebyte.clear();
+        _onebyte.put((byte)b);
+        write(_onebyte);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void write(Buffer buffer) throws IOException
+    {
+        if (_closed)
+            throw new IOException("Closed");
+        if (!_generator.isOpen())
+            throw new EofException();
+        
+        // Block until we can add _content.
+        while (_generator.isBufferFull())
+        {
+            _generator.blockForOutput(getMaxIdleTime());
+            if (_closed)
+                throw new IOException("Closed");
+            if (!_generator.isOpen())
+                throw new EofException();
+        }
+
+        // Add the _content
+        _generator.addContent(buffer, Generator.MORE);
+
+        // Have to flush and complete headers?
+        
+        if (_generator.isAllContentWritten())
+        {
+            flush();
+            close();
+        } 
+        else if (_generator.isBufferFull())
+            _connection.commitResponse(Generator.MORE);
+
+        // Block until our buffer is free
+        while (buffer.length() > 0 && _generator.isOpen())
+        {
+            _generator.blockForOutput(getMaxIdleTime());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.ServletOutputStream#print(java.lang.String)
+     */
+    @Override
+    public void print(String s) throws IOException
+    {
+        write(s.getBytes());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/HttpWriter.java b/src/java/org/eclipse/jetty/server/HttpWriter.java
new file mode 100644
index 0000000..9bff50d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/HttpWriter.java
@@ -0,0 +1,302 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.eclipse.jetty.http.AbstractGenerator;
+import org.eclipse.jetty.util.ByteArrayOutputStream2;
+import org.eclipse.jetty.util.StringUtil;
+
+/** OutputWriter.
+ * A writer that can wrap a {@link HttpOutput} stream and provide
+ * character encodings.
+ *
+ * The UTF-8 encoding is done by this class and no additional 
+ * buffers or Writers are used.
+ * The UTF-8 code was inspired by http://javolution.org
+ */
+public class HttpWriter extends Writer
+{
+    public static final int MAX_OUTPUT_CHARS = 512; 
+    
+    private static final int WRITE_CONV = 0;
+    private static final int WRITE_ISO1 = 1;
+    private static final int WRITE_UTF8 = 2;
+    
+    final HttpOutput _out;
+    final AbstractGenerator _generator;
+    int _writeMode;
+    int _surrogate;
+
+    /* ------------------------------------------------------------ */
+    public HttpWriter(HttpOutput out)
+    {
+        _out=out;
+        _generator=_out._generator;
+        _surrogate=0; // AS lastUTF16CodePoint
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setCharacterEncoding(String encoding)
+    {
+        if (encoding == null || StringUtil.__ISO_8859_1.equalsIgnoreCase(encoding))
+        {
+            _writeMode = WRITE_ISO1;
+        }
+        else if (StringUtil.__UTF8.equalsIgnoreCase(encoding))
+        {
+            _writeMode = WRITE_UTF8;
+        }
+        else
+        {
+            _writeMode = WRITE_CONV;
+            if (_out._characterEncoding == null || !_out._characterEncoding.equalsIgnoreCase(encoding))
+                _out._converter = null; // Set lazily in getConverter()
+        }
+        
+        _out._characterEncoding = encoding;
+        if (_out._bytes==null)
+            _out._bytes = new ByteArrayOutputStream2(MAX_OUTPUT_CHARS);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void close() throws IOException
+    {
+        _out.close();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void flush() throws IOException
+    {
+        _out.flush();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write (String s,int offset, int length) throws IOException
+    {   
+        while (length > MAX_OUTPUT_CHARS)
+        {
+            write(s, offset, MAX_OUTPUT_CHARS);
+            offset += MAX_OUTPUT_CHARS;
+            length -= MAX_OUTPUT_CHARS;
+        }
+
+        if (_out._chars==null)
+        {
+            _out._chars = new char[MAX_OUTPUT_CHARS]; 
+        }
+        char[] chars = _out._chars;
+        s.getChars(offset, offset + length, chars, 0);
+        write(chars, 0, length);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write (char[] s,int offset, int length) throws IOException
+    {              
+        HttpOutput out = _out; 
+        
+        while (length > 0)
+        {  
+            out._bytes.reset();
+            int chars = length>MAX_OUTPUT_CHARS?MAX_OUTPUT_CHARS:length;
+            
+            switch (_writeMode)
+            {
+                case WRITE_CONV:
+                {
+                    Writer converter=getConverter();
+                    converter.write(s, offset, chars);
+                    converter.flush();
+                }
+                break;
+
+                case WRITE_ISO1:
+                {
+                    byte[] buffer=out._bytes.getBuf();
+                    int bytes=out._bytes.getCount();
+                    
+                    if (chars>buffer.length-bytes)
+                        chars=buffer.length-bytes;
+
+                    for (int i = 0; i < chars; i++)
+                    {
+                        int c = s[offset+i];
+                        buffer[bytes++]=(byte)(c<256?c:'?'); // ISO-1 and UTF-8 match for 0 - 255
+                    }
+                    if (bytes>=0)
+                        out._bytes.setCount(bytes);
+
+                    break;
+                }
+
+                case WRITE_UTF8:
+                {
+                    byte[] buffer=out._bytes.getBuf();
+                    int bytes=out._bytes.getCount();
+
+                    if (bytes+chars>buffer.length)
+                        chars=buffer.length-bytes;
+
+                    for (int i = 0; i < chars; i++)
+                    {
+                        int code = s[offset+i];
+
+                        // Do we already have a surrogate?
+                        if(_surrogate==0)
+                        {
+                            // No - is this char code a surrogate?
+                            if(Character.isHighSurrogate((char)code))
+                            {
+                                _surrogate=code; // UCS-?
+                                continue;
+                            }                            
+                        }
+                        // else handle a low surrogate
+                        else if(Character.isLowSurrogate((char)code))
+                        {
+                            code = Character.toCodePoint((char)_surrogate, (char)code); // UCS-4
+                        }
+                        // else UCS-2
+                        else
+                        {
+                            code=_surrogate; // UCS-2
+                            _surrogate=0; // USED
+                            i--;
+                        }
+
+                        if ((code & 0xffffff80) == 0) 
+                        {
+                            // 1b
+                            if (bytes>=buffer.length)
+                            {
+                                chars=i;
+                                break;
+                            }
+                            buffer[bytes++]=(byte)(code);
+                        }
+                        else
+                        {
+                            if((code&0xfffff800)==0)
+                            {
+                                // 2b
+                                if (bytes+2>buffer.length)
+                                {
+                                    chars=i;
+                                    break;
+                                }
+                                buffer[bytes++]=(byte)(0xc0|(code>>6));
+                                buffer[bytes++]=(byte)(0x80|(code&0x3f));
+                            }
+                            else if((code&0xffff0000)==0)
+                            {
+                                // 3b
+                                if (bytes+3>buffer.length)
+                                {
+                                    chars=i;
+                                    break;
+                                }
+                                buffer[bytes++]=(byte)(0xe0|(code>>12));
+                                buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|(code&0x3f));
+                            }
+                            else if((code&0xff200000)==0)
+                            {
+                                // 4b
+                                if (bytes+4>buffer.length)
+                                {
+                                    chars=i;
+                                    break;
+                                }
+                                buffer[bytes++]=(byte)(0xf0|(code>>18));
+                                buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|(code&0x3f));
+                            }
+                            else if((code&0xf4000000)==0)
+                            {
+                                // 5b
+                                if (bytes+5>buffer.length)
+                                {
+                                    chars=i;
+                                    break;
+                                }
+                                buffer[bytes++]=(byte)(0xf8|(code>>24));
+                                buffer[bytes++]=(byte)(0x80|((code>>18)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|(code&0x3f));
+                            }
+                            else if((code&0x80000000)==0)
+                            {
+                                // 6b
+                                if (bytes+6>buffer.length)
+                                {
+                                    chars=i;
+                                    break;
+                                }
+                                buffer[bytes++]=(byte)(0xfc|(code>>30));
+                                buffer[bytes++]=(byte)(0x80|((code>>24)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>18)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>12)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|((code>>6)&0x3f));
+                                buffer[bytes++]=(byte)(0x80|(code&0x3f));
+                            }
+                            else
+                            {
+                                buffer[bytes++]=(byte)('?');
+                            } 
+
+                            _surrogate=0; // USED
+
+                            if (bytes==buffer.length)
+                            {
+                                chars=i+1;
+                                break;
+                            }
+                        }
+                    }
+                    out._bytes.setCount(bytes);
+                    break;
+                }
+                default:
+                    throw new IllegalStateException();
+            }
+            
+            out._bytes.writeTo(out);
+            length-=chars;
+            offset+=chars;
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private Writer getConverter() throws IOException
+    {
+        if (_out._converter == null)
+            _out._converter = new OutputStreamWriter(_out._bytes, _out._characterEncoding);
+        return _out._converter;
+    }   
+}
diff --git a/src/java/org/eclipse/jetty/server/InclusiveByteRange.java b/src/java/org/eclipse/jetty/server/InclusiveByteRange.java
new file mode 100644
index 0000000..10329bb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/InclusiveByteRange.java
@@ -0,0 +1,227 @@
+//
+//  ========================================================================
+//  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.Enumeration;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Byte range inclusive of end points.
+ * <PRE>
+ * 
+ *   parses the following types of byte ranges:
+ * 
+ *       bytes=100-499
+ *       bytes=-300
+ *       bytes=100-
+ *       bytes=1-2,2-3,6-,-2
+ *
+ *   given an entity length, converts range to string
+ * 
+ *       bytes 100-499/500
+ * 
+ * </PRE>
+ * 
+ * Based on RFC2616 3.12, 14.16, 14.35.1, 14.35.2
+ * @version $version$
+ * 
+ */
+public class InclusiveByteRange 
+{
+    private static final Logger LOG = Log.getLogger(InclusiveByteRange.class);
+
+    long first = 0;
+    long last  = 0;    
+
+    public InclusiveByteRange(long first, long last)
+    {
+        this.first = first;
+        this.last = last;
+    }
+    
+    public long getFirst()
+    {
+        return first;
+    }
+
+    public long getLast()
+    {
+        return last;
+    }    
+
+
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @param headers Enumeration of Range header fields.
+     * @param size Size of the resource.
+     * @return LazyList of satisfiable ranges
+     */
+    public static List satisfiableRanges(Enumeration headers, long size)
+    {
+        Object satRanges=null;
+        
+        // walk through all Range headers
+    headers:
+        while (headers.hasMoreElements())
+        {
+            String header = (String) headers.nextElement();
+            StringTokenizer tok = new StringTokenizer(header,"=,",false);
+            String t=null;
+            try
+            {
+                // read all byte ranges for this header 
+                while (tok.hasMoreTokens())
+                {
+                    try
+                    {
+                        t = tok.nextToken().trim();
+
+                        long first = -1;
+                        long last = -1;
+                        int d = t.indexOf('-');
+                        if (d < 0 || t.indexOf("-",d + 1) >= 0)
+                        {
+                            if ("bytes".equals(t))
+                                continue;
+                            LOG.warn("Bad range format: {}",t);
+                            continue headers;
+                        }
+                        else if (d == 0)
+                        {
+                            if (d + 1 < t.length())
+                                last = Long.parseLong(t.substring(d + 1).trim());
+                            else
+                            {
+                                LOG.warn("Bad range format: {}",t);
+                                continue;
+                            }
+                        }
+                        else if (d + 1 < t.length())
+                        {
+                            first = Long.parseLong(t.substring(0,d).trim());
+                            last = Long.parseLong(t.substring(d + 1).trim());
+                        }
+                        else
+                            first = Long.parseLong(t.substring(0,d).trim());
+
+                        if (first == -1 && last == -1)
+                            continue headers;
+
+                        if (first != -1 && last != -1 && (first > last))
+                            continue headers;
+
+                        if (first < size)
+                        {
+                            InclusiveByteRange range = new InclusiveByteRange(first,last);
+                            satRanges = LazyList.add(satRanges,range);
+                        }
+                    }
+                    catch (NumberFormatException e)
+                    {
+                        LOG.warn("Bad range format: {}",t);
+                        LOG.ignore(e);
+                        continue;
+                    }
+                }
+            }
+            catch(Exception e)
+            {
+                LOG.warn("Bad range format: {}",t);
+                LOG.ignore(e);
+            }    
+        }
+        return LazyList.getList(satRanges,true);
+    }
+
+    /* ------------------------------------------------------------ */
+    public long getFirst(long size)
+    {
+        if (first<0)
+        {
+            long tf=size-last;
+            if (tf<0)
+                tf=0;
+            return tf;
+        }
+        return first;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public long getLast(long size)
+    {
+        if (first<0)
+            return size-1;
+        
+        if (last<0 ||last>=size)
+            return size-1;
+        return last;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public long getSize(long size)
+    {
+        return getLast(size)-getFirst(size)+1;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public String toHeaderRangeString(long size)
+    {
+        StringBuilder sb = new StringBuilder(40);
+        sb.append("bytes ");
+        sb.append(getFirst(size));
+        sb.append('-');
+        sb.append(getLast(size));
+        sb.append("/");
+        sb.append(size);
+        return sb.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String to416HeaderRangeString(long size)
+    {
+        StringBuilder sb = new StringBuilder(40);
+        sb.append("bytes */");
+        sb.append(size);
+        return sb.toString();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder(60);
+        sb.append(Long.toString(first));
+        sb.append(":");
+        sb.append(Long.toString(last));
+        return sb.toString();
+    }
+
+
+}
+
+
+
diff --git a/src/java/org/eclipse/jetty/server/LocalConnector.java b/src/java/org/eclipse/jetty/server/LocalConnector.java
new file mode 100644
index 0000000..e7edad3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/LocalConnector.java
@@ -0,0 +1,176 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.ByteArrayEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class LocalConnector extends AbstractConnector
+{
+    private static final Logger LOG = Log.getLogger(LocalConnector.class);
+    private final BlockingQueue<Request> _requests = new LinkedBlockingQueue<Request>();
+    
+    public LocalConnector()
+    {
+        setMaxIdleTime(30000);
+    }
+
+    public Object getConnection()
+    {
+        return this;
+    }
+
+    public String getResponses(String requests) throws Exception
+    {
+        return getResponses(requests, false);
+    }
+
+    public String getResponses(String requests, boolean keepOpen) throws Exception
+    {
+        ByteArrayBuffer result = getResponses(new ByteArrayBuffer(requests, StringUtil.__ISO_8859_1), keepOpen);
+        return result==null?null:result.toString(StringUtil.__ISO_8859_1);
+    }
+
+    public ByteArrayBuffer getResponses(ByteArrayBuffer requestsBuffer, boolean keepOpen) throws Exception
+    {
+        CountDownLatch latch = new CountDownLatch(1);
+        Request request = new Request(requestsBuffer, keepOpen, latch);
+        _requests.add(request);
+        latch.await(getMaxIdleTime(),TimeUnit.MILLISECONDS);
+        return request.getResponsesBuffer();
+    }
+
+    @Override
+    protected void accept(int acceptorID) throws IOException, InterruptedException
+    {
+        Request request = _requests.take();
+        getThreadPool().dispatch(request);
+    }
+
+    public void open() throws IOException
+    {
+    }
+
+    public void close() throws IOException
+    {
+    }
+
+    public int getLocalPort()
+    {
+        return -1;
+    }
+
+    public void executeRequest(String rawRequest) throws IOException
+    {
+        Request request = new Request(new ByteArrayBuffer(rawRequest, "UTF-8"), true, null);
+        _requests.add(request);
+    }
+
+    private class Request implements Runnable
+    {
+        private final ByteArrayBuffer _requestsBuffer;
+        private final boolean _keepOpen;
+        private final CountDownLatch _latch;
+        private volatile ByteArrayBuffer _responsesBuffer;
+
+        private Request(ByteArrayBuffer requestsBuffer, boolean keepOpen, CountDownLatch latch)
+        {
+            _requestsBuffer = requestsBuffer;
+            _keepOpen = keepOpen;
+            _latch = latch;
+        }
+
+        public void run()
+        {
+            try
+            {
+                ByteArrayEndPoint endPoint = new ByteArrayEndPoint(_requestsBuffer.asArray(), 1024)
+                {
+                    @Override
+                    public void setConnection(Connection connection)
+                    {
+                        if (getConnection()!=null && connection!=getConnection())
+                            connectionUpgraded(getConnection(),connection);
+                        super.setConnection(connection);
+                    }
+                };
+
+                endPoint.setGrowOutput(true);
+                AbstractHttpConnection connection = new BlockingHttpConnection(LocalConnector.this, endPoint, getServer());
+                endPoint.setConnection(connection);
+                connectionOpened(connection);
+
+                boolean leaveOpen = _keepOpen;
+                try
+                {
+                    while (endPoint.getIn().length() > 0 && endPoint.isOpen())
+                    {
+                        while (true)
+                        {
+                            final Connection con = endPoint.getConnection();
+                            final Connection next = con.handle();
+                            if (next!=con)
+                            {  
+                                endPoint.setConnection(next);
+                                continue;
+                            }
+                            break;
+                        }
+                    }
+                }
+                catch (IOException x)
+                {
+                    LOG.debug(x);
+                    leaveOpen = false;
+                }
+                catch (Exception x)
+                {
+                    LOG.warn(x);
+                    leaveOpen = false;
+                }
+                finally
+                {
+                    if (!leaveOpen)
+                        connectionClosed(connection);
+                    _responsesBuffer = endPoint.getOut();
+                }
+            }
+            finally
+            {
+                if (_latch != null)
+                    _latch.countDown();
+            }
+        }
+
+        public ByteArrayBuffer getResponsesBuffer()
+        {
+            return _responsesBuffer;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/NCSARequestLog.java b/src/java/org/eclipse/jetty/server/NCSARequestLog.java
new file mode 100644
index 0000000..5bcf73d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/NCSARequestLog.java
@@ -0,0 +1,726 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.servlet.http.Cookie;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.util.DateCache;
+import org.eclipse.jetty.util.RolloverFileOutputStream;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * This {@link RequestLog} implementation outputs logs in the pseudo-standard
+ * NCSA common log format. Configuration options allow a choice between the
+ * standard Common Log Format (as used in the 3 log format) and the Combined Log
+ * Format (single log format). This log format can be output by most web
+ * servers, and almost all web log analysis software can understand these
+ * formats.
+ *
+ * @org.apache.xbean.XBean element="ncsaLog"
+ */
+
+/* ------------------------------------------------------------ */
+/**
+ */
+public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
+{
+    private static final Logger LOG = Log.getLogger(NCSARequestLog.class);
+    private static ThreadLocal<StringBuilder> _buffers = new ThreadLocal<StringBuilder>()
+            {
+                @Override
+                protected StringBuilder initialValue()
+                {
+                    return new StringBuilder(256);
+                }
+            };
+
+    private String _filename;
+    private boolean _extended;
+    private boolean _append;
+    private int _retainDays;
+    private boolean _closeOut;
+    private boolean _preferProxiedForAddress;
+    private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z";
+    private String _filenameDateFormat = null;
+    private Locale _logLocale = Locale.getDefault();
+    private String _logTimeZone = "GMT";
+    private String[] _ignorePaths;
+    private boolean _logLatency = false;
+    private boolean _logCookies = false;
+    private boolean _logServer = false;
+    private boolean _logDispatch = false;
+
+    private transient OutputStream _out;
+    private transient OutputStream _fileOut;
+    private transient DateCache _logDateCache;
+    private transient PathMap _ignorePathMap;
+    private transient Writer _writer;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create request log object with default settings.
+     */
+    public NCSARequestLog()
+    {
+        _extended = true;
+        _append = true;
+        _retainDays = 31;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create request log object with specified output file name.
+     * 
+     * @param filename the file name for the request log.
+     *                 This may be in the format expected
+     *                 by {@link RolloverFileOutputStream}
+     */
+    public NCSARequestLog(String filename)
+    {
+        _extended = true;
+        _append = true;
+        _retainDays = 31;
+        setFilename(filename);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the output file name of the request log.
+     * The file name may be in the format expected by
+     * {@link RolloverFileOutputStream}.
+     * 
+     * @param filename file name of the request log
+     *                
+     */
+    public void setFilename(String filename)
+    {
+        if (filename != null)
+        {
+            filename = filename.trim();
+            if (filename.length() == 0)
+                filename = null;
+        }
+        _filename = filename;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the output file name of the request log.
+     * 
+     * @return file name of the request log
+     */
+    public String getFilename()
+    {
+        return _filename;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the file name of the request log with the expanded
+     * date wildcard if the output is written to the disk using
+     * {@link RolloverFileOutputStream}.
+     * 
+     * @return file name of the request log, or null if not applicable
+     */
+    public String getDatedFilename()
+    {
+        if (_fileOut instanceof RolloverFileOutputStream)
+            return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the timestamp format for request log entries in the file.
+     * If this is not set, the pre-formated request timestamp is used.
+     * 
+     * @param format timestamp format string 
+     */
+    public void setLogDateFormat(String format)
+    {
+        _logDateFormat = format;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the timestamp format string for request log entries.
+     * 
+     * @return timestamp format string.
+     */
+    public String getLogDateFormat()
+    {
+        return _logDateFormat;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the locale of the request log.
+     * 
+     * @param logLocale locale object
+     */
+    public void setLogLocale(Locale logLocale)
+    {
+        _logLocale = logLocale;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the locale of the request log.
+     * 
+     * @return locale object
+     */
+    public Locale getLogLocale()
+    {
+        return _logLocale;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the timezone of the request log.
+     * 
+     * @param tz timezone string
+     */
+    public void setLogTimeZone(String tz)
+    {
+        _logTimeZone = tz;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the timezone of the request log.
+     * 
+     * @return timezone string
+     */
+    public String getLogTimeZone()
+    {
+        return _logTimeZone;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the number of days before rotated log files are deleted.
+     * 
+     * @param retainDays number of days to keep a log file
+     */
+    public void setRetainDays(int retainDays)
+    {
+        _retainDays = retainDays;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the number of days before rotated log files are deleted.
+     * 
+     * @return number of days to keep a log file
+     */
+    public int getRetainDays()
+    {
+        return _retainDays;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the extended request log format flag.
+     * 
+     * @param extended true - log the extended request information,
+     *                 false - do not log the extended request information
+     */
+    public void setExtended(boolean extended)
+    {
+        _extended = extended;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the extended request log format flag.
+     * 
+     * @return value of the flag
+     */
+    public boolean isExtended()
+    {
+        return _extended;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set append to log flag.
+     * 
+     * @param append true - request log file will be appended after restart,
+     *               false - request log file will be overwritten after restart
+     */
+    public void setAppend(boolean append)
+    {
+        _append = append;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve append to log flag.
+     * 
+     * @return value of the flag
+     */
+    public boolean isAppend()
+    {
+        return _append;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set request paths that will not be logged.
+     * 
+     * @param ignorePaths array of request paths
+     */
+    public void setIgnorePaths(String[] ignorePaths)
+    {
+        _ignorePaths = ignorePaths;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the request paths that will not be logged.
+     * 
+     * @return array of request paths
+     */
+    public String[] getIgnorePaths()
+    {
+        return _ignorePaths;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Controls logging of the request cookies.
+     * 
+     * @param logCookies true - values of request cookies will be logged,
+     *                   false - values of request cookies will not be logged
+     */
+    public void setLogCookies(boolean logCookies)
+    {
+        _logCookies = logCookies;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve log cookies flag
+     * 
+     * @return value of the flag
+     */
+    public boolean getLogCookies()
+    {
+        return _logCookies;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Controls logging of the request hostname.
+     * 
+     * @param logServer true - request hostname will be logged,
+     *                  false - request hostname will not be logged
+     */
+    public void setLogServer(boolean logServer)
+    {
+        _logServer = logServer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve log hostname flag.
+     * 
+     * @return value of the flag
+     */
+    public boolean getLogServer()
+    {
+        return _logServer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Controls logging of request processing time.
+     * 
+     * @param logLatency true - request processing time will be logged
+     *                   false - request processing time will not be logged
+     */
+    public void setLogLatency(boolean logLatency)
+    {
+        _logLatency = logLatency;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve log request processing time flag.
+     * 
+     * @return value of the flag
+     */
+    public boolean getLogLatency()
+    {
+        return _logLatency;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Controls whether the actual IP address of the connection or
+     * the IP address from the X-Forwarded-For header will be logged.
+     * 
+     * @param preferProxiedForAddress true - IP address from header will be logged,
+     *                                false - IP address from the connection will be logged
+     */
+    public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
+    {
+        _preferProxiedForAddress = preferProxiedForAddress;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieved log X-Forwarded-For IP address flag.
+     * 
+     * @return value of the flag
+     */
+    public boolean getPreferProxiedForAddress()
+    {
+        return _preferProxiedForAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the log file name date format.
+     * @see RolloverFileOutputStream#RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)
+     * 
+     * @param logFileDateFormat format string that is passed to {@link RolloverFileOutputStream}
+     */
+    public void setFilenameDateFormat(String logFileDateFormat)
+    {
+        _filenameDateFormat = logFileDateFormat;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the file name date format string.
+     * 
+     * @return the log File Date Format
+     */
+    public String getFilenameDateFormat()
+    {
+        return _filenameDateFormat;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * Controls logging of the request dispatch time
+     * 
+     * @param value true - request dispatch time will be logged
+     *              false - request dispatch time will not be logged
+     */
+    public void setLogDispatch(boolean value)
+    {
+        _logDispatch = value;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve request dispatch time logging flag
+     * 
+     * @return value of the flag
+     */
+    public boolean isLogDispatch()
+    {
+        return _logDispatch;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Writes the request and response information to the output stream.
+     * 
+     * @see org.eclipse.jetty.server.RequestLog#log(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response)
+     */
+    public void log(Request request, Response response)
+    {
+        try
+        {
+            if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
+                return;
+
+            if (_fileOut == null)
+                return;
+
+            StringBuilder buf= _buffers.get();
+            buf.setLength(0);
+
+            if (_logServer)
+            {
+                buf.append(request.getServerName());
+                buf.append(' ');
+            }
+
+            String addr = null;
+            if (_preferProxiedForAddress)
+            {
+                addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
+            }
+
+            if (addr == null)
+                addr = request.getRemoteAddr();
+
+            buf.append(addr);
+            buf.append(" - ");
+            Authentication authentication=request.getAuthentication();
+            if (authentication instanceof Authentication.User)
+                buf.append(((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName());
+            else
+                buf.append(" - ");
+
+            buf.append(" [");
+            if (_logDateCache != null)
+                buf.append(_logDateCache.format(request.getTimeStamp()));
+            else
+                buf.append(request.getTimeStampBuffer().toString());
+
+            buf.append("] \"");
+            buf.append(request.getMethod());
+            buf.append(' ');
+            buf.append(request.getUri().toString());
+            buf.append(' ');
+            buf.append(request.getProtocol());
+            buf.append("\" ");
+            if (request.getAsyncContinuation().isInitial())
+            {
+                int status = response.getStatus();
+                if (status <= 0)
+                    status = 404;
+                buf.append((char)('0' + ((status / 100) % 10)));
+                buf.append((char)('0' + ((status / 10) % 10)));
+                buf.append((char)('0' + (status % 10)));
+            }
+            else
+                buf.append("Async");
+
+            long responseLength = response.getContentCount();
+            if (responseLength >= 0)
+            {
+                buf.append(' ');
+                if (responseLength > 99999)
+                    buf.append(responseLength);
+                else
+                {
+                    if (responseLength > 9999)
+                        buf.append((char)('0' + ((responseLength / 10000) % 10)));
+                    if (responseLength > 999)
+                        buf.append((char)('0' + ((responseLength / 1000) % 10)));
+                    if (responseLength > 99)
+                        buf.append((char)('0' + ((responseLength / 100) % 10)));
+                    if (responseLength > 9)
+                        buf.append((char)('0' + ((responseLength / 10) % 10)));
+                    buf.append((char)('0' + (responseLength) % 10));
+                }
+                buf.append(' ');
+            }
+            else
+                buf.append(" - ");
+
+            
+            if (_extended)
+                logExtended(request, response, buf);
+
+            if (_logCookies)
+            {
+                Cookie[] cookies = request.getCookies();
+                if (cookies == null || cookies.length == 0)
+                    buf.append(" -");
+                else
+                {
+                    buf.append(" \"");
+                    for (int i = 0; i < cookies.length; i++)
+                    {
+                        if (i != 0)
+                            buf.append(';');
+                        buf.append(cookies[i].getName());
+                        buf.append('=');
+                        buf.append(cookies[i].getValue());
+                    }
+                    buf.append('\"');
+                }
+            }
+
+            if (_logDispatch || _logLatency)
+            {
+                long now = System.currentTimeMillis();
+
+                if (_logDispatch)
+                {   
+                    long d = request.getDispatchTime();
+                    buf.append(' ');
+                    buf.append(now - (d==0 ? request.getTimeStamp():d));
+                }
+
+                if (_logLatency)
+                {
+                    buf.append(' ');
+                    buf.append(now - request.getTimeStamp());
+                }
+            }
+
+            buf.append(StringUtil.__LINE_SEPARATOR);
+            
+            String log = buf.toString();
+            write(log);
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void write(String log) throws IOException 
+    {
+        synchronized(this)
+        {
+            if (_writer==null)
+                return;
+            _writer.write(log);
+            _writer.flush();
+        }
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Writes extended request and response information to the output stream.
+     * 
+     * @param request request object
+     * @param response response object
+     * @param b StringBuilder to write to
+     * @throws IOException
+     */
+    protected void logExtended(Request request,
+                               Response response,
+                               StringBuilder b) throws IOException
+    {
+        String referer = request.getHeader(HttpHeaders.REFERER);
+        if (referer == null)
+            b.append("\"-\" ");
+        else
+        {
+            b.append('"');
+            b.append(referer);
+            b.append("\" ");
+        }
+
+        String agent = request.getHeader(HttpHeaders.USER_AGENT);
+        if (agent == null)
+            b.append("\"-\" ");
+        else
+        {
+            b.append('"');
+            b.append(agent);
+            b.append('"');
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set up request logging and open log file.
+     * 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected synchronized void doStart() throws Exception
+    {
+        if (_logDateFormat != null)
+        {
+            _logDateCache = new DateCache(_logDateFormat,_logLocale);
+            _logDateCache.setTimeZoneID(_logTimeZone);
+        }
+
+        if (_filename != null)
+        {
+            _fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
+            _closeOut = true;
+            LOG.info("Opened " + getDatedFilename());
+        }
+        else
+            _fileOut = System.err;
+
+        _out = _fileOut;
+
+        if (_ignorePaths != null && _ignorePaths.length > 0)
+        {
+            _ignorePathMap = new PathMap();
+            for (int i = 0; i < _ignorePaths.length; i++)
+                _ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
+        }
+        else
+            _ignorePathMap = null;
+
+        synchronized(this)
+        {
+            _writer = new OutputStreamWriter(_out);
+        }
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Close the log file and perform cleanup.
+     * 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        synchronized (this)
+        {
+            super.doStop();
+            try
+            {
+                if (_writer != null)
+                    _writer.flush();
+            }
+            catch (IOException e)
+            {
+                LOG.ignore(e);
+            }
+            if (_out != null && _closeOut)
+                try
+                {
+                    _out.close();
+                }
+                catch (IOException e)
+                {
+                    LOG.ignore(e);
+                }
+
+            _out = null;
+            _fileOut = null;
+            _closeOut = false;
+            _logDateCache = null;
+            _writer = null;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/Request.java b/src/java/org/eclipse/jetty/server/Request.java
new file mode 100644
index 0000000..4b8c1d4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Request.java
@@ -0,0 +1,2204 @@
+//
+//  ========================================================================
+//  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.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.DispatcherType;
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.HttpVersions;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.BufferUtil;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.DirectNIOBuffer;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.io.nio.NIOBuffer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiException;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.MultiPartInputStream;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Jetty Request.
+ * <p>
+ * Implements {@link javax.servlet.http.HttpServletRequest} from the <code>javax.servlet.http</code> package.
+ * </p>
+ * <p>
+ * The standard interface of mostly getters, is extended with setters so that the request is mutable by the handlers that it is passed to. This allows the
+ * request object to be as lightweight as possible and not actually implement any significant behavior. For example
+ * <ul>
+ *
+ * <li>The {@link Request#getContextPath()} method will return null, until the request has been passed to a {@link ContextHandler} which matches the
+ * {@link Request#getPathInfo()} with a context path and calls {@link Request#setContextPath(String)} as a result.</li>
+ *
+ * <li>the HTTP session methods will all return null sessions until such time as a request has been passed to a
+ * {@link org.eclipse.jetty.server.session.SessionHandler} which checks for session cookies and enables the ability to create new sessions.</li>
+ *
+ * <li>The {@link Request#getServletPath()} method will return null until the request has been passed to a <code>org.eclipse.jetty.servlet.ServletHandler</code>
+ * and the pathInfo matched against the servlet URL patterns and {@link Request#setServletPath(String)} called as a result.</li>
+ * </ul>
+ *
+ * A request instance is created for each {@link AbstractHttpConnection} accepted by the server and recycled for each HTTP request received via that connection.
+ * An effort is made to avoid reparsing headers and cookies that are likely to be the same for requests from the same connection.
+ *
+ * <p>
+ * The form content that a request can process is limited to protect from Denial of Service attacks. The size in bytes is limited by
+ * {@link ContextHandler#getMaxFormContentSize()} or if there is no context then the "org.eclipse.jetty.server.Request.maxFormContentSize" {@link Server}
+ * attribute. The number of parameters keys is limited by {@link ContextHandler#getMaxFormKeys()} or if there is no context then the
+ * "org.eclipse.jetty.server.Request.maxFormKeys" {@link Server} attribute.
+ *
+ *
+ */
+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);
+
+    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
+    {
+
+        @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);
+                    }
+                }
+            }
+        }
+
+        @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;
+
+    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 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);
+
+        if (_paramsExtracted)
+        {
+            if (_parameters == null)
+                _parameters = _baseParameters;
+            return;
+        }
+
+        _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);
+
+                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 (_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 (content_length > maxFormContentSize && maxFormContentSize > 0)
+                            {
+                                throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize);
+                            }
+                            InputStream in = getInputStream();
+
+                            // 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_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 AsyncContext getAsyncContext()
+    {
+        if (_async.isInitial() && !_async.isAsyncStarted())
+            throw new IllegalStateException(_async.getStatusString());
+        return _async;
+    }
+
+    /* ------------------------------------------------------------ */
+    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());
+
+        Object attr = (_attributes == null)?null:_attributes.getAttribute(name);
+        if (attr == null && Continuation.ATTRIBUTE.equals(name))
+            return _async;
+        return attr;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getAttributeNames()
+     */
+    public Enumeration getAttributeNames()
+    {
+        if (_attributes == null)
+            return Collections.enumeration(Collections.EMPTY_LIST);
+
+        return AttributesMap.getAttributeNamesCopy(_attributes);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    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.ServletRequest#getCharacterEncoding()
+     */
+    public String getCharacterEncoding()
+    {
+        return _characterEncoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the connection.
+     */
+    public AbstractHttpConnection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getContentType()
+     */
+    public String getContentType()
+    {
+        return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getContextPath()
+     */
+    public String getContextPath()
+    {
+        return _contextPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getCookies()
+     */
+    public Cookie[] getCookies()
+    {
+        if (_cookiesExtracted)
+            return _cookies == null?null:_cookies.getCookies();
+
+        _cookiesExtracted = true;
+
+        Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER);
+
+        // Handle no cookies
+        if (enm != null)
+        {
+            if (_cookies == null)
+                _cookies = new CookieCutter();
+
+            while (enm.hasMoreElements())
+            {
+                String c = (String)enm.nextElement();
+                _cookies.addCookieField(c);
+            }
+        }
+
+        return _cookies == null?null:_cookies.getCookies();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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#getHeader(java.lang.String)
+     */
+    public String getHeader(String name)
+    {
+        return _connection.getRequestFields().getStringField(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
+     */
+    public Enumeration getHeaderNames()
+    {
+        return _connection.getRequestFields().getFieldNames();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the inputState.
+     */
+    public int getInputState()
+    {
+        return _inputState;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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.http.HttpServletRequest#getIntHeader(java.lang.String)
+     */
+    public int getIntHeader(String name)
+    {
+        return (int)_connection.getRequestFields().getLongField(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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);
+
+        // handle no locale
+        if (enm == null || !enm.hasMoreElements())
+            return Locale.getDefault();
+
+        // sort the list in quality order
+        List acceptLanguage = HttpFields.qualityList(enm);
+        if (acceptLanguage.size() == 0)
+            return Locale.getDefault();
+
+        int size = acceptLanguage.size();
+
+        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);
+        }
+
+        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);
+
+        // sort the list in quality order
+        List acceptLanguage = HttpFields.qualityList(enm);
+
+        if (acceptLanguage.size() == 0)
+            return Collections.enumeration(__defaultLocale);
+
+        Object langs = null;
+        int size = acceptLanguage.size();
+
+        // 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));
+        }
+
+        if (LazyList.size(langs) == 0)
+            return Collections.enumeration(__defaultLocale);
+
+        return Collections.enumeration(LazyList.getList(langs));
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getLocalName()
+     */
+    public String getLocalName()
+    {
+        if (_endp == null)
+            return null;
+        if (_dns)
+            return _endp.getLocalHost();
+
+        String local = _endp.getLocalAddr();
+        if (local != null && local.indexOf(':') >= 0)
+            local = "[" + local + "]";
+        return local;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getLocalPort()
+     */
+    public int getLocalPort()
+    {
+        return _endp == null?0:_endp.getLocalPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getMethod()
+     */
+    public String getMethod()
+    {
+        return _method;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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.ServletRequest#getParameterMap()
+     */
+    public Map getParameterMap()
+    {
+        if (!_paramsExtracted)
+            extractParameters();
+
+        return Collections.unmodifiableMap(_parameters.toStringArrayMap());
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getParameterNames()
+     */
+    public Enumeration getParameterNames()
+    {
+        if (!_paramsExtracted)
+            extractParameters();
+        return Collections.enumeration(_parameters.keySet());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the parameters.
+     */
+    public MultiMap<String> getParameters()
+    {
+        return _parameters;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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#getPathInfo()
+     */
+    public String getPathInfo()
+    {
+        return _pathInfo;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
+     */
+    public String getPathTranslated()
+    {
+        if (_pathInfo == null || _context == null)
+            return null;
+        return _context.getRealPath(_pathInfo);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getProtocol()
+     */
+    public String getProtocol()
+    {
+        return _protocol;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getQueryEncoding()
+    {
+        return _queryEncoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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;
+
+        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#getRealPath(java.lang.String)
+     */
+    public String getRealPath(String path)
+    {
+        if (_context == null)
+            return null;
+        return _context.getRealPath(path);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getRemoteAddr()
+     */
+    public String getRemoteAddr()
+    {
+        if (_remoteAddr != null)
+            return _remoteAddr;
+        return _endp == null?null:_endp.getRemoteAddr();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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#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;
+
+        // 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);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
+     */
+    public String getRequestedSessionId()
+    {
+        return _requestedSessionId;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getRequestURI()
+     */
+    public String getRequestURI()
+    {
+        if (_requestURI == null && _uri != null)
+            _requestURI = _uri.getPathAndParam();
+        return _requestURI;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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(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);
+            }
+
+            url.append(getRequestURI());
+            return url;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Response getResponse()
+    {
+        return _connection._response;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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(scheme);
+        url.append("://");
+        url.append(getServerName());
+
+        if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
+        {
+            url.append(':');
+            url.append(port);
+        }
+        return url;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getScheme()
+     */
+    public String getScheme()
+    {
+        return _scheme;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getServerName()
+     */
+    public String getServerName()
+    {
+        // Return already determined host
+        if (_serverName != null)
+            return _serverName;
+
+        if (_uri == null)
+            throw new IllegalStateException("No uri");
+
+        // Return host from absolute URI
+        _serverName = _uri.getHost();
+        _port = _uri.getPort();
+        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;
+
+                    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 _serverName;
+        }
+
+        // Return host from connection
+        if (_connection != null)
+        {
+            _serverName = getLocalName();
+            _port = getLocalPort();
+            if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName))
+                return _serverName;
+        }
+
+        // Return the local host
+        try
+        {
+            _serverName = InetAddress.getLocalHost().getHostAddress();
+        }
+        catch (java.net.UnknownHostException e)
+        {
+            LOG.ignore(e);
+        }
+        return _serverName;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#getServerPort()
+     */
+    public int getServerPort()
+    {
+        if (_port <= 0)
+        {
+            if (_serverName == null)
+                getServerName();
+
+            if (_port <= 0)
+            {
+                if (_serverName != null && _uri != null)
+                    _port = _uri.getPort();
+                else
+                    _port = _endp == null?0:_endp.getLocalPort();
+            }
+        }
+
+        if (_port <= 0)
+        {
+            if (getScheme().equalsIgnoreCase(URIUtil.HTTPS))
+                return 443;
+            return 80;
+        }
+        return _port;
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletContext getServletContext()
+    {
+        return _context;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public String getServletName()
+    {
+        if (_scope != null)
+            return _scope.getName();
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getServletPath()
+     */
+    public String getServletPath()
+    {
+        if (_servletPath == null)
+            _servletPath = "";
+        return _servletPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletResponse getServletResponse()
+    {
+        return _connection.getResponse();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletRequest#getSession()
+     */
+    public HttpSession getSession()
+    {
+        return getSession(true);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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;
+        }
+
+        if (!create)
+            return null;
+
+        if (_sessionManager == null)
+            throw new IllegalStateException("No SessionManager");
+
+        _session = _sessionManager.newHttpSession(this);
+        HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
+        if (cookie != null)
+            _connection.getResponse().addCookie(cookie);
+
+        return _session;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the sessionManager.
+     */
+    public SessionManager getSessionManager()
+    {
+        return _sessionManager;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the uri.
+     */
+    public HttpURI getUri()
+    {
+        return _uri;
+    }
+
+    /* ------------------------------------------------------------ */
+    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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get timestamp of the request dispatch
+     *
+     * @return timestamp
+     */
+    public long getDispatchTime()
+    {
+        return _dispatchTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isHandled()
+    {
+        return _handled;
+    }
+
+    public boolean isAsyncStarted()
+    {
+       return _async.isAsyncStarted();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isAsyncSupported()
+    {
+        return _asyncSupported;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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#isRequestedSessionIdValid()
+     */
+    public boolean isRequestedSessionIdValid()
+    {
+        if (_requestedSessionId == null)
+            return false;
+
+        HttpSession session = getSession(false);
+        return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session)));
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletRequest#isSecure()
+     */
+    public boolean isSecure()
+    {
+        return _connection.isConfidential(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @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));
+
+        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;
+            }
+        }
+
+        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 (_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);
+                    }
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    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 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);
+
+        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 (old_value == null)
+                        l.attributeAdded(event);
+                    else if (value == null)
+                        l.attributeRemoved(event);
+                    else
+                        l.attributeReplaced(event);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public void setAttributes(Attributes attributes)
+    {
+        _attributes = attributes;
+    }
+
+    /* ------------------------------------------------------------ */
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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;
+
+        _characterEncoding = 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    // 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);
+
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setDispatcherType(DispatcherType type)
+    {
+        _dispatcherType = type;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setHandled(boolean h)
+    {
+        _handled = h;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @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 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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 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 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 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 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 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 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setUserIdentityScope(UserIdentity.Scope scope)
+    {
+        _scope = scope;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 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;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    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()));
+
+                    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 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;
+
+        // 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();
+
+                // 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));
+            }
+        }
+
+        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(LazyList.get(values,i));
+                        }
+                    }
+                }
+
+                query = query + overridden_query_string;
+            }
+            else
+            {
+                query = query + "&" + _queryString;
+            }
+        }
+
+        setParameters(parameters);
+        setQueryString(query);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/RequestLog.java b/src/java/org/eclipse/jetty/server/RequestLog.java
new file mode 100644
index 0000000..0cb1a53
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/RequestLog.java
@@ -0,0 +1,30 @@
+//
+//  ========================================================================
+//  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 org.eclipse.jetty.util.component.LifeCycle;
+
+/** 
+ * A <code>RequestLog</code> can be attached to a {@link org.eclipse.jetty.server.handler.RequestLogHandler} to enable 
+ * logging of requests/responses.
+ */
+public interface RequestLog extends LifeCycle
+{
+    public void log(Request request, Response response);
+}
diff --git a/src/java/org/eclipse/jetty/server/ResourceCache.java b/src/java/org/eclipse/jetty/server/ResourceCache.java
new file mode 100644
index 0000000..204d71e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ResourceCache.java
@@ -0,0 +1,522 @@
+//
+//  ========================================================================
+//  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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Comparator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.http.HttpContent;
+import org.eclipse.jetty.http.HttpContent.ResourceAsHttpContent;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.View;
+import org.eclipse.jetty.io.nio.DirectNIOBuffer;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceFactory;
+
+
+/* ------------------------------------------------------------ */
+/** 
+ * 
+ */
+public class ResourceCache
+{
+    private static final Logger LOG = Log.getLogger(ResourceCache.class);
+
+    private final ConcurrentMap<String,Content> _cache;
+    private final AtomicInteger _cachedSize;
+    private final AtomicInteger _cachedFiles;
+    private final ResourceFactory _factory;
+    private final ResourceCache _parent;
+    private final MimeTypes _mimeTypes;
+    private final boolean _etags;
+
+    private boolean  _useFileMappedBuffer=true;
+    private int _maxCachedFileSize =4*1024*1024;
+    private int _maxCachedFiles=2048;
+    private int _maxCacheSize =32*1024*1024;
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     * @param mimeTypes Mimetype to use for meta data
+     */
+    public ResourceCache(ResourceCache parent, ResourceFactory factory, MimeTypes mimeTypes,boolean useFileMappedBuffer,boolean etags)
+    {
+        _factory = factory;
+        _cache=new ConcurrentHashMap<String,Content>();
+        _cachedSize=new AtomicInteger();
+        _cachedFiles=new AtomicInteger();
+        _mimeTypes=mimeTypes;
+        _parent=parent;
+        _etags=etags;
+        _useFileMappedBuffer=useFileMappedBuffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getCachedSize()
+    {
+        return _cachedSize.get();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int getCachedFiles()
+    {
+        return _cachedFiles.get();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int getMaxCachedFileSize()
+    {
+        return _maxCachedFileSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxCachedFileSize(int maxCachedFileSize)
+    {
+        _maxCachedFileSize = maxCachedFileSize;
+        shrinkCache();
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxCacheSize()
+    {
+        return _maxCacheSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMaxCacheSize(int maxCacheSize)
+    {
+        _maxCacheSize = maxCacheSize;
+        shrinkCache();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the maxCachedFiles.
+     */
+    public int getMaxCachedFiles()
+    {
+        return _maxCachedFiles;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxCachedFiles The maxCachedFiles to set.
+     */
+    public void setMaxCachedFiles(int maxCachedFiles)
+    {
+        _maxCachedFiles = maxCachedFiles;
+        shrinkCache();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isUseFileMappedBuffer()
+    {
+        return _useFileMappedBuffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setUseFileMappedBuffer(boolean useFileMappedBuffer)
+    {
+        _useFileMappedBuffer = useFileMappedBuffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void flushCache()
+    {
+        if (_cache!=null)
+        {
+            while (_cache.size()>0)
+            {
+                for (String path : _cache.keySet())
+                {
+                    Content content = _cache.remove(path);
+                    if (content!=null)
+                        content.invalidate();
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get a Entry from the cache.
+     * Get either a valid entry object or create a new one if possible.
+     *
+     * @param pathInContext The key into the cache
+     * @return The entry matching <code>pathInContext</code>, or a new entry 
+     * if no matching entry was found. If the content exists but is not cachable, 
+     * then a {@link ResourceAsHttpContent} instance is return. If 
+     * the resource does not exist, then null is returned.
+     * @throws IOException Problem loading the resource
+     */
+    public HttpContent lookup(String pathInContext)
+        throws IOException
+    {
+        // Is the content in this cache?
+        Content content =_cache.get(pathInContext);
+        if (content!=null && (content).isValid())
+            return content;
+       
+        // try loading the content from our factory.
+        Resource resource=_factory.getResource(pathInContext);
+        HttpContent loaded = load(pathInContext,resource);
+        if (loaded!=null)
+            return loaded;
+        
+        // Is the content in the parent cache?
+        if (_parent!=null)
+        {
+            HttpContent httpContent=_parent.lookup(pathInContext);
+            if (httpContent!=null)
+                return httpContent;
+        }
+        
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param resource
+     * @return True if the resource is cacheable. The default implementation tests the cache sizes.
+     */
+    protected boolean isCacheable(Resource resource)
+    {
+        long len = resource.length();
+
+        // Will it fit in the cache?
+        return  (len>0 && len<_maxCachedFileSize && len<_maxCacheSize);
+    }
+    
+    /* ------------------------------------------------------------ */
+    private HttpContent load(String pathInContext, Resource resource)
+        throws IOException
+    {
+        Content content=null;
+        
+        if (resource==null || !resource.exists())
+            return null;
+        
+        // Will it fit in the cache?
+        if (!resource.isDirectory() && isCacheable(resource))
+        {   
+            // Create the Content (to increment the cache sizes before adding the content 
+            content = new Content(pathInContext,resource);
+
+            // reduce the cache to an acceptable size.
+            shrinkCache();
+
+            // Add it to the cache.
+            Content added = _cache.putIfAbsent(pathInContext,content);
+            if (added!=null)
+            {
+                content.invalidate();
+                content=added;
+            }
+
+            return content;
+        }
+        
+        return new HttpContent.ResourceAsHttpContent(resource,_mimeTypes.getMimeByExtension(resource.toString()),getMaxCachedFileSize(),_etags);
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    private void shrinkCache()
+    {
+        // While we need to shrink
+        while (_cache.size()>0 && (_cachedFiles.get()>_maxCachedFiles || _cachedSize.get()>_maxCacheSize))
+        {
+            // Scan the entire cache and generate an ordered list by last accessed time.
+            SortedSet<Content> sorted= new TreeSet<Content>(
+                    new Comparator<Content>()
+                    {
+                        public int compare(Content c1, Content c2)
+                        {
+                            if (c1._lastAccessed<c2._lastAccessed)
+                                return -1;
+                            
+                            if (c1._lastAccessed>c2._lastAccessed)
+                                return 1;
+
+                            if (c1._length<c2._length)
+                                return -1;
+                            
+                            return c1._key.compareTo(c2._key);
+                        }
+                    });
+            for (Content content : _cache.values())
+                sorted.add(content);
+            
+            // Invalidate least recently used first
+            for (Content content : sorted)
+            {
+                if (_cachedFiles.get()<=_maxCachedFiles && _cachedSize.get()<=_maxCacheSize)
+                    break;
+                if (content==_cache.remove(content.getKey()))
+                    content.invalidate();
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected Buffer getIndirectBuffer(Resource resource)
+    {
+        try
+        {
+            int len=(int)resource.length();
+            if (len<0)
+            {
+                LOG.warn("invalid resource: "+String.valueOf(resource)+" "+len);
+                return null;
+            }
+            Buffer buffer = new IndirectNIOBuffer(len);
+            InputStream is = resource.getInputStream();
+            buffer.readFrom(is,len);
+            is.close();
+            return buffer;
+        }
+        catch(IOException e)
+        {
+            LOG.warn(e);
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected Buffer getDirectBuffer(Resource resource)
+    {
+        try
+        {
+            if (_useFileMappedBuffer && resource.getFile()!=null) 
+                return new DirectNIOBuffer(resource.getFile());
+
+            int len=(int)resource.length();
+            if (len<0)
+            {
+                LOG.warn("invalid resource: "+String.valueOf(resource)+" "+len);
+                return null;
+            }
+            Buffer buffer = new DirectNIOBuffer(len);
+            InputStream is = resource.getInputStream();
+            buffer.readFrom(is,len);
+            is.close();
+            return buffer;
+        }
+        catch(IOException e)
+        {
+            LOG.warn(e);
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return "ResourceCache["+_parent+","+_factory+"]@"+hashCode();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /** MetaData associated with a context Resource.
+     */
+    public class Content implements HttpContent
+    {
+        final Resource _resource;
+        final int _length;
+        final String _key;
+        final long _lastModified;
+        final Buffer _lastModifiedBytes;
+        final Buffer _contentType;
+        final Buffer _etagBuffer;
+        
+        volatile long _lastAccessed;
+        AtomicReference<Buffer> _indirectBuffer=new AtomicReference<Buffer>();
+        AtomicReference<Buffer> _directBuffer=new AtomicReference<Buffer>();
+
+        /* ------------------------------------------------------------ */
+        Content(String pathInContext,Resource resource)
+        {
+            _key=pathInContext;
+            _resource=resource;
+
+            _contentType=_mimeTypes.getMimeByExtension(_resource.toString());
+            boolean exists=resource.exists();
+            _lastModified=exists?resource.lastModified():-1;
+            _lastModifiedBytes=_lastModified<0?null:new ByteArrayBuffer(HttpFields.formatDate(_lastModified));
+            
+            _length=exists?(int)resource.length():0;
+            _cachedSize.addAndGet(_length);
+            _cachedFiles.incrementAndGet();
+            _lastAccessed=System.currentTimeMillis();
+            
+            _etagBuffer=_etags?new ByteArrayBuffer(resource.getWeakETag()):null;
+        }
+
+
+        /* ------------------------------------------------------------ */
+        public String getKey()
+        {
+            return _key;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isCached()
+        {
+            return _key!=null;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public boolean isMiss()
+        {
+            return false;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Resource getResource()
+        {
+            return _resource;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getETag()
+        {
+            return _etagBuffer;
+        }
+        
+        /* ------------------------------------------------------------ */
+        boolean isValid()
+        {
+            if (_lastModified==_resource.lastModified() && _length==_resource.length())
+            {
+                _lastAccessed=System.currentTimeMillis();
+                return true;
+            }
+
+            if (this==_cache.remove(_key))
+                invalidate();
+            return false;
+        }
+
+        /* ------------------------------------------------------------ */
+        protected void invalidate()
+        {
+            // Invalidate it
+            _cachedSize.addAndGet(-_length);
+            _cachedFiles.decrementAndGet();
+            _resource.release(); 
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getLastModified()
+        {
+            return _lastModifiedBytes;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getContentType()
+        {
+            return _contentType;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void release()
+        {
+            // don't release while cached. Release when invalidated.
+        }
+
+        /* ------------------------------------------------------------ */
+        public Buffer getIndirectBuffer()
+        {
+            Buffer buffer = _indirectBuffer.get();
+            if (buffer==null)
+            {
+                Buffer buffer2=ResourceCache.this.getIndirectBuffer(_resource);
+                
+                if (buffer2==null)
+                    LOG.warn("Could not load "+this);
+                else if (_indirectBuffer.compareAndSet(null,buffer2))
+                    buffer=buffer2;
+                else
+                    buffer=_indirectBuffer.get();
+            }
+            if (buffer==null)
+                return null;
+            return new View(buffer);
+        }
+        
+
+        /* ------------------------------------------------------------ */
+        public Buffer getDirectBuffer()
+        {
+            Buffer buffer = _directBuffer.get();
+            if (buffer==null)
+            {
+                Buffer buffer2=ResourceCache.this.getDirectBuffer(_resource);
+
+                if (buffer2==null)
+                    LOG.warn("Could not load "+this);
+                else if (_directBuffer.compareAndSet(null,buffer2))
+                    buffer=buffer2;
+                else
+                    buffer=_directBuffer.get();
+            }
+            if (buffer==null)
+                return null;
+                        
+            return new View(buffer);
+        }
+        
+        /* ------------------------------------------------------------ */
+        public long getContentLength()
+        {
+            return _length;
+        }
+
+        /* ------------------------------------------------------------ */
+        public InputStream getInputStream() throws IOException
+        {
+            Buffer indirect = getIndirectBuffer();
+            if (indirect!=null && indirect.array()!=null)
+                return new ByteArrayInputStream(indirect.array(),indirect.getIndex(),indirect.length());
+           
+            return _resource.getInputStream();
+        }   
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return String.format("%s %s %d %s %s",_resource,_resource.exists(),_resource.lastModified(),_contentType,_lastModifiedBytes);
+        }   
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/Response.java b/src/java/org/eclipse/jetty/server/Response.java
new file mode 100644
index 0000000..d9d3a98
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Response.java
@@ -0,0 +1,1307 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpGenerator;
+import org.eclipse.jetty.http.HttpHeaderValues;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.HttpVersions;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.BufferCache.CachedBuffer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.util.ByteArrayISO8859Writer;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/** Response.
+ * <p>
+ * Implements {@link javax.servlet.http.HttpServletResponse} from the <code>javax.servlet.http</code> package.
+ * </p>
+ */
+public class Response implements HttpServletResponse
+{
+    private static final Logger LOG = Log.getLogger(Response.class);
+
+    
+    public static final int
+        NONE=0,
+        STREAM=1,
+        WRITER=2;
+
+    /**
+     * If a header name starts with this string,  the header (stripped of the prefix)
+     * can be set during include using only {@link #setHeader(String, String)} or
+     * {@link #addHeader(String, String)}.
+     */
+    public final static String SET_INCLUDE_HEADER_PREFIX = "org.eclipse.jetty.server.include.";
+
+    /**
+     * If this string is found within the comment of a cookie added with {@link #addCookie(Cookie)}, then the cookie 
+     * will be set as HTTP ONLY.
+     */
+    public final static String HTTP_ONLY_COMMENT="__HTTP_ONLY__";
+    
+    
+    /* ------------------------------------------------------------ */
+    public static Response getResponse(HttpServletResponse response)
+    {
+        if (response instanceof Response)
+            return (Response)response;
+
+        return AbstractHttpConnection.getCurrentConnection().getResponse();
+    }
+    
+    private final AbstractHttpConnection _connection;
+    private int _status=SC_OK;
+    private String _reason;
+    private Locale _locale;
+    private String _mimeType;
+    private CachedBuffer _cachedMimeType;
+    private String _characterEncoding;
+    private boolean _explicitEncoding;
+    private String _contentType;
+    private volatile int _outputState;
+    private PrintWriter _writer;
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public Response(AbstractHttpConnection connection)
+    {
+        _connection=connection;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#reset()
+     */
+    protected void recycle()
+    {
+        _status=SC_OK;
+        _reason=null;
+        _locale=null;
+        _mimeType=null;
+        _cachedMimeType=null;
+        _characterEncoding=null;
+        _explicitEncoding=false;
+        _contentType=null;
+        _writer=null;
+        _outputState=NONE;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
+     */
+    public void addCookie(HttpCookie cookie)
+    {
+        _connection.getResponseFields().addSetCookie(cookie);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
+     */
+    public void addCookie(Cookie cookie)
+    {
+        String comment=cookie.getComment();
+        boolean http_only=false;
+        
+        if (comment!=null)
+        {
+            int i=comment.indexOf(HTTP_ONLY_COMMENT);
+            if (i>=0)
+            {
+                http_only=true;
+                comment=comment.replace(HTTP_ONLY_COMMENT,"").trim();
+                if (comment.length()==0)
+                    comment=null;
+            }
+        }
+        _connection.getResponseFields().addSetCookie(cookie.getName(),
+                cookie.getValue(),
+                cookie.getDomain(),
+                cookie.getPath(),
+                cookie.getMaxAge(),
+                comment,
+                cookie.getSecure(),
+                http_only || cookie.isHttpOnly(),
+                cookie.getVersion());
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String)
+     */
+    public boolean containsHeader(String name)
+    {
+        return _connection.getResponseFields().containsKey(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)
+     */
+    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);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String)
+     */
+    public String encodeRedirectURL(String url)
+    {
+        return encodeURL(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String encodeUrl(String url)
+    {
+        return encodeURL(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String encodeRedirectUrl(String url)
+    {
+        return encodeRedirectURL(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String)
+     */
+    public void sendError(int code, String message) throws IOException
+    {
+    	if (_connection.isIncluding())
+    		return;
+
+        if (isCommitted())
+            LOG.warn("Committed before "+code+" "+message);
+
+        resetBuffer();
+        _characterEncoding=null;
+        setHeader(HttpHeaders.EXPIRES,null);
+        setHeader(HttpHeaders.LAST_MODIFIED,null);
+        setHeader(HttpHeaders.CACHE_CONTROL,null);
+        setHeader(HttpHeaders.CONTENT_TYPE,null);
+        setHeader(HttpHeaders.CONTENT_LENGTH,null);
+
+        _outputState=NONE;
+        setStatus(code,message);
+
+        if (message==null)
+            message=HttpStatus.getMessage(code);
+
+        // If we are allowed to have a body
+        if (code!=SC_NO_CONTENT &&
+            code!=SC_NOT_MODIFIED &&
+            code!=SC_PARTIAL_CONTENT &&
+            code>=SC_OK)
+        {
+            Request request = _connection.getRequest();
+
+            ErrorHandler error_handler = null;
+            ContextHandler.Context context = request.getContext();
+            if (context!=null)
+                error_handler=context.getContextHandler().getErrorHandler();
+            if (error_handler==null)
+                error_handler = _connection.getConnector().getServer().getBean(ErrorHandler.class);
+            if (error_handler!=null)
+            {
+                request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(code));
+                request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message);
+                request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI());
+                request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME,request.getServletName());
+                error_handler.handle(null,_connection.getRequest(),_connection.getRequest(),this );
+            }
+            else
+            {
+                setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
+                setContentType(MimeTypes.TEXT_HTML_8859_1);
+                ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(2048);
+                if (message != null)
+                {
+                    message= StringUtil.replace(message, "&", "&amp;");
+                    message= StringUtil.replace(message, "<", "&lt;");
+                    message= StringUtil.replace(message, ">", "&gt;");
+                }
+                String uri= request.getRequestURI();
+                if (uri!=null)
+                {
+                    uri= StringUtil.replace(uri, "&", "&amp;");
+                    uri= StringUtil.replace(uri, "<", "&lt;");
+                    uri= StringUtil.replace(uri, ">", "&gt;");
+                }
+
+                writer.write("<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n");
+                writer.write("<title>Error ");
+                writer.write(Integer.toString(code));
+                writer.write(' ');
+                if (message==null)
+                    message=HttpStatus.getMessage(code);
+                writer.write(message);
+                writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: ");
+                writer.write(Integer.toString(code));
+                writer.write("</h2>\n<p>Problem accessing ");
+                writer.write(uri);
+                writer.write(". Reason:\n<pre>    ");
+                writer.write(message);
+                writer.write("</pre>");
+                writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>");
+
+                for (int i= 0; i < 20; i++)
+                    writer.write("\n                                                ");
+                writer.write("\n</body>\n</html>\n");
+
+                writer.flush();
+                setContentLength(writer.size());
+                writer.writeTo(getOutputStream());
+                writer.destroy();
+            }
+        }
+        else if (code!=SC_PARTIAL_CONTENT)
+        {
+            _connection.getRequestFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
+            _connection.getRequestFields().remove(HttpHeaders.CONTENT_LENGTH_BUFFER);
+            _characterEncoding=null;
+            _mimeType=null;
+            _cachedMimeType=null;
+        }
+
+        complete();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#sendError(int)
+     */
+    public void sendError(int sc) throws IOException
+    {
+        if (sc==102)
+            sendProcessing();
+        else
+            sendError(sc,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* Send a 102-Processing response.
+     * If the connection is a HTTP connection, the version is 1.1 and the
+     * request has a Expect header starting with 102, then a 102 response is
+     * sent. This indicates that the request still be processed and real response
+     * can still be sent.   This method is called by sendError if it is passed 102.
+     * @see javax.servlet.http.HttpServletResponse#sendError(int)
+     */
+    public void sendProcessing() throws IOException
+    {
+        if (_connection.isExpecting102Processing() && !isCommitted())
+            ((HttpGenerator)_connection.getGenerator()).send1xx(HttpStatus.PROCESSING_102);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String)
+     */
+    public void sendRedirect(String location) throws IOException
+    {
+    	if (_connection.isIncluding())
+    		return;
+
+        if (location==null)
+            throw new IllegalArgumentException();
+
+        if (!URIUtil.hasScheme(location))
+        {
+            StringBuilder buf = _connection.getRequest().getRootURL();
+            if (location.startsWith("/"))
+                buf.append(location);
+            else
+            {
+                String path=_connection.getRequest().getRequestURI();
+                String parent=(path.endsWith("/"))?path:URIUtil.parentPath(path);
+                location=URIUtil.addPaths(parent,location);
+                if(location==null)
+                    throw new IllegalStateException("path cannot be above root");
+                if (!location.startsWith("/"))
+                    buf.append('/');
+                buf.append(location);
+            }
+
+            location=buf.toString();
+            HttpURI uri = new HttpURI(location);
+            String path=uri.getDecodedPath();
+            String canonical=URIUtil.canonicalPath(path);
+            if (canonical==null)
+                throw new IllegalArgumentException();
+            if (!canonical.equals(path))
+            {
+                buf = _connection.getRequest().getRootURL();
+                buf.append(URIUtil.encodePath(canonical));
+                String param=uri.getParam();
+                if (param!=null)
+                {
+                    buf.append(';');
+                    buf.append(param);
+                }
+                String query=uri.getQuery();
+                if (query!=null)
+                {
+                    buf.append('?');
+                    buf.append(query);
+                }
+                String fragment=uri.getFragment();
+                if (fragment!=null)
+                {
+                    buf.append('#');
+                    buf.append(fragment);
+                }
+                location=buf.toString();
+            }
+        }
+        
+        resetBuffer();
+        setHeader(HttpHeaders.LOCATION,location);
+        setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+        complete();
+
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long)
+     */
+    public void setDateHeader(String name, long date)
+    {
+        if (!_connection.isIncluding())
+            _connection.getResponseFields().putDateField(name, date);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long)
+     */
+    public void addDateHeader(String name, long date)
+    {
+        if (!_connection.isIncluding())
+            _connection.getResponseFields().addDateField(name, date);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
+     */
+    public void setHeader(String name, String value)
+    {
+        if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name))
+            setContentType(value);
+        else
+        {
+            if (_connection.isIncluding())
+            {
+                if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
+                    name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
+                else
+                    return;
+            }
+            _connection.getResponseFields().put(name, value);
+            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
+            {
+                if (value==null)
+                    _connection._generator.setContentLength(-1);
+                else
+                    _connection._generator.setContentLength(Long.parseLong(value));
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public Collection<String> getHeaderNames()
+    {
+        final HttpFields fields=_connection.getResponseFields();
+        return fields.getFieldNamesCollection();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public String getHeader(String name)
+    {
+        return _connection.getResponseFields().getStringField(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public Collection<String> getHeaders(String name)
+    {
+        final HttpFields fields=_connection.getResponseFields();
+        Collection<String> i = fields.getValuesCollection(name);
+        if (i==null)
+            return Collections.EMPTY_LIST;
+        return i;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String)
+     */
+    public void addHeader(String name, String value)
+    {
+
+        if (_connection.isIncluding())
+        {
+            if (name.startsWith(SET_INCLUDE_HEADER_PREFIX))
+                name=name.substring(SET_INCLUDE_HEADER_PREFIX.length());
+            else
+                return;
+        }
+
+        if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name))
+        {
+            setContentType(value);
+            return;
+        }
+        
+        _connection.getResponseFields().add(name, value);
+        if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
+            _connection._generator.setContentLength(Long.parseLong(value));
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int)
+     */
+    public void setIntHeader(String name, int value)
+    {
+        if (!_connection.isIncluding())
+        {
+            _connection.getResponseFields().putLongField(name, value);
+            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
+                _connection._generator.setContentLength(value);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int)
+     */
+    public void addIntHeader(String name, int value)
+    {
+        if (!_connection.isIncluding())
+        {
+            _connection.getResponseFields().addLongField(name, value);
+            if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name))
+                _connection._generator.setContentLength(value);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#setStatus(int)
+     */
+    public void setStatus(int sc)
+    {
+        setStatus(sc,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String)
+     */
+    public void setStatus(int sc, String sm)
+    {
+        if (sc<=0)
+            throw new IllegalArgumentException();
+        if (!_connection.isIncluding())
+        {
+            _status=sc;
+            _reason=sm;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getCharacterEncoding()
+     */
+    public String getCharacterEncoding()
+    {
+        if (_characterEncoding==null)
+            _characterEncoding=StringUtil.__ISO_8859_1;
+        return _characterEncoding;
+    }
+    
+    /* ------------------------------------------------------------ */
+    String getSetCharacterEncoding()
+    {
+        return _characterEncoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getContentType()
+     */
+    public String getContentType()
+    {
+        return _contentType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getOutputStream()
+     */
+    public ServletOutputStream getOutputStream() throws IOException
+    {
+        if (_outputState!=NONE && _outputState!=STREAM)
+            throw new IllegalStateException("WRITER");
+
+        ServletOutputStream out = _connection.getOutputStream();
+        _outputState=STREAM;
+        return out;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isWriting()
+    {
+        return _outputState==WRITER;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isOutputing()
+    {
+        return _outputState!=NONE;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getWriter()
+     */
+    public PrintWriter getWriter() throws IOException
+    {
+        if (_outputState!=NONE && _outputState!=WRITER)
+            throw new IllegalStateException("STREAM");
+
+        /* if there is no writer yet */
+        if (_writer==null)
+        {
+            /* get encoding from Content-Type header */
+            String encoding = _characterEncoding;
+
+            if (encoding==null)
+            {
+                /* implementation of educated defaults */
+                if(_cachedMimeType != null)
+                    encoding = MimeTypes.getCharsetFromContentType(_cachedMimeType);
+
+                if (encoding==null)
+                    encoding = StringUtil.__ISO_8859_1;
+
+                setCharacterEncoding(encoding);
+            }
+
+            /* construct Writer using correct encoding */
+            _writer = _connection.getPrintWriter(encoding);
+        }
+        _outputState=WRITER;
+        return _writer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setCharacterEncoding(java.lang.String)
+     */
+    public void setCharacterEncoding(String encoding)
+    {
+    	if (_connection.isIncluding())
+    		return;
+
+        if (this._outputState==0 && !isCommitted())
+        {
+            _explicitEncoding=true;
+
+            if (encoding==null)
+            {
+                // Clear any encoding.
+                if (_characterEncoding!=null)
+                {
+                    _characterEncoding=null;
+                    if (_cachedMimeType!=null)
+                        _contentType=_cachedMimeType.toString();
+                    else if (_mimeType!=null)
+                        _contentType=_mimeType;
+                    else
+                        _contentType=null;
+
+                    if (_contentType==null)
+                        _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
+                    else
+                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                }
+            }
+            else
+            {
+                // No, so just add this one to the mimetype
+                _characterEncoding=encoding;
+                if (_contentType!=null)
+                {
+                    int i0=_contentType.indexOf(';');
+                    if (i0<0)
+                    {
+                        _contentType=null;
+                        if(_cachedMimeType!=null)
+                        {
+                            CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
+                            if (content_type!=null)
+                            {
+                                _contentType=content_type.toString();
+                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
+                            }
+                        }
+
+                        if (_contentType==null)
+                        {
+                            _contentType = _mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                        }
+                    }
+                    else
+                    {
+                        int i1=_contentType.indexOf("charset=",i0);
+                        if (i1<0)
+                        {
+                            _contentType = _contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                        }
+                        else
+                        {
+                            int i8=i1+8;
+                            int i2=_contentType.indexOf(" ",i8);
+                            if (i2<0)
+                                _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                            else
+                                _contentType=_contentType.substring(0,i8)+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ")+_contentType.substring(i2);
+                        }
+                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                    }
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setContentLength(int)
+     */
+    public void setContentLength(int len)
+    {
+        // Protect from setting after committed as default handling
+        // of a servlet HEAD request ALWAYS sets _content length, even
+        // if the getHandling committed the response!
+        if (isCommitted() || _connection.isIncluding())
+            return;
+        _connection._generator.setContentLength(len);
+        if (len>0)
+        {
+            _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
+            if (_connection._generator.isAllContentWritten())
+            {
+                if (_outputState==WRITER)
+                    _writer.close();
+                else if (_outputState==STREAM)
+                {
+                    try
+                    {
+                        getOutputStream().close();
+                    }
+                    catch(IOException e)
+                    {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setContentLength(int)
+     */
+    public void setLongContentLength(long len)
+    {
+        // Protect from setting after committed as default handling
+        // of a servlet HEAD request ALWAYS sets _content length, even
+        // if the getHandling committed the response!
+        if (isCommitted() || _connection.isIncluding())
+        	return;
+        _connection._generator.setContentLength(len);
+        _connection.getResponseFields().putLongField(HttpHeaders.CONTENT_LENGTH, len);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setContentType(java.lang.String)
+     */
+    public void setContentType(String contentType)
+    {
+        if (isCommitted() || _connection.isIncluding())
+            return;
+
+        // Yes this method is horribly complex.... but there are lots of special cases and
+        // as this method is called on every request, it is worth trying to save string creation.
+        //
+
+        if (contentType==null)
+        {
+            if (_locale==null)
+                _characterEncoding=null;
+            _mimeType=null;
+            _cachedMimeType=null;
+            _contentType=null;
+            _connection.getResponseFields().remove(HttpHeaders.CONTENT_TYPE_BUFFER);
+        }
+        else
+        {
+            // Look for encoding in contentType
+            int i0=contentType.indexOf(';');
+
+            if (i0>0)
+            {
+                // we have content type parameters
+
+                // Extract params off mimetype
+                _mimeType=contentType.substring(0,i0).trim();
+                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
+
+                // Look for charset
+                int i1=contentType.indexOf("charset=",i0+1);
+                if (i1>=0)
+                {
+                    _explicitEncoding=true;
+                    int i8=i1+8;
+                    int i2 = contentType.indexOf(' ',i8);
+
+                    if (_outputState==WRITER)
+                    {
+                        // strip the charset and ignore;
+                        if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
+                        {
+                            if (_cachedMimeType!=null)
+                            {
+                                CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
+                                if (content_type!=null)
+                                {
+                                    _contentType=content_type.toString();
+                                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
+                                }
+                                else
+                                {
+                                    _contentType=_mimeType+";charset="+_characterEncoding;
+                                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                                }
+                            }
+                            else
+                            {
+                                _contentType=_mimeType+";charset="+_characterEncoding;
+                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                            }
+                        }
+                        else if (i2<0)
+                        {
+                            _contentType=contentType.substring(0,i1)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                        }
+                        else
+                        {
+                            _contentType=contentType.substring(0,i1)+contentType.substring(i2)+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                        }
+                    }
+                    else if ((i1==i0+1 && i2<0) || (i1==i0+2 && i2<0 && contentType.charAt(i0+1)==' '))
+                    {
+                        // The params are just the char encoding
+                        _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
+                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
+
+                        if (_cachedMimeType!=null)
+                        {
+                            CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
+                            if (content_type!=null)
+                            {
+                                _contentType=content_type.toString();
+                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
+                            }
+                            else
+                            {
+                                _contentType=contentType;
+                                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                            }
+                        }
+                        else
+                        {
+                            _contentType=contentType;
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                        }
+                    }
+                    else if (i2>0)
+                    {
+                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8,i2));
+                        _contentType=contentType;
+                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                    }
+                    else
+                    {
+                        _characterEncoding = QuotedStringTokenizer.unquote(contentType.substring(i8));
+                        _contentType=contentType;
+                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                    }
+                }
+                else // No encoding in the params.
+                {
+                    _cachedMimeType=null;
+                    _contentType=_characterEncoding==null?contentType:contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                }
+            }
+            else // No params at all
+            {
+                _mimeType=contentType;
+                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
+
+                if (_characterEncoding!=null)
+                {
+                    if (_cachedMimeType!=null)
+                    {
+                        CachedBuffer content_type = _cachedMimeType.getAssociate(_characterEncoding);
+                        if (content_type!=null)
+                        {
+                            _contentType=content_type.toString();
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,content_type);
+                        }
+                        else
+                        {
+                            _contentType=_mimeType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                            _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                        }
+                    }
+                    else
+                    {
+                        _contentType=contentType+";charset="+QuotedStringTokenizer.quoteIfNeeded(_characterEncoding,";= ");
+                        _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                    }
+                }
+                else if (_cachedMimeType!=null)
+                {
+                    _contentType=_cachedMimeType.toString();
+                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_cachedMimeType);
+                }
+                else
+                {
+                    _contentType=contentType;
+                    _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setBufferSize(int)
+     */
+    public void setBufferSize(int size)
+    {
+        if (isCommitted() || getContentCount()>0)
+            throw new IllegalStateException("Committed or content written");
+        _connection.getGenerator().increaseContentBufferSize(size);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getBufferSize()
+     */
+    public int getBufferSize()
+    {
+        return _connection.getGenerator().getContentBufferSize();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#flushBuffer()
+     */
+    public void flushBuffer() throws IOException
+    {
+        _connection.flushResponse();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#reset()
+     */
+    public void reset()
+    {
+        resetBuffer();
+        fwdReset();
+        _status=200;
+        _reason=null;
+        
+        HttpFields response_fields=_connection.getResponseFields();
+        
+        response_fields.clear();
+        String connection=_connection.getRequestFields().getStringField(HttpHeaders.CONNECTION_BUFFER);
+        if (connection!=null)
+        {
+            String[] values = connection.split(",");
+            for  (int i=0;values!=null && i<values.length;i++)
+            {
+                CachedBuffer cb = HttpHeaderValues.CACHE.get(values[0].trim());
+
+                if (cb!=null)
+                {
+                    switch(cb.getOrdinal())
+                    {
+                        case HttpHeaderValues.CLOSE_ORDINAL:
+                            response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.CLOSE_BUFFER);
+                            break;
+
+                        case HttpHeaderValues.KEEP_ALIVE_ORDINAL:
+                            if (HttpVersions.HTTP_1_0.equalsIgnoreCase(_connection.getRequest().getProtocol()))
+                                response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.KEEP_ALIVE);
+                            break;
+                        case HttpHeaderValues.TE_ORDINAL:
+                            response_fields.put(HttpHeaders.CONNECTION_BUFFER,HttpHeaderValues.TE);
+                            break;
+                    }
+                }
+            }
+        }
+    }
+    
+
+    public void reset(boolean preserveCookies)
+    { 
+        if (!preserveCookies)
+            reset();
+        else
+        {
+            HttpFields response_fields=_connection.getResponseFields();
+
+            ArrayList<String> cookieValues = new ArrayList<String>(5);
+            Enumeration<String> vals = response_fields.getValues(HttpHeaders.SET_COOKIE);
+            while (vals.hasMoreElements())
+                cookieValues.add((String)vals.nextElement());
+
+            reset();
+
+            for (String v:cookieValues)
+                response_fields.add(HttpHeaders.SET_COOKIE, v);
+        }
+    }
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#reset()
+     */
+    public void fwdReset()
+    {
+        resetBuffer();
+
+        _writer=null;
+        _outputState=NONE;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#resetBuffer()
+     */
+    public void resetBuffer()
+    {
+        if (isCommitted())
+            throw new IllegalStateException("Committed");
+        _connection.getGenerator().resetBuffer();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#isCommitted()
+     */
+    public boolean isCommitted()
+    {
+        return _connection.isResponseCommitted();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#setLocale(java.util.Locale)
+     */
+    public void setLocale(Locale locale)
+    {
+        if (locale == null || isCommitted() ||_connection.isIncluding())
+            return;
+
+        _locale = locale;
+        _connection.getResponseFields().put(HttpHeaders.CONTENT_LANGUAGE_BUFFER,locale.toString().replace('_','-'));
+
+        if (_explicitEncoding || _outputState!=0 )
+            return;
+
+        if (_connection.getRequest().getContext()==null)
+            return;
+
+        String charset = _connection.getRequest().getContext().getContextHandler().getLocaleEncoding(locale);
+
+        if (charset!=null && charset.length()>0)
+        {
+            _characterEncoding=charset;
+
+            /* get current MIME type from Content-Type header */
+            String type=getContentType();
+            if (type!=null)
+            {
+                _characterEncoding=charset;
+                int semi=type.indexOf(';');
+                if (semi<0)
+                {
+                    _mimeType=type;
+                    _contentType= type += ";charset="+charset;
+                }
+                else
+                {
+                    _mimeType=type.substring(0,semi);
+                    _contentType= _mimeType += ";charset="+charset;
+                }
+
+                _cachedMimeType=MimeTypes.CACHE.get(_mimeType);
+                _connection.getResponseFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,_contentType);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletResponse#getLocale()
+     */
+    public Locale getLocale()
+    {
+        if (_locale==null)
+            return Locale.getDefault();
+        return _locale;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The HTTP status code that has been set for this request. This will be <code>200<code>
+     *    ({@link HttpServletResponse#SC_OK}), unless explicitly set through one of the <code>setStatus</code> methods.
+     */
+    public int getStatus()
+    {
+        return _status;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The reason associated with the current {@link #getStatus() status}. This will be <code>null</code>,
+     *    unless one of the <code>setStatus</code> methods have been called.
+     */
+    public String getReason()
+    {
+        return _reason;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void complete()
+        throws IOException
+    {
+        _connection.completeResponse();
+    }
+
+    /* ------------------------------------------------------------- */
+    /**
+     * @return the number of bytes actually written in response body
+     */
+    public long getContentCount()
+    {
+        if (_connection==null || _connection.getGenerator()==null)
+            return -1;
+        return _connection.getGenerator().getContentWritten();
+    }
+
+    /* ------------------------------------------------------------ */
+    public HttpFields getHttpFields()
+    {
+        return _connection.getResponseFields();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return "HTTP/1.1 "+_status+" "+ (_reason==null?"":_reason) +System.getProperty("line.separator")+
+        _connection.getResponseFields().toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class NullOutput extends ServletOutputStream
+    {
+        @Override
+        public void write(int b) throws IOException
+        {
+        }
+
+        @Override
+        public void print(String s) throws IOException
+        {
+        }
+
+        @Override
+        public void println(String s) throws IOException
+        {
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException
+        {
+        }
+
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/Server.java b/src/java/org/eclipse/jetty/server/Server.java
new file mode 100644
index 0000000..745f232
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/Server.java
@@ -0,0 +1,662 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Enumeration;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpGenerator;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiException;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.component.Container;
+import org.eclipse.jetty.util.component.Destroyable;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.ShutdownThread;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/* ------------------------------------------------------------ */
+/** Jetty HTTP Servlet Server.
+ * This class is the main class for the Jetty HTTP Servlet server.
+ * It aggregates Connectors (HTTP request receivers) and request Handlers.
+ * The server is itself a handler and a ThreadPool.  Connectors use the ThreadPool methods
+ * to run jobs that will eventually call the handle method.
+ *
+ *  @org.apache.xbean.XBean  description="Creates an embedded Jetty web server"
+ */
+public class Server extends HandlerWrapper implements Attributes
+{
+    private static final Logger LOG = Log.getLogger(Server.class);
+
+    private static final String __version;
+    static
+    {
+        if (Server.class.getPackage()!=null &&
+            "Eclipse.org - Jetty".equals(Server.class.getPackage().getImplementationVendor()) &&
+             Server.class.getPackage().getImplementationVersion()!=null)
+            __version=Server.class.getPackage().getImplementationVersion();
+        else
+            __version=System.getProperty("jetty.version","8.y.z-SNAPSHOT");
+    }
+
+    private final Container _container=new Container();
+    private final AttributesMap _attributes = new AttributesMap();
+    private ThreadPool _threadPool;
+    private Connector[] _connectors;
+    private SessionIdManager _sessionIdManager;
+    private boolean _sendServerVersion = true; //send Server: header
+    private boolean _sendDateHeader = false; //send Date: header
+    private int _graceful=0;
+    private boolean _stopAtShutdown;
+    private boolean _dumpAfterStart=false;
+    private boolean _dumpBeforeStop=false;
+    private boolean _uncheckedPrintWriter=false;
+
+
+    /* ------------------------------------------------------------ */
+    public Server()
+    {
+        setServer(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convenience constructor
+     * Creates server and a {@link SelectChannelConnector} at the passed port.
+     */
+    public Server(int port)
+    {
+        setServer(this);
+
+        Connector connector=new SelectChannelConnector();
+        connector.setPort(port);
+        setConnectors(new Connector[]{connector});
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convenience constructor
+     * Creates server and a {@link SelectChannelConnector} at the passed address.
+     */
+    public Server(InetSocketAddress addr)
+    {
+        setServer(this);
+
+        Connector connector=new SelectChannelConnector();
+        connector.setHost(addr.getHostName());
+        connector.setPort(addr.getPort());
+        setConnectors(new Connector[]{connector});
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public static String getVersion()
+    {
+        return __version;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the container.
+     */
+    public Container getContainer()
+    {
+        return _container;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getStopAtShutdown()
+    {
+        return _stopAtShutdown;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setStopAtShutdown(boolean stop)
+    {
+        //if we now want to stop
+        if (stop)
+        {
+            //and we weren't stopping before
+            if (!_stopAtShutdown)
+            {  
+                //only register to stop if we're already started (otherwise we'll do it in doStart())
+                if (isStarted()) 
+                    ShutdownThread.register(this);
+            }
+        }
+        else
+            ShutdownThread.deregister(this);
+        
+        _stopAtShutdown=stop;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the connectors.
+     */
+    public Connector[] getConnectors()
+    {
+        return _connectors;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addConnector(Connector connector)
+    {
+        setConnectors((Connector[])LazyList.addToArray(getConnectors(), connector, Connector.class));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Conveniance method which calls {@link #getConnectors()} and {@link #setConnectors(Connector[])} to
+     * remove a connector.
+     * @param connector The connector to remove.
+     */
+    public void removeConnector(Connector connector) {
+        setConnectors((Connector[])LazyList.removeFromArray (getConnectors(), connector));
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the connectors for this server.
+     * Each connector has this server set as it's ThreadPool and its Handler.
+     * @param connectors The connectors to set.
+     */
+    public void setConnectors(Connector[] connectors)
+    {
+        if (connectors!=null)
+        {
+            for (int i=0;i<connectors.length;i++)
+                connectors[i].setServer(this);
+        }
+
+        _container.update(this, _connectors, connectors, "connector");
+        _connectors = connectors;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the threadPool.
+     */
+    public ThreadPool getThreadPool()
+    {
+        return _threadPool;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param threadPool The threadPool to set.
+     */
+    public void setThreadPool(ThreadPool threadPool)
+    {
+        if (_threadPool!=null)
+            removeBean(_threadPool);
+        _container.update(this, _threadPool, threadPool, "threadpool",false);
+        _threadPool = threadPool;
+        if (_threadPool!=null)
+            addBean(_threadPool);
+    }
+
+    /**
+     * @return true if {@link #dumpStdErr()} is called after starting
+     */
+    public boolean isDumpAfterStart()
+    {
+        return _dumpAfterStart;
+    }
+
+    /**
+     * @param dumpAfterStart true if {@link #dumpStdErr()} is called after starting
+     */
+    public void setDumpAfterStart(boolean dumpAfterStart)
+    {
+        _dumpAfterStart = dumpAfterStart;
+    }
+
+    /**
+     * @return true if {@link #dumpStdErr()} is called before stopping
+     */
+    public boolean isDumpBeforeStop()
+    {
+        return _dumpBeforeStop;
+    }
+
+    /**
+     * @param dumpBeforeStop true if {@link #dumpStdErr()} is called before stopping
+     */
+    public void setDumpBeforeStop(boolean dumpBeforeStop)
+    {
+        _dumpBeforeStop = dumpBeforeStop;
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (getStopAtShutdown())
+        {
+            ShutdownThread.register(this);    
+        }
+        
+        ShutdownMonitor.getInstance().start(); // initialize
+
+        LOG.info("jetty-"+__version);
+        HttpGenerator.setServerVersion(__version);
+        
+        MultiException mex=new MultiException();
+
+        if (_threadPool==null)
+            setThreadPool(new QueuedThreadPool());
+
+        try
+        {
+            super.doStart();
+        }
+        catch(Throwable e)
+        {
+            mex.add(e);
+        }
+
+        if (_connectors!=null && mex.size()==0)
+        {
+            for (int i=0;i<_connectors.length;i++)
+            {
+                try{_connectors[i].start();}
+                catch(Throwable e)
+                {
+                    mex.add(e);
+                }
+            }
+        }
+
+        if (isDumpAfterStart())
+            dumpStdErr();
+
+        mex.ifExceptionThrow();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        if (isDumpBeforeStop())
+            dumpStdErr();
+
+        MultiException mex=new MultiException();
+
+        if (_graceful>0)
+        {
+            if (_connectors!=null)
+            {
+                for (int i=_connectors.length;i-->0;)
+                {
+                    LOG.info("Graceful shutdown {}",_connectors[i]);
+                    try{_connectors[i].close();}catch(Throwable e){mex.add(e);}
+                }
+            }
+
+            Handler[] contexts = getChildHandlersByClass(Graceful.class);
+            for (int c=0;c<contexts.length;c++)
+            {
+                Graceful context=(Graceful)contexts[c];
+                LOG.info("Graceful shutdown {}",context);
+                context.setShutdown(true);
+            }
+            Thread.sleep(_graceful);
+        }
+
+        if (_connectors!=null)
+        {
+            for (int i=_connectors.length;i-->0;)
+                try{_connectors[i].stop();}catch(Throwable e){mex.add(e);}
+        }
+
+        try {super.doStop(); } catch(Throwable e) { mex.add(e);}
+
+        mex.ifExceptionThrow();
+
+        if (getStopAtShutdown())
+            ShutdownThread.deregister(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* Handle a request from a connection.
+     * Called to handle a request on the connection when either the header has been received,
+     * or after the entire request has been received (for short requests of known length), or
+     * on the dispatch of an async request.
+     */
+    public void handle(AbstractHttpConnection connection) throws IOException, ServletException
+    {
+        final String target=connection.getRequest().getPathInfo();
+        final Request request=connection.getRequest();
+        final Response response=connection.getResponse();
+
+        if (LOG.isDebugEnabled())
+        {
+            LOG.debug("REQUEST "+target+" on "+connection);
+            handle(target, request, request, response);
+            LOG.debug("RESPONSE "+target+"  "+connection.getResponse().getStatus()+" handled="+request.isHandled());
+        }
+        else
+            handle(target, request, request, response);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* Handle a request from a connection.
+     * Called to handle a request on the connection when either the header has been received,
+     * or after the entire request has been received (for short requests of known length), or
+     * on the dispatch of an async request.
+     */
+    public void handleAsync(AbstractHttpConnection connection) throws IOException, ServletException
+    {
+        final AsyncContinuation async = connection.getRequest().getAsyncContinuation();
+        final AsyncContinuation.AsyncEventState state = async.getAsyncEventState();
+
+        final Request baseRequest=connection.getRequest();
+        final String path=state.getPath();
+
+        if (path!=null)
+        {
+            // this is a dispatch with a path
+            final String contextPath=state.getServletContext().getContextPath();
+            HttpURI uri = new HttpURI(URIUtil.addPaths(contextPath,path));
+            baseRequest.setUri(uri);
+            baseRequest.setRequestURI(null);
+            baseRequest.setPathInfo(baseRequest.getRequestURI());
+            if (uri.getQuery()!=null)
+                baseRequest.mergeQueryString(uri.getQuery()); //we have to assume dispatch path and query are UTF8
+        }
+
+        final String target=baseRequest.getPathInfo();
+        final HttpServletRequest request=(HttpServletRequest)async.getRequest();
+        final HttpServletResponse response=(HttpServletResponse)async.getResponse();
+
+        if (LOG.isDebugEnabled())
+        {
+            LOG.debug("REQUEST "+target+" on "+connection);
+            handle(target, baseRequest, request, response);
+            LOG.debug("RESPONSE "+target+"  "+connection.getResponse().getStatus());
+        }
+        else
+            handle(target, baseRequest, request, response);
+
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void join() throws InterruptedException
+    {
+        getThreadPool().join();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the sessionIdManager.
+     */
+    public SessionIdManager getSessionIdManager()
+    {
+        return _sessionIdManager;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * @param sessionIdManager The sessionIdManager to set.
+     */
+    public void setSessionIdManager(SessionIdManager sessionIdManager)
+    {
+        if (_sessionIdManager!=null)
+            removeBean(_sessionIdManager);
+        _container.update(this, _sessionIdManager, sessionIdManager, "sessionIdManager",false);
+        _sessionIdManager = sessionIdManager;
+        if (_sessionIdManager!=null)
+            addBean(_sessionIdManager);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setSendServerVersion (boolean sendServerVersion)
+    {
+        _sendServerVersion = sendServerVersion;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getSendServerVersion()
+    {
+        return _sendServerVersion;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param sendDateHeader
+     */
+    public void setSendDateHeader(boolean sendDateHeader)
+    {
+        _sendDateHeader = sendDateHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getSendDateHeader()
+    {
+        return _sendDateHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     */
+    @Deprecated
+    public int getMaxCookieVersion()
+    {
+        return 1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     */
+    @Deprecated
+    public void setMaxCookieVersion(int maxCookieVersion)
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add a LifeCycle object to be started/stopped
+     * along with the Server.
+     * @deprecated Use {@link #addBean(Object)}
+     * @param c
+     */
+    @Deprecated
+    public void addLifeCycle (LifeCycle c)
+    {
+        addBean(c);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add an associated bean.
+     * The bean will be added to the servers {@link Container}
+     * and if it is a {@link LifeCycle} instance, it will be
+     * started/stopped along with the Server. Any beans that are also
+     * {@link Destroyable}, will be destroyed with the server.
+     * @param o the bean object to add
+     */
+    @Override
+    public boolean addBean(Object o)
+    {
+        if (super.addBean(o))
+        {
+            _container.addBean(o);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Remove a LifeCycle object to be started/stopped
+     * along with the Server
+     * @deprecated Use {@link #removeBean(Object)}
+     */
+    @Deprecated
+    public void removeLifeCycle (LifeCycle c)
+    {
+        removeBean(c);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Remove an associated bean.
+     */
+    @Override
+    public boolean removeBean (Object o)
+    {
+        if (super.removeBean(o))
+        {
+            _container.removeBean(o);
+            return true;
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.util.AttributesMap#clearAttributes()
+     */
+    public void clearAttributes()
+    {
+        _attributes.clearAttributes();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.util.AttributesMap#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _attributes.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.util.AttributesMap#getAttributeNames()
+     */
+    public Enumeration getAttributeNames()
+    {
+        return AttributesMap.getAttributeNamesCopy(_attributes);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.util.AttributesMap#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _attributes.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.util.AttributesMap#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        _attributes.setAttribute(name, attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the graceful
+     */
+    public int getGracefulShutdown()
+    {
+        return _graceful;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set graceful shutdown timeout.  If set, the internal <code>doStop()</code> method will not immediately stop the
+     * server. Instead, all {@link Connector}s will be closed so that new connections will not be accepted
+     * and all handlers that implement {@link Graceful} will be put into the shutdown mode so that no new requests
+     * will be accepted, but existing requests can complete.  The server will then wait the configured timeout
+     * before stopping.
+     * @param timeoutMS the milliseconds to wait for existing request to complete before stopping the server.
+     *
+     */
+    public void setGracefulShutdown(int timeoutMS)
+    {
+        _graceful=timeoutMS;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return this.getClass().getName()+"@"+Integer.toHexString(hashCode());
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void dump(Appendable out,String indent) throws IOException
+    {
+        dumpThis(out);
+        dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors));
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isUncheckedPrintWriter()
+    {
+        return _uncheckedPrintWriter;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setUncheckedPrintWriter(boolean unchecked)
+    {
+        _uncheckedPrintWriter=unchecked;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* A handler that can be gracefully shutdown.
+     * Called by doStop if a {@link #setGracefulShutdown} period is set.
+     * TODO move this somewhere better
+     */
+    public interface Graceful extends Handler
+    {
+        public void setShutdown(boolean shutdown);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void main(String...args) throws Exception
+    {
+        System.err.println(getVersion());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java b/src/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java
new file mode 100644
index 0000000..1da30a3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ServletRequestHttpWrapper.java
@@ -0,0 +1,212 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Enumeration;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
+
+/* ------------------------------------------------------------ */
+/** Class to tunnel a ServletRequest via a HttpServletRequest
+ */
+public class ServletRequestHttpWrapper extends ServletRequestWrapper implements HttpServletRequest
+{
+    public ServletRequestHttpWrapper(ServletRequest request)
+    {
+        super(request);
+    }
+
+    public String getAuthType()
+    {
+        return null;
+    }
+
+    public Cookie[] getCookies()
+    {
+        return null;
+    }
+
+    public long getDateHeader(String name)
+    {
+        return 0;
+    }
+
+    public String getHeader(String name)
+    {
+        return null;
+    }
+
+    public Enumeration getHeaders(String name)
+    {
+        return null;
+    }
+
+    public Enumeration getHeaderNames()
+    {
+        return null;
+    }
+
+    public int getIntHeader(String name)
+    {
+        return 0;
+    }
+
+    public String getMethod()
+    {
+        return null;
+    }
+
+    public String getPathInfo()
+    {
+        return null;
+    }
+
+    public String getPathTranslated()
+    {
+        return null;
+    }
+
+    public String getContextPath()
+    {
+        return null;
+    }
+
+    public String getQueryString()
+    {
+        return null;
+    }
+
+    public String getRemoteUser()
+    {
+        return null;
+    }
+
+    public boolean isUserInRole(String role)
+    {
+        return false;
+    }
+
+    public Principal getUserPrincipal()
+    {
+        return null;
+    }
+
+    public String getRequestedSessionId()
+    {
+        return null;
+    }
+
+    public String getRequestURI()
+    {
+        return null;
+    }
+
+    public StringBuffer getRequestURL()
+    {
+        return null;
+    }
+
+    public String getServletPath()
+    {
+        return null;
+    }
+
+    public HttpSession getSession(boolean create)
+    {
+        return null;
+    }
+
+    public HttpSession getSession()
+    {
+        return null;
+    }
+
+    public boolean isRequestedSessionIdValid()
+    {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromCookie()
+    {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromURL()
+    {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromUrl()
+    {
+        return false;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletRequest#authenticate(javax.servlet.http.HttpServletResponse)
+     */
+    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException
+    {
+        return false;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletRequest#getPart(java.lang.String)
+     */
+    public Part getPart(String name) throws IOException, ServletException
+    {
+        return null;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletRequest#getParts()
+     */
+    public Collection<Part> getParts() throws IOException, ServletException
+    {
+        return null;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletRequest#login(java.lang.String, java.lang.String)
+     */
+    public void login(String username, String password) throws ServletException
+    {
+
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletRequest#logout()
+     */
+    public void logout() throws ServletException
+    {
+        
+    }
+
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java b/src/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java
new file mode 100644
index 0000000..f98cd59
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ServletResponseHttpWrapper.java
@@ -0,0 +1,145 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.util.Collection;
+
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+
+/* ------------------------------------------------------------ */
+/** Wrapper to tunnel a ServletResponse via a HttpServletResponse
+ */
+public class ServletResponseHttpWrapper extends ServletResponseWrapper implements HttpServletResponse
+{
+    public ServletResponseHttpWrapper(ServletResponse response)
+    {
+        super(response);
+    }
+
+    public void addCookie(Cookie cookie)
+    {        
+    }
+
+    public boolean containsHeader(String name)
+    {
+        return false;
+    }
+
+    public String encodeURL(String url)
+    {
+        return null;
+    }
+
+    public String encodeRedirectURL(String url)
+    {
+        return null;
+    }
+
+    public String encodeUrl(String url)
+    {
+        return null;
+    }
+
+    public String encodeRedirectUrl(String url)
+    {
+        return null;
+    }
+
+    public void sendError(int sc, String msg) throws IOException
+    {        
+    }
+
+    public void sendError(int sc) throws IOException
+    {        
+    }
+
+    public void sendRedirect(String location) throws IOException
+    {        
+    }
+
+    public void setDateHeader(String name, long date)
+    {        
+    }
+
+    public void addDateHeader(String name, long date)
+    {        
+    }
+
+    public void setHeader(String name, String value)
+    {        
+    }
+
+    public void addHeader(String name, String value)
+    {        
+    }
+
+    public void setIntHeader(String name, int value)
+    {        
+    }
+
+    public void addIntHeader(String name, int value)
+    {        
+    }
+
+    public void setStatus(int sc)
+    {        
+    }
+
+    public void setStatus(int sc, String sm)
+    {        
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletResponse#getHeader(java.lang.String)
+     */
+    public String getHeader(String name)
+    {
+        return null;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletResponse#getHeaderNames()
+     */
+    public Collection<String> getHeaderNames()
+    {
+        return null;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletResponse#getHeaders(java.lang.String)
+     */
+    public Collection<String> getHeaders(String name)
+    {
+        return null;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpServletResponse#getStatus()
+     */
+    public int getStatus()
+    {
+        return 0;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/SessionIdManager.java b/src/java/org/eclipse/jetty/server/SessionIdManager.java
new file mode 100644
index 0000000..62a9304
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/SessionIdManager.java
@@ -0,0 +1,81 @@
+//
+//  ========================================================================
+//  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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/** Session ID Manager.
+ * Manages session IDs across multiple contexts.
+ */
+public interface SessionIdManager extends LifeCycle
+{
+    /**
+     * @param id The session ID without any cluster node extension
+     * @return True if the session ID is in use by at least one context.
+     */
+    public boolean idInUse(String id);
+    
+    /**
+     * Add a session to the list of known sessions for a given ID.
+     * @param session The session
+     */
+    public void addSession(HttpSession session);
+    
+    /**
+     * Remove session from the list of known sessions for a given ID.
+     * @param session
+     */
+    public void removeSession(HttpSession session);
+    
+    /**
+     * Call {@link HttpSession#invalidate()} on all known sessions for the given id.
+     * @param id The session ID without any cluster node extension
+     */
+    public void invalidateAll(String id);
+    
+    /**
+     * @param request
+     * @param created
+     * @return the new session id
+     */
+    public String newSessionId(HttpServletRequest request,long created);
+    
+    public String getWorkerName();
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Get a cluster ID from a node ID.
+     * Strip node identifier from a located session ID.
+     * @param nodeId
+     * @return the cluster id
+     */
+    public String getClusterId(String nodeId);
+    
+    /* ------------------------------------------------------------ */
+    /** Get a node ID from a cluster ID and a request
+     * @param clusterId The ID of the session
+     * @param request The request that for the session (or null)
+     * @return The session ID qualified with the node ID.
+     */
+    public String getNodeId(String clusterId,HttpServletRequest request);
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/SessionManager.java b/src/java/org/eclipse/jetty/server/SessionManager.java
new file mode 100644
index 0000000..38e3f36
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/SessionManager.java
@@ -0,0 +1,307 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/ShutdownMonitor.java b/src/java/org/eclipse/jetty/server/ShutdownMonitor.java
new file mode 100644
index 0000000..36d3cd7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ShutdownMonitor.java
@@ -0,0 +1,384 @@
+//
+//  ========================================================================
+//  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.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Properties;
+
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.thread.ShutdownThread;
+
+/**
+ * Shutdown/Stop Monitor thread.
+ * <p>
+ * This thread listens on the port specified by the STOP.PORT system parameter (defaults to -1 for not listening) for request authenticated with the key given
+ * by the STOP.KEY system parameter (defaults to "eclipse") for admin requests.
+ * <p>
+ * If the stop port is set to zero, then a random port is assigned and the port number is printed to stdout.
+ * <p>
+ * Commands "stop" and "status" are currently supported.
+ */
+public class ShutdownMonitor 
+{
+    // Implementation of safe lazy init, using Initialization on Demand Holder technique.
+    static class Holder
+    {
+        static ShutdownMonitor instance = new ShutdownMonitor();
+    }
+
+    public static ShutdownMonitor getInstance()
+    {
+        return Holder.instance;
+    }
+
+    /**
+     * ShutdownMonitorThread
+     *
+     * Thread for listening to STOP.PORT for command to stop Jetty.
+     * If ShowndownMonitor.exitVm is true, then Sytem.exit will also be
+     * called after the stop.
+     *
+     */
+    public class ShutdownMonitorThread extends Thread
+    {
+
+        public ShutdownMonitorThread ()
+        {
+            setDaemon(true);
+            setName("ShutdownMonitor");
+        }
+        
+        @Override
+        public void run()
+        {
+            if (serverSocket == null)
+            {
+                return;
+            }
+
+            while (serverSocket != null)
+            {
+                Socket socket = null;
+                try
+                {
+                    socket = serverSocket.accept();
+
+                    LineNumberReader lin = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
+                    String receivedKey = lin.readLine();
+                    if (!key.equals(receivedKey))
+                    {
+                        System.err.println("Ignoring command with incorrect key");
+                        continue;
+                    }
+
+                    OutputStream out = socket.getOutputStream();
+
+                    String cmd = lin.readLine();
+                    debug("command=%s",cmd);
+                    if ("stop".equals(cmd))
+                    {
+                        // Graceful Shutdown
+                        debug("Issuing graceful shutdown..");
+                        ShutdownThread.getInstance().run();
+
+                        // Reply to client
+                        debug("Informing client that we are stopped.");
+                        out.write("Stopped\r\n".getBytes(StringUtil.__UTF8));
+                        out.flush();
+
+                        // Shutdown Monitor
+                        debug("Shutting down monitor");
+                        close(socket);
+                        socket = null;
+                        close(serverSocket);
+                        serverSocket = null;
+
+                        if (exitVm)
+                        {
+                            // Kill JVM
+                            debug("Killing JVM");
+                            System.exit(0);
+                        }
+                    }
+                    else if ("status".equals(cmd))
+                    {
+                        // Reply to client
+                        out.write("OK\r\n".getBytes(StringUtil.__UTF8));
+                        out.flush();
+                    }
+                }
+                catch (Exception e)
+                {
+                    debug(e);
+                    System.err.println(e.toString());
+                }
+                finally
+                {
+                    close(socket);
+                    socket = null;
+                }
+            }
+        }
+        
+        public void start()
+        {
+            if (isAlive())
+            {
+                System.err.printf("ShutdownMonitorThread already started");
+                return; // cannot start it again
+            }
+
+            startListenSocket();
+            
+            if (serverSocket == null)
+            {
+                return;
+            }
+            if (DEBUG)
+                System.err.println("Starting ShutdownMonitorThread");
+            super.start();
+        }
+        
+        private void startListenSocket()
+        {
+            if (port < 0)
+            {            
+                if (DEBUG)
+                    System.err.println("ShutdownMonitor not in use (port < 0): " + port);
+                return;
+            }
+
+            try
+            {
+                serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
+                if (port == 0)
+                {
+                    // server assigned port in use
+                    port = serverSocket.getLocalPort();
+                    System.out.printf("STOP.PORT=%d%n",port);
+                }
+
+                if (key == null)
+                {
+                    // create random key
+                    key = Long.toString((long)(Long.MAX_VALUE * Math.random() + this.hashCode() + System.currentTimeMillis()),36);
+                    System.out.printf("STOP.KEY=%s%n",key);
+                }
+            }
+            catch (Exception e)
+            {
+                debug(e);
+                System.err.println("Error binding monitor port " + port + ": " + e.toString());
+                serverSocket = null;
+            }
+            finally
+            {
+                // establish the port and key that are in use
+                debug("STOP.PORT=%d",port);
+                debug("STOP.KEY=%s",key);
+                debug("%s",serverSocket);
+            }
+        }
+
+    }
+    
+    private boolean DEBUG;
+    private int port;
+    private String key;
+    private boolean exitVm;
+    private ServerSocket serverSocket;
+    private ShutdownMonitorThread thread;
+    
+    
+
+    /**
+     * Create a ShutdownMonitor using configuration from the System properties.
+     * <p>
+     * <code>STOP.PORT</code> = the port to listen on (empty, null, or values less than 0 disable the stop ability)<br>
+     * <code>STOP.KEY</code> = the magic key/passphrase to allow the stop (defaults to "eclipse")<br>
+     * <p>
+     * Note: server socket will only listen on localhost, and a successful stop will issue a System.exit() call.
+     */
+    private ShutdownMonitor()
+    {
+        Properties props = System.getProperties();
+
+        this.DEBUG = props.containsKey("DEBUG");
+
+        // Use values passed thru via /jetty-start/
+        this.port = Integer.parseInt(props.getProperty("STOP.PORT","-1"));
+        this.key = props.getProperty("STOP.KEY",null);
+        this.exitVm = true;
+    }
+
+    private void close(ServerSocket server)
+    {
+        if (server == null)
+        {
+            return;
+        }
+
+        try
+        {
+            server.close();
+        }
+        catch (IOException ignore)
+        {
+            /* ignore */
+        }
+    }
+
+    private void close(Socket socket)
+    {
+        if (socket == null)
+        {
+            return;
+        }
+
+        try
+        {
+            socket.close();
+        }
+        catch (IOException ignore)
+        {
+            /* ignore */
+        }
+    }
+
+    private void debug(String format, Object... args)
+    {
+        if (DEBUG)
+        {
+            System.err.printf("[ShutdownMonitor] " + format + "%n",args);
+        }
+    }
+
+    private void debug(Throwable t)
+    {
+        if (DEBUG)
+        {
+            t.printStackTrace(System.err);
+        }
+    }
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public int getPort()
+    {
+        return port;
+    }
+
+    public ServerSocket getServerSocket()
+    {
+        return serverSocket;
+    }
+
+    public boolean isExitVm()
+    {
+        return exitVm;
+    }
+
+
+    public void setDebug(boolean flag)
+    {
+        this.DEBUG = flag;
+    }
+
+    public void setExitVm(boolean exitVm)
+    {
+        synchronized (this)
+        {
+            if (thread != null && thread.isAlive())
+            {
+                throw new IllegalStateException("ShutdownMonitorThread already started");
+            }
+            this.exitVm = exitVm;
+        }
+    }
+
+    public void setKey(String key)
+    {
+        synchronized (this)
+        {
+            if (thread != null && thread.isAlive())
+            {
+                throw new IllegalStateException("ShutdownMonitorThread already started");
+            }
+            this.key = key;
+        }
+    }
+
+    public void setPort(int port)
+    {
+        synchronized (this)
+        {
+            if (thread != null && thread.isAlive())
+            {
+                throw new IllegalStateException("ShutdownMonitorThread already started");
+            }
+            this.port = port;
+        }
+    }
+
+    protected void start() throws Exception
+    {
+        ShutdownMonitorThread t = null;
+        synchronized (this)
+        {
+            if (thread != null && thread.isAlive())
+            {
+                System.err.printf("ShutdownMonitorThread already started");
+                return; // cannot start it again
+            }
+         
+            thread = new ShutdownMonitorThread();
+            t = thread;
+        }
+         
+        if (t != null)
+            t.start();
+    }
+
+
+    protected boolean isAlive ()
+    {
+        boolean result = false;
+        synchronized (this)
+        {
+            result = (thread != null && thread.isAlive());
+        }
+        return result;
+    }
+    
+ 
+    @Override
+    public String toString()
+    {
+        return String.format("%s[port=%d]",this.getClass().getName(),port);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/UserIdentity.java b/src/java/org/eclipse/jetty/server/UserIdentity.java
new file mode 100644
index 0000000..4ebb5fc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/UserIdentity.java
@@ -0,0 +1,116 @@
+//
+//  ========================================================================
+//  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.security.Principal;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+
+/* ------------------------------------------------------------ */
+/** User object that encapsulates user identity and operations such as run-as-role actions, 
+ * checking isUserInRole and getUserPrincipal.
+ *
+ * Implementations of UserIdentity should be immutable so that they may be
+ * cached by Authenticators and LoginServices.
+ *
+ */
+public interface UserIdentity
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The user subject
+     */
+    Subject getSubject();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The user principal
+     */
+    Principal getUserPrincipal();
+
+    /* ------------------------------------------------------------ */
+    /** Check if the user is in a role.
+     * This call is used to satisfy authorization calls from 
+     * container code which will be using translated role names.
+     * @param role A role name.
+     * @param scope
+     * @return True if the user can act in that role.
+     */
+    boolean isUserInRole(String role, Scope scope);
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * A UserIdentity Scope.
+     * A scope is the environment in which a User Identity is to 
+     * be interpreted. Typically it is set by the target servlet of 
+     * a request.
+     */
+    interface Scope
+    {
+        /* ------------------------------------------------------------ */
+        /**
+         * @return The context path that the identity is being considered within
+         */
+        String getContextPath();
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * @return The name of the identity context. Typically this is the servlet name.
+         */
+        String getName();
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * @return A map of role reference names that converts from names used by application code
+         * to names used by the context deployment.
+         */
+        Map<String,String> getRoleRefMap();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public interface UnauthenticatedUserIdentity extends UserIdentity
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public static final UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity()
+    {
+        public Subject getSubject()
+        {
+            return null;
+        }
+        
+        public Principal getUserPrincipal()
+        {
+            return null;
+        }
+        
+        public boolean isUserInRole(String role, Scope scope)
+        {
+            return false;
+        }
+        
+        @Override
+        public String toString()
+        {
+            return "UNAUTHENTICATED";
+        }
+    };
+}
diff --git a/src/java/org/eclipse/jetty/server/bio/SocketConnector.java b/src/java/org/eclipse/jetty/server/bio/SocketConnector.java
new file mode 100644
index 0000000..337af11
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/bio/SocketConnector.java
@@ -0,0 +1,325 @@
+//
+//  ========================================================================
+//  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.bio;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.server.AbstractConnector;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.BlockingHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------------------------- */
+/**  Socket Connector.
+ * This connector implements a traditional blocking IO and threading model.
+ * Normal JRE sockets are used and a thread is allocated per connection.
+ * Buffers are managed so that large buffers are only allocated to active connections.
+ *
+ * This Connector should only be used if NIO is not available.
+ *
+ * @org.apache.xbean.XBean element="bioConnector" description="Creates a BIO based socket connector"
+ *
+ *
+ */
+public class SocketConnector extends AbstractConnector
+{
+    private static final Logger LOG = Log.getLogger(SocketConnector.class);
+
+    protected ServerSocket _serverSocket;
+    protected final Set<EndPoint> _connections;
+    protected volatile int _localPort=-1;
+
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     *
+     */
+    public SocketConnector()
+    {
+        _connections=new HashSet<EndPoint>();
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object getConnection()
+    {
+        return _serverSocket;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void open() throws IOException
+    {
+        // Create a new server socket and set to non blocking mode
+        if (_serverSocket==null || _serverSocket.isClosed())
+        _serverSocket= newServerSocket(getHost(),getPort(),getAcceptQueueSize());
+        _serverSocket.setReuseAddress(getReuseAddress());
+        _localPort=_serverSocket.getLocalPort();
+        if (_localPort<=0)
+            throw new IllegalStateException("port not allocated for "+this);
+
+    }
+
+    /* ------------------------------------------------------------ */
+    protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
+    {
+        ServerSocket ss= host==null?
+            new ServerSocket(port,backlog):
+            new ServerSocket(port,backlog,InetAddress.getByName(host));
+
+        return ss;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void close() throws IOException
+    {
+        if (_serverSocket!=null)
+            _serverSocket.close();
+        _serverSocket=null;
+        _localPort=-2;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void accept(int acceptorID)
+    	throws IOException, InterruptedException
+    {
+        Socket socket = _serverSocket.accept();
+        configure(socket);
+
+        ConnectorEndPoint connection=new ConnectorEndPoint(socket);
+        connection.dispatch();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Allows subclass to override Conection if required.
+     */
+    protected Connection newConnection(EndPoint endpoint)
+    {
+        return new BlockingHttpConnection(this, endpoint, getServer());
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void customize(EndPoint endpoint, Request request)
+        throws IOException
+    {
+        ConnectorEndPoint connection = (ConnectorEndPoint)endpoint;
+        int lrmit = isLowResources()?_lowResourceMaxIdleTime:_maxIdleTime;
+        connection.setMaxIdleTime(lrmit);
+
+        super.customize(endpoint, request);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public int getLocalPort()
+    {
+        return _localPort;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _connections.clear();
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        Set<EndPoint> set = new HashSet<EndPoint>();
+        synchronized(_connections)
+        {
+            set.addAll(_connections);
+        }
+        for (EndPoint endPoint : set)
+        {
+            ConnectorEndPoint connection = (ConnectorEndPoint)endPoint;
+            connection.close();
+        }
+    }
+
+    @Override
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        super.dump(out, indent);
+        Set<EndPoint> connections = new HashSet<EndPoint>();
+        synchronized (_connections)
+        {
+            connections.addAll(_connections);
+        }
+        AggregateLifeCycle.dump(out, indent, connections);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    protected class ConnectorEndPoint extends SocketEndPoint implements Runnable, ConnectedEndPoint
+    {
+        volatile Connection _connection;
+        protected final Socket _socket;
+
+        public ConnectorEndPoint(Socket socket) throws IOException
+        {
+            super(socket,_maxIdleTime);
+            _connection = newConnection(this);
+            _socket=socket;
+        }
+
+        public Connection getConnection()
+        {
+            return _connection;
+        }
+
+        public void setConnection(Connection connection)
+        {
+            if (_connection!=connection && _connection!=null)
+                connectionUpgraded(_connection,connection);
+            _connection=connection;
+        }
+
+        public void dispatch() throws IOException
+        {
+            if (getThreadPool()==null || !getThreadPool().dispatch(this))
+            {
+                LOG.warn("dispatch failed for {}",_connection);
+                close();
+            }
+        }
+
+        @Override
+        public int fill(Buffer buffer) throws IOException
+        {
+            int l = super.fill(buffer);
+            if (l<0)
+            {
+                if (!isInputShutdown())
+                    shutdownInput();
+                if (isOutputShutdown())
+                    close();
+            }
+            return l;
+        }
+
+        @Override
+        public void close() throws IOException
+        {
+            if (_connection instanceof AbstractHttpConnection)
+                ((AbstractHttpConnection)_connection).getRequest().getAsyncContinuation().cancel();
+            super.close();
+        }
+
+        public void run()
+        {
+            try
+            {
+                connectionOpened(_connection);
+                synchronized(_connections)
+                {
+                    _connections.add(this);
+                }
+
+                while (isStarted() && !isClosed())
+                {
+                    if (_connection.isIdle())
+                    {
+                        if (isLowResources())
+                            setMaxIdleTime(getLowResourcesMaxIdleTime());
+                    }
+
+                    _connection=_connection.handle();
+                }
+            }
+            catch (EofException e)
+            {
+                LOG.debug("EOF", e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch (SocketException e)
+            {
+                LOG.debug("EOF", e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch (HttpException e)
+            {
+                LOG.debug("BAD", e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch(Exception e)
+            {
+                LOG.warn("handle failed?",e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            finally
+            {
+                connectionClosed(_connection);
+                synchronized(_connections)
+                {
+                    _connections.remove(this);
+                }
+
+                // wait for client to close, but if not, close ourselves.
+                try
+                {
+                    if (!_socket.isClosed())
+                    {
+                        long timestamp=System.currentTimeMillis();
+                        int max_idle=getMaxIdleTime();
+
+                        _socket.setSoTimeout(getMaxIdleTime());
+                        int c=0;
+                        do
+                        {
+                            c = _socket.getInputStream().read();
+                        }
+                        while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle);
+                        if (!_socket.isClosed())
+                            _socket.close();
+                    }
+                }
+                catch(IOException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/AbstractHandler.java b/src/java/org/eclipse/jetty/server/handler/AbstractHandler.java
new file mode 100644
index 0000000..07f140c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/AbstractHandler.java
@@ -0,0 +1,105 @@
+//
+//  ========================================================================
+//  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.handler;
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** AbstractHandler.
+ * 
+ *
+ */
+public abstract class AbstractHandler extends AggregateLifeCycle implements Handler
+{
+    private static final Logger LOG = Log.getLogger(AbstractHandler.class);
+
+    private Server _server;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     */
+    public AbstractHandler()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.thread.LifeCycle#start()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        LOG.debug("starting {}",this);
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.thread.LifeCycle#stop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        LOG.debug("stopping {}",this);
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setServer(Server server)
+    {
+        Server old_server=_server;
+        if (old_server!=null && old_server!=server)
+            old_server.getContainer().removeBean(this);
+        _server=server;
+        if (_server!=null && _server!=old_server)
+            _server.getContainer().addBean(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Server getServer()
+    {
+        return _server;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void destroy()
+    {
+        if (!isStopped())
+            throw new IllegalStateException("!STOPPED");
+        super.destroy();
+        if (_server!=null)
+            _server.getContainer().removeBean(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dumpThis(Appendable out) throws IOException
+    {
+        out.append(toString()).append(" - ").append(getState()).append('\n');
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java b/src/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java
new file mode 100644
index 0000000..55e33f6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java
@@ -0,0 +1,123 @@
+//
+//  ========================================================================
+//  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.handler;
+
+
+import java.io.IOException;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.TypeUtil;
+
+
+/* ------------------------------------------------------------ */
+/** Abstract Handler Container.
+ * This is the base class for handlers that may contain other handlers.
+ *
+ */
+public abstract class AbstractHandlerContainer extends AbstractHandler implements HandlerContainer
+{
+    /* ------------------------------------------------------------ */
+    public AbstractHandlerContainer()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Handler[] getChildHandlers()
+    {
+        Object list = expandChildren(null,null);
+        return (Handler[])LazyList.toArray(list, Handler.class);
+    }
+        
+    /* ------------------------------------------------------------ */
+    public Handler[] getChildHandlersByClass(Class<?> byclass)
+    {
+        Object list = expandChildren(null,byclass);
+        return (Handler[])LazyList.toArray(list, byclass);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public <T extends Handler> T getChildHandlerByClass(Class<T> byclass)
+    {
+        // TODO this can be more efficient?
+        Object list = expandChildren(null,byclass);
+        if (list==null)
+            return null;
+        return (T)LazyList.get(list, 0);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected Object expandChildren(Object list, Class<?> byClass)
+    {
+        return list;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected Object expandHandler(Handler handler, Object list, Class<Handler> byClass)
+    {
+        if (handler==null)
+            return list;
+        
+        if (byClass==null || byClass.isAssignableFrom(handler.getClass()))
+            list=LazyList.add(list, handler);
+
+        if (handler instanceof AbstractHandlerContainer)
+            list=((AbstractHandlerContainer)handler).expandChildren(list, byClass);
+        else if (handler instanceof HandlerContainer)
+        {
+            HandlerContainer container = (HandlerContainer)handler;
+            Handler[] handlers=byClass==null?container.getChildHandlers():container.getChildHandlersByClass(byClass);
+            list=LazyList.addArray(list, handlers);
+        }
+        
+        return list;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static <T extends HandlerContainer> T findContainerOf(HandlerContainer root,Class<T>type, Handler handler)
+    {
+        if (root==null || handler==null)
+            return null;
+        
+        Handler[] branches=root.getChildHandlersByClass(type);
+        if (branches!=null)
+        {
+            for (Handler h:branches)
+            {
+                T container = (T)h;
+                Handler[] candidates = container.getChildHandlersByClass(handler.getClass());
+                if (candidates!=null)
+                {
+                    for (Handler c:candidates)
+                        if (c==handler)
+                            return container;
+                }
+            }
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out,String indent) throws IOException
+    {
+        dumpThis(out);
+        dump(out,indent,getBeans(),TypeUtil.asList(getHandlers()));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ConnectHandler.java b/src/java/org/eclipse/jetty/server/handler/ConnectHandler.java
new file mode 100644
index 0000000..ac70203
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ConnectHandler.java
@@ -0,0 +1,1025 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.HostMap;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/**
+ * <p>Implementation of a tunneling proxy that supports HTTP CONNECT.</p>
+ * <p>To work as CONNECT proxy, objects of this class must be instantiated using the no-arguments
+ * constructor, since the remote server information will be present in the CONNECT URI.</p>
+ */
+public class ConnectHandler extends HandlerWrapper
+{
+    private static final Logger LOG = Log.getLogger(ConnectHandler.class);
+    private final SelectorManager _selectorManager = new Manager();
+    private volatile int _connectTimeout = 5000;
+    private volatile int _writeTimeout = 30000;
+    private volatile ThreadPool _threadPool;
+    private volatile boolean _privateThreadPool;
+    private HostMap<String> _white = new HostMap<String>();
+    private HostMap<String> _black = new HostMap<String>();
+
+    public ConnectHandler()
+    {
+        this(null);
+    }
+
+    public ConnectHandler(String[] white, String[] black)
+    {
+        this(null, white, black);
+    }
+
+    public ConnectHandler(Handler handler)
+    {
+        setHandler(handler);
+    }
+
+    public ConnectHandler(Handler handler, String[] white, String[] black)
+    {
+        setHandler(handler);
+        set(white, _white);
+        set(black, _black);
+    }
+
+    /**
+     * @return the timeout, in milliseconds, to connect to the remote server
+     */
+    public int getConnectTimeout()
+    {
+        return _connectTimeout;
+    }
+
+    /**
+     * @param connectTimeout the timeout, in milliseconds, to connect to the remote server
+     */
+    public void setConnectTimeout(int connectTimeout)
+    {
+        _connectTimeout = connectTimeout;
+    }
+
+    /**
+     * @return the timeout, in milliseconds, to write data to a peer
+     */
+    public int getWriteTimeout()
+    {
+        return _writeTimeout;
+    }
+
+    /**
+     * @param writeTimeout the timeout, in milliseconds, to write data to a peer
+     */
+    public void setWriteTimeout(int writeTimeout)
+    {
+        _writeTimeout = writeTimeout;
+    }
+
+    @Override
+    public void setServer(Server server)
+    {
+        super.setServer(server);
+
+        server.getContainer().update(this, null, _selectorManager, "selectManager");
+
+        if (_privateThreadPool)
+            server.getContainer().update(this, null, _privateThreadPool, "threadpool", true);
+        else
+            _threadPool = server.getThreadPool();
+    }
+
+    /**
+     * @return the thread pool
+     */
+    public ThreadPool getThreadPool()
+    {
+        return _threadPool;
+    }
+
+    /**
+     * @param threadPool the thread pool
+     */
+    public void setThreadPool(ThreadPool threadPool)
+    {
+        if (getServer() != null)
+            getServer().getContainer().update(this, _privateThreadPool ? _threadPool : null, threadPool, "threadpool", true);
+        _privateThreadPool = threadPool != null;
+        _threadPool = threadPool;
+    }
+
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+
+        if (_threadPool == null)
+        {
+            _threadPool = getServer().getThreadPool();
+            _privateThreadPool = false;
+        }
+        if (_threadPool instanceof LifeCycle && !((LifeCycle)_threadPool).isRunning())
+            ((LifeCycle)_threadPool).start();
+
+        _selectorManager.start();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        _selectorManager.stop();
+
+        ThreadPool threadPool = _threadPool;
+        if (_privateThreadPool && _threadPool != null && threadPool instanceof LifeCycle)
+            ((LifeCycle)threadPool).stop();
+
+        super.doStop();
+    }
+
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+    {
+        if (HttpMethods.CONNECT.equalsIgnoreCase(request.getMethod()))
+        {
+            LOG.debug("CONNECT request for {}", request.getRequestURI());
+            try
+            {
+                handleConnect(baseRequest, request, response, request.getRequestURI());
+            }
+            catch(Exception e)
+            {
+                LOG.warn("ConnectHandler "+baseRequest.getUri()+" "+ e);
+                LOG.debug(e);
+            }
+        }
+        else
+        {
+            super.handle(target, baseRequest, request, response);
+        }
+    }
+
+    /**
+     * <p>Handles a CONNECT request.</p>
+     * <p>CONNECT requests may have authentication headers such as <code>Proxy-Authorization</code>
+     * that authenticate the client with the proxy.</p>
+     *
+     * @param baseRequest   Jetty-specific http request
+     * @param request       the http request
+     * @param response      the http response
+     * @param serverAddress the remote server address in the form {@code host:port}
+     * @throws ServletException if an application error occurs
+     * @throws IOException      if an I/O error occurs
+     */
+    protected void handleConnect(Request baseRequest, HttpServletRequest request, HttpServletResponse response, String serverAddress) throws ServletException, IOException
+    {
+        boolean proceed = handleAuthentication(request, response, serverAddress);
+        if (!proceed)
+            return;
+
+        String host = serverAddress;
+        int port = 80;
+        int colon = serverAddress.indexOf(':');
+        if (colon > 0)
+        {
+            host = serverAddress.substring(0, colon);
+            port = Integer.parseInt(serverAddress.substring(colon + 1));
+        }
+
+        if (!validateDestination(host))
+        {
+            LOG.info("ProxyHandler: Forbidden destination " + host);
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            baseRequest.setHandled(true);
+            return;
+        }
+
+        SocketChannel channel;
+
+        try
+        {
+            channel = connectToServer(request,host,port);
+        }
+        catch (SocketException se)
+        {
+            LOG.info("ConnectHandler: SocketException " + se.getMessage());
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            baseRequest.setHandled(true);
+            return;
+        }
+        catch (SocketTimeoutException ste)
+        {
+            LOG.info("ConnectHandler: SocketTimeoutException" + ste.getMessage());
+            response.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
+            baseRequest.setHandled(true);
+            return;
+        }
+        catch (IOException ioe)
+        {
+            LOG.info("ConnectHandler: IOException" + ioe.getMessage());
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            baseRequest.setHandled(true);
+            return;
+        }
+
+        // Transfer unread data from old connection to new connection
+        // We need to copy the data to avoid races:
+        // 1. when this unread data is written and the server replies before the clientToProxy
+        // connection is installed (it is only installed after returning from this method)
+        // 2. when the client sends data before this unread data has been written.
+        AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentConnection();
+        Buffer headerBuffer = ((HttpParser)httpConnection.getParser()).getHeaderBuffer();
+        Buffer bodyBuffer = ((HttpParser)httpConnection.getParser()).getBodyBuffer();
+        int length = headerBuffer == null ? 0 : headerBuffer.length();
+        length += bodyBuffer == null ? 0 : bodyBuffer.length();
+        IndirectNIOBuffer buffer = null;
+        if (length > 0)
+        {
+            buffer = new IndirectNIOBuffer(length);
+            if (headerBuffer != null)
+            {
+                buffer.put(headerBuffer);
+                headerBuffer.clear();
+            }
+            if (bodyBuffer != null)
+            {
+                buffer.put(bodyBuffer);
+                bodyBuffer.clear();
+            }
+        }
+
+        ConcurrentMap<String, Object> context = new ConcurrentHashMap<String, Object>();
+        prepareContext(request, context);
+
+        ClientToProxyConnection clientToProxy = prepareConnections(context, channel, buffer);
+
+        // CONNECT expects a 200 response
+        response.setStatus(HttpServletResponse.SC_OK);
+
+        // Prevent close
+        baseRequest.getConnection().getGenerator().setPersistent(true);
+
+        // Close to force last flush it so that the client receives it
+        response.getOutputStream().close();
+
+        upgradeConnection(request, response, clientToProxy);
+    }
+
+    private ClientToProxyConnection prepareConnections(ConcurrentMap<String, Object> context, SocketChannel channel, Buffer buffer)
+    {
+        AbstractHttpConnection httpConnection = AbstractHttpConnection.getCurrentConnection();
+        ProxyToServerConnection proxyToServer = newProxyToServerConnection(context, buffer);
+        ClientToProxyConnection clientToProxy = newClientToProxyConnection(context, channel, httpConnection.getEndPoint(), httpConnection.getTimeStamp());
+        clientToProxy.setConnection(proxyToServer);
+        proxyToServer.setConnection(clientToProxy);
+        return clientToProxy;
+    }
+
+    /**
+     * <p>Handles the authentication before setting up the tunnel to the remote server.</p>
+     * <p>The default implementation returns true.</p>
+     *
+     * @param request  the HTTP request
+     * @param response the HTTP response
+     * @param address  the address of the remote server in the form {@code host:port}.
+     * @return true to allow to connect to the remote host, false otherwise
+     * @throws ServletException to report a server error to the caller
+     * @throws IOException      to report a server error to the caller
+     */
+    protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) throws ServletException, IOException
+    {
+        return true;
+    }
+
+    protected ClientToProxyConnection newClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timeStamp)
+    {
+        return new ClientToProxyConnection(context, channel, endPoint, timeStamp);
+    }
+
+    protected ProxyToServerConnection newProxyToServerConnection(ConcurrentMap<String, Object> context, Buffer buffer)
+    {
+        return new ProxyToServerConnection(context, buffer);
+    }
+
+    // may return null
+    private SocketChannel connectToServer(HttpServletRequest request, String host, int port) throws IOException
+    {
+        SocketChannel channel = connect(request, host, port);      
+        channel.configureBlocking(false);
+        return channel;
+    }
+
+    /**
+     * <p>Establishes a connection to the remote server.</p>
+     *
+     * @param request the HTTP request that initiated the tunnel
+     * @param host    the host to connect to
+     * @param port    the port to connect to
+     * @return a {@link SocketChannel} connected to the remote server
+     * @throws IOException if the connection cannot be established
+     */
+    protected SocketChannel connect(HttpServletRequest request, String host, int port) throws IOException
+    {
+        SocketChannel channel = SocketChannel.open();
+
+        if (channel == null)
+        {
+            throw new IOException("unable to connect to " + host + ":" + port);
+        }
+
+        try
+        {
+            // Connect to remote server
+            LOG.debug("Establishing connection to {}:{}", host, port);
+            channel.socket().setTcpNoDelay(true);
+            channel.socket().connect(new InetSocketAddress(host, port), getConnectTimeout());
+            LOG.debug("Established connection to {}:{}", host, port);
+            return channel;
+        }
+        catch (IOException x)
+        {
+            LOG.debug("Failed to establish connection to " + host + ":" + port, x);
+            try
+            {
+                channel.close();
+            }
+            catch (IOException xx)
+            {
+                LOG.ignore(xx);
+            }
+            throw x;
+        }
+    }
+
+    protected void prepareContext(HttpServletRequest request, ConcurrentMap<String, Object> context)
+    {
+    }
+
+    private void upgradeConnection(HttpServletRequest request, HttpServletResponse response, Connection connection) throws IOException
+    {
+        // Set the new connection as request attribute and change the status to 101
+        // so that Jetty understands that it has to upgrade the connection
+        request.setAttribute("org.eclipse.jetty.io.Connection", connection);
+        response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
+        LOG.debug("Upgraded connection to {}", connection);
+    }
+
+    private void register(SocketChannel channel, ProxyToServerConnection proxyToServer) throws IOException
+    {
+        _selectorManager.register(channel, proxyToServer);
+        proxyToServer.waitReady(_connectTimeout);
+    }
+
+    /**
+     * <p>Reads (with non-blocking semantic) into the given {@code buffer} from the given {@code endPoint}.</p>
+     *
+     * @param endPoint the endPoint to read from
+     * @param buffer   the buffer to read data into
+     * @param context  the context information related to the connection
+     * @return the number of bytes read (possibly 0 since the read is non-blocking)
+     *         or -1 if the channel has been closed remotely
+     * @throws IOException if the endPoint cannot be read
+     */
+    protected int read(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+    {
+        return endPoint.fill(buffer);
+    }
+
+    /**
+     * <p>Writes (with blocking semantic) the given buffer of data onto the given endPoint.</p>
+     *
+     * @param endPoint the endPoint to write to
+     * @param buffer   the buffer to write
+     * @param context  the context information related to the connection
+     * @throws IOException if the buffer cannot be written
+     * @return the number of bytes written
+     */
+    protected int write(EndPoint endPoint, Buffer buffer, ConcurrentMap<String, Object> context) throws IOException
+    {
+        if (buffer == null)
+            return 0;
+
+        int length = buffer.length();
+        final StringBuilder debug = LOG.isDebugEnabled()?new StringBuilder():null;
+        int flushed = endPoint.flush(buffer);
+        if (debug!=null)
+            debug.append(flushed);
+        
+        // Loop until all written
+        while (buffer.length()>0 && !endPoint.isOutputShutdown())
+        {
+            if (!endPoint.isBlocking())
+            {
+                boolean ready = endPoint.blockWritable(getWriteTimeout());
+                if (!ready)
+                    throw new IOException("Write timeout");
+            }
+            flushed = endPoint.flush(buffer);
+            if (debug!=null)
+                debug.append("+").append(flushed);
+        }
+       
+        LOG.debug("Written {}/{} bytes {}", debug, length, endPoint);
+        buffer.compact();
+        return length;
+    }
+
+    private class Manager extends SelectorManager
+    {
+        @Override
+        protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+        {
+            SelectChannelEndPoint endp = new SelectChannelEndPoint(channel, selectSet, key, channel.socket().getSoTimeout());
+            endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
+            endp.setMaxIdleTime(_writeTimeout);
+            return endp;
+        }
+
+        @Override
+        public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment)
+        {
+            ProxyToServerConnection proxyToServer = (ProxyToServerConnection)attachment;
+            proxyToServer.setTimeStamp(System.currentTimeMillis());
+            proxyToServer.setEndPoint(endpoint);
+            return proxyToServer;
+        }
+
+        @Override
+        protected void endPointOpened(SelectChannelEndPoint endpoint)
+        {
+            ProxyToServerConnection proxyToServer = (ProxyToServerConnection)endpoint.getSelectionKey().attachment();
+            proxyToServer.ready();
+        }
+
+        @Override
+        public boolean dispatch(Runnable task)
+        {
+            return _threadPool.dispatch(task);
+        }
+
+        @Override
+        protected void endPointClosed(SelectChannelEndPoint endpoint)
+        {
+        }
+
+        @Override
+        protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
+        {
+        }
+    }
+
+    public class ProxyToServerConnection implements AsyncConnection
+    {
+        private final CountDownLatch _ready = new CountDownLatch(1);
+        private final Buffer _buffer = new IndirectNIOBuffer(4096);
+        private final ConcurrentMap<String, Object> _context;
+        private volatile Buffer _data;
+        private volatile ClientToProxyConnection _toClient;
+        private volatile long _timestamp;
+        private volatile AsyncEndPoint _endPoint;
+
+        public ProxyToServerConnection(ConcurrentMap<String, Object> context, Buffer data)
+        {
+            _context = context;
+            _data = data;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder builder = new StringBuilder("ProxyToServer");
+            builder.append("(:").append(_endPoint.getLocalPort());
+            builder.append("<=>:").append(_endPoint.getRemotePort());
+            return builder.append(")").toString();
+        }
+
+        public Connection handle() throws IOException
+        {
+            LOG.debug("{}: begin reading from server", this);
+            try
+            {
+                writeData();
+
+                while (true)
+                {
+                    int read = read(_endPoint, _buffer, _context);
+
+                    if (read == -1)
+                    {
+                        LOG.debug("{}: server closed connection {}", this, _endPoint);
+
+                        if (_endPoint.isOutputShutdown() || !_endPoint.isOpen())
+                            closeClient();
+                        else
+                            _toClient.shutdownOutput();
+
+                        break;
+                    }
+
+                    if (read == 0)
+                        break;
+
+                    LOG.debug("{}: read from server {} bytes {}", this, read, _endPoint);
+                    int written = write(_toClient._endPoint, _buffer, _context);
+                    LOG.debug("{}: written to {} {} bytes", this, _toClient, written);
+                }
+                return this;
+            }
+            catch (ClosedChannelException x)
+            {
+                LOG.debug(x);
+                throw x;
+            }
+            catch (IOException x)
+            {
+                LOG.warn(this + ": unexpected exception", x);
+                close();
+                throw x;
+            }
+            catch (RuntimeException x)
+            {
+                LOG.warn(this + ": unexpected exception", x);
+                close();
+                throw x;
+            }
+            finally
+            {
+                LOG.debug("{}: end reading from server", this);
+            }
+        }
+
+        public void onInputShutdown() throws IOException
+        {
+        }
+
+        private void writeData() throws IOException
+        {
+            // This method is called from handle() and closeServer()
+            // which may happen concurrently (e.g. a client closing
+            // while reading from the server), so needs synchronization
+            synchronized (this)
+            {
+                if (_data != null)
+                {
+                    try
+                    {
+                        int written = write(_endPoint, _data, _context);
+                        LOG.debug("{}: written to server {} bytes", this, written);
+                    }
+                    finally
+                    {
+                        // Attempt once to write the data; if the write fails (for example
+                        // because the connection is already closed), clear the data and
+                        // give up to avoid to continue to write data to a closed connection
+                        _data = null;
+                    }
+                }
+            }
+        }
+
+        public void setConnection(ClientToProxyConnection connection)
+        {
+            _toClient = connection;
+        }
+
+        public long getTimeStamp()
+        {
+            return _timestamp;
+        }
+
+        public void setTimeStamp(long timestamp)
+        {
+            _timestamp = timestamp;
+        }
+
+        public void setEndPoint(AsyncEndPoint endpoint)
+        {
+            _endPoint = endpoint;
+        }
+
+        public boolean isIdle()
+        {
+            return false;
+        }
+
+        public boolean isSuspended()
+        {
+            return false;
+        }
+
+        public void onClose()
+        {
+        }
+
+        public void ready()
+        {
+            _ready.countDown();
+        }
+
+        public void waitReady(long timeout) throws IOException
+        {
+            try
+            {
+                _ready.await(timeout, TimeUnit.MILLISECONDS);
+            }
+            catch (final InterruptedException x)
+            {
+                throw new IOException()
+                {{
+                        initCause(x);
+                    }};
+            }
+        }
+
+        public void closeClient() throws IOException
+        {
+            _toClient.closeClient();
+        }
+
+        public void closeServer() throws IOException
+        {
+            _endPoint.close();
+        }
+
+        public void close()
+        {
+            try
+            {
+                closeClient();
+            }
+            catch (IOException x)
+            {
+                LOG.debug(this + ": unexpected exception closing the client", x);
+            }
+
+            try
+            {
+                closeServer();
+            }
+            catch (IOException x)
+            {
+                LOG.debug(this + ": unexpected exception closing the server", x);
+            }
+        }
+
+        public void shutdownOutput() throws IOException
+        {
+            writeData();
+            _endPoint.shutdownOutput();
+        }
+
+        public void onIdleExpired(long idleForMs)
+        {
+            try
+            {
+                LOG.debug("{} idle expired", this);
+                if (_endPoint.isOutputShutdown())
+                    close();
+                else
+                    shutdownOutput();
+            }
+            catch(Exception e)
+            {
+                LOG.debug(e);
+                close();
+            }
+        }
+    }
+
+    public class ClientToProxyConnection implements AsyncConnection
+    {
+        private final Buffer _buffer = new IndirectNIOBuffer(4096);
+        private final ConcurrentMap<String, Object> _context;
+        private final SocketChannel _channel;
+        private final EndPoint _endPoint;
+        private final long _timestamp;
+        private volatile ProxyToServerConnection _toServer;
+        private boolean _firstTime = true;
+
+        public ClientToProxyConnection(ConcurrentMap<String, Object> context, SocketChannel channel, EndPoint endPoint, long timestamp)
+        {
+            _context = context;
+            _channel = channel;
+            _endPoint = endPoint;
+            _timestamp = timestamp;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder builder = new StringBuilder("ClientToProxy");
+            builder.append("(:").append(_endPoint.getLocalPort());
+            builder.append("<=>:").append(_endPoint.getRemotePort());
+            return builder.append(")").toString();
+        }
+
+        public Connection handle() throws IOException
+        {
+            LOG.debug("{}: begin reading from client", this);
+            try
+            {
+                if (_firstTime)
+                {
+                    _firstTime = false;
+                    register(_channel, _toServer);
+                    LOG.debug("{}: registered channel {} with connection {}", this, _channel, _toServer);
+                }
+
+                while (true)
+                {
+                    int read = read(_endPoint, _buffer, _context);
+
+                    if (read == -1)
+                    {
+                        LOG.debug("{}: client closed connection {}", this, _endPoint);
+
+                        if (_endPoint.isOutputShutdown() || !_endPoint.isOpen())
+                            closeServer();
+                        else
+                            _toServer.shutdownOutput();
+
+                        break;
+                    }
+
+                    if (read == 0)
+                        break;
+
+                    LOG.debug("{}: read from client {} bytes {}", this, read, _endPoint);
+                    int written = write(_toServer._endPoint, _buffer, _context);
+                    LOG.debug("{}: written to {} {} bytes", this, _toServer, written);
+                }
+                return this;
+            }
+            catch (ClosedChannelException x)
+            {
+                LOG.debug(x);
+                closeServer();
+                throw x;
+            }
+            catch (IOException x)
+            {
+                LOG.warn(this + ": unexpected exception", x);
+                close();
+                throw x;
+            }
+            catch (RuntimeException x)
+            {
+                LOG.warn(this + ": unexpected exception", x);
+                close();
+                throw x;
+            }
+            finally
+            {
+                LOG.debug("{}: end reading from client", this);
+            }
+        }
+
+        public void onInputShutdown() throws IOException
+        {
+        }
+
+        public long getTimeStamp()
+        {
+            return _timestamp;
+        }
+
+        public boolean isIdle()
+        {
+            return false;
+        }
+
+        public boolean isSuspended()
+        {
+            return false;
+        }
+
+        public void onClose()
+        {
+        }
+
+        public void setConnection(ProxyToServerConnection connection)
+        {
+            _toServer = connection;
+        }
+
+        public void closeClient() throws IOException
+        {
+            _endPoint.close();
+        }
+
+        public void closeServer() throws IOException
+        {
+            _toServer.closeServer();
+        }
+
+        public void close()
+        {
+            try
+            {
+                closeClient();
+            }
+            catch (IOException x)
+            {
+                LOG.debug(this + ": unexpected exception closing the client", x);
+            }
+
+            try
+            {
+                closeServer();
+            }
+            catch (IOException x)
+            {
+                LOG.debug(this + ": unexpected exception closing the server", x);
+            }
+        }
+
+        public void shutdownOutput() throws IOException
+        {
+            _endPoint.shutdownOutput();
+        }
+
+        public void onIdleExpired(long idleForMs)
+        {
+            try
+            {
+                LOG.debug("{} idle expired", this);
+                if (_endPoint.isOutputShutdown())
+                    close();
+                else
+                    shutdownOutput();
+            }
+            catch(Exception e)
+            {
+                LOG.debug(e);
+                close();
+            }
+        }
+    }
+
+    /**
+     * Add a whitelist entry to an existing handler configuration
+     *
+     * @param entry new whitelist entry
+     */
+    public void addWhite(String entry)
+    {
+        add(entry, _white);
+    }
+
+    /**
+     * Add a blacklist entry to an existing handler configuration
+     *
+     * @param entry new blacklist entry
+     */
+    public void addBlack(String entry)
+    {
+        add(entry, _black);
+    }
+
+    /**
+     * Re-initialize the whitelist of existing handler object
+     *
+     * @param entries array of whitelist entries
+     */
+    public void setWhite(String[] entries)
+    {
+        set(entries, _white);
+    }
+
+    /**
+     * Re-initialize the blacklist of existing handler object
+     *
+     * @param entries array of blacklist entries
+     */
+    public void setBlack(String[] entries)
+    {
+        set(entries, _black);
+    }
+
+    /**
+     * Helper method to process a list of new entries and replace
+     * the content of the specified host map
+     *
+     * @param entries new entries
+     * @param hostMap target host map
+     */
+    protected void set(String[] entries, HostMap<String> hostMap)
+    {
+        hostMap.clear();
+
+        if (entries != null && entries.length > 0)
+        {
+            for (String addrPath : entries)
+            {
+                add(addrPath, hostMap);
+            }
+        }
+    }
+
+    /**
+     * Helper method to process the new entry and add it to
+     * the specified host map.
+     *
+     * @param entry      new entry
+     * @param hostMap target host map
+     */
+    private void add(String entry, HostMap<String> hostMap)
+    {
+        if (entry != null && entry.length() > 0)
+        {
+            entry = entry.trim();
+            if (hostMap.get(entry) == null)
+            {
+                hostMap.put(entry, entry);
+            }
+        }
+    }
+
+    /**
+     * Check the request hostname against white- and blacklist.
+     *
+     * @param host hostname to check
+     * @return true if hostname is allowed to be proxied
+     */
+    public boolean validateDestination(String host)
+    {
+        if (_white.size() > 0)
+        {
+            Object whiteObj = _white.getLazyMatches(host);
+            if (whiteObj == null)
+            {
+                return false;
+            }
+        }
+
+        if (_black.size() > 0)
+        {
+            Object blackObj = _black.getLazyMatches(host);
+            if (blackObj != null)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        dumpThis(out);
+        if (_privateThreadPool)
+            dump(out, indent, Arrays.asList(_threadPool, _selectorManager), TypeUtil.asList(getHandlers()), getBeans());
+        else
+            dump(out, indent, Arrays.asList(_selectorManager), TypeUtil.asList(getHandlers()), getBeans());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ContextHandler.java b/src/java/org/eclipse/jetty/server/handler/ContextHandler.java
new file mode 100644
index 0000000..16dec37
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -0,0 +1,2569 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.FilterRegistration.Dynamic;
+import javax.servlet.descriptor.JspConfigDescriptor;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.Attributes;
+import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/* ------------------------------------------------------------ */
+/**
+ * ContextHandler.
+ *
+ * This handler wraps a call to handle by setting the context and servlet path, plus setting the context classloader.
+ *
+ * <p>
+ * If the context init parameter "org.eclipse.jetty.server.context.ManagedAttributes" is set to a comma separated list of names, then they are treated as
+ * context attribute names, which if set as attributes are passed to the servers Container so that they may be managed with JMX.
+ * <p>
+ * The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys
+ * and org.eclipse.jetty.server.Request.maxFormContentSize.  These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)}
+ * 
+ * @org.apache.xbean.XBean description="Creates a basic HTTP context"
+ */
+public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful
+{
+    private static final Logger LOG = Log.getLogger(ContextHandler.class);
+
+    private static final ThreadLocal<Context> __context = new ThreadLocal<Context>();
+
+    /**
+     * If a context attribute with this name is set, it is interpreted as a comma separated list of attribute name. Any other context attributes that are set
+     * with a name from this list will result in a call to {@link #setManagedAttribute(String, Object)}, which typically initiates the creation of a JMX MBean
+     * for the attribute value.
+     */
+    public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the current ServletContext implementation.
+     *
+     * @return ServletContext implementation
+     */
+    public static Context getCurrentContext()
+    {
+        return __context.get();
+    }
+
+    protected Context _scontext;
+
+    private final AttributesMap _attributes;
+    private final AttributesMap _contextAttributes;
+    private final Map<String, String> _initParams;
+    private ClassLoader _classLoader;
+    private String _contextPath = "/";
+    private String _displayName;
+    private Resource _baseResource;
+    private MimeTypes _mimeTypes;
+    private Map<String, String> _localeEncodingMap;
+    private String[] _welcomeFiles;
+    private ErrorHandler _errorHandler;
+    private String[] _vhosts;
+    private Set<String> _connectors;
+    private EventListener[] _eventListeners;
+    private Logger _logger;
+    private boolean _allowNullPathInfo;
+    private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys",-1).intValue();
+    private int _maxFormContentSize = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormContentSize",-1).intValue();
+    private boolean _compactPath = false;
+    private boolean _aliasesAllowed = false;
+
+    private Object _contextListeners;
+    private Object _contextAttributeListeners;
+    private Object _requestListeners;
+    private Object _requestAttributeListeners;
+    private Object _durableListeners;
+    private Map<String, Object> _managedAttributes;
+    private String[] _protectedTargets;
+    private final CopyOnWriteArrayList<AliasCheck> _aliasChecks = new CopyOnWriteArrayList<ContextHandler.AliasCheck>();
+
+    private boolean _shutdown = false;
+    private boolean _available = true;
+    private volatile int _availability; // 0=STOPPED, 1=AVAILABLE, 2=SHUTDOWN, 3=UNAVAILABLE
+
+    private final static int __STOPPED = 0, __AVAILABLE = 1, __SHUTDOWN = 2, __UNAVAILABLE = 3;
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public ContextHandler()
+    {
+        super();
+        _scontext = new Context();
+        _attributes = new AttributesMap();
+        _contextAttributes = new AttributesMap();
+        _initParams = new HashMap<String, String>();
+        addAliasCheck(new ApproveNonExistentDirectoryAliases());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    protected ContextHandler(Context context)
+    {
+        super();
+        _scontext = context;
+        _attributes = new AttributesMap();
+        _contextAttributes = new AttributesMap();
+        _initParams = new HashMap<String, String>();
+        addAliasCheck(new ApproveNonExistentDirectoryAliases());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public ContextHandler(String contextPath)
+    {
+        this();
+        setContextPath(contextPath);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public ContextHandler(HandlerContainer parent, String contextPath)
+    {
+        this();
+        setContextPath(contextPath);
+        if (parent instanceof HandlerWrapper)
+            ((HandlerWrapper)parent).setHandler(this);
+        else if (parent instanceof HandlerCollection)
+            ((HandlerCollection)parent).addHandler(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        dumpThis(out);
+        dump(out,indent,Collections.singletonList(new CLDump(getClassLoader())),TypeUtil.asList(getHandlers()),getBeans(),_initParams.entrySet(),
+                _attributes.getAttributeEntrySet(),_contextAttributes.getAttributeEntrySet());
+    }
+
+    /* ------------------------------------------------------------ */
+    public Context getServletContext()
+    {
+        return _scontext;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the allowNullPathInfo true if /context is not redirected to /context/
+     */
+    public boolean getAllowNullPathInfo()
+    {
+        return _allowNullPathInfo;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param allowNullPathInfo
+     *            true if /context is not redirected to /context/
+     */
+    public void setAllowNullPathInfo(boolean allowNullPathInfo)
+    {
+        _allowNullPathInfo = allowNullPathInfo;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setServer(Server server)
+    {
+        if (_errorHandler != null)
+        {
+            Server old_server = getServer();
+            if (old_server != null && old_server != server)
+                old_server.getContainer().update(this,_errorHandler,null,"error",true);
+            super.setServer(server);
+            if (server != null && server != old_server)
+                server.getContainer().update(this,null,_errorHandler,"error",true);
+            _errorHandler.setServer(server);
+        }
+        else
+            super.setServer(server);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the virtual hosts for the context. Only requests that have a matching host header or fully qualified URL will be passed to that context with a
+     * virtual host name. A context with no virtual host names or a null virtual host name is available to all requests that are not served by a context with a
+     * matching virtual host name.
+     *
+     * @param vhosts
+     *            Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
+     *            String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+     */
+    public void setVirtualHosts(String[] vhosts)
+    {
+        if (vhosts == null)
+        {
+            _vhosts = vhosts;
+        }
+        else
+        {
+            _vhosts = new String[vhosts.length];
+            for (int i = 0; i < vhosts.length; i++)
+                _vhosts[i] = normalizeHostname(vhosts[i]);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Either set virtual hosts or add to an existing set of virtual hosts.
+     *
+     * @param virtualHosts
+     *            Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
+     *            String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+     */
+    public void addVirtualHosts(String[] virtualHosts)
+    {
+        if (virtualHosts == null)  // since this is add, we don't null the old ones
+        {
+            return;
+        }
+        else
+        {
+            List<String> currentVirtualHosts = null;
+            if (_vhosts != null)
+            {
+                currentVirtualHosts = new ArrayList<String>(Arrays.asList(_vhosts));
+            }
+            else
+            {
+                currentVirtualHosts = new ArrayList<String>();
+            }
+
+            for (int i = 0; i < virtualHosts.length; i++)
+            {
+                String normVhost = normalizeHostname(virtualHosts[i]);
+                if (!currentVirtualHosts.contains(normVhost))
+                {
+                    currentVirtualHosts.add(normVhost);
+                }
+            }
+            _vhosts = currentVirtualHosts.toArray(new String[0]);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Removes an array of virtual host entries, if this removes all entries the _vhosts will be set to null
+     *
+     *  @param virtualHosts
+     *            Array of virtual hosts that this context responds to. A null host name or null/empty array means any hostname is acceptable. Host names may be
+     *            String representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+     */
+    public void removeVirtualHosts(String[] virtualHosts)
+    {
+        if (virtualHosts == null)
+        {
+            return; // do nothing
+        }
+        else if ( _vhosts == null || _vhosts.length == 0)
+        {
+            return; // do nothing
+        }
+        else
+        {
+            List<String> existingVirtualHosts = new ArrayList<String>(Arrays.asList(_vhosts));
+
+            for (int i = 0; i < virtualHosts.length; i++)
+            {
+                String toRemoveVirtualHost = normalizeHostname(virtualHosts[i]);
+                if (existingVirtualHosts.contains(toRemoveVirtualHost))
+                {
+                    existingVirtualHosts.remove(toRemoveVirtualHost);
+                }
+            }
+
+            if (existingVirtualHosts.isEmpty())
+            {
+                _vhosts = null; // if we ended up removing them all, just null out _vhosts
+            }
+            else
+            {
+                _vhosts = existingVirtualHosts.toArray(new String[0]);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the virtual hosts for the context. Only requests that have a matching host header or fully qualified URL will be passed to that context with a
+     * virtual host name. A context with no virtual host names or a null virtual host name is available to all requests that are not served by a context with a
+     * matching virtual host name.
+     *
+     * @return Array of virtual hosts that this context responds to. A null host name or empty array means any hostname is acceptable. Host names may be String
+     *         representation of IP addresses. Host names may start with '*.' to wildcard one level of names.
+     */
+    public String[] getVirtualHosts()
+    {
+        return _vhosts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return an array of connector names that this context will accept a request from.
+     */
+    public String[] getConnectorNames()
+    {
+        if (_connectors == null || _connectors.size() == 0)
+            return null;
+
+        return _connectors.toArray(new String[_connectors.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the names of accepted connectors.
+     *
+     * Names are either "host:port" or a specific configured name for a connector.
+     *
+     * @param connectors
+     *            If non null, an array of connector names that this context will accept a request from.
+     */
+    public void setConnectorNames(String[] connectors)
+    {
+        if (connectors == null || connectors.length == 0)
+            _connectors = null;
+        else
+            _connectors = new HashSet<String>(Arrays.asList(connectors));
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _attributes.getAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#getAttributeNames()
+     */
+    @SuppressWarnings("unchecked")
+    public Enumeration getAttributeNames()
+    {
+        return AttributesMap.getAttributeNamesCopy(_attributes);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the attributes.
+     */
+    public Attributes getAttributes()
+    {
+        return _attributes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the classLoader.
+     */
+    public ClassLoader getClassLoader()
+    {
+        return _classLoader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Make best effort to extract a file classpath from the context classloader
+     *
+     * @return Returns the classLoader.
+     */
+    public String getClassPath()
+    {
+        if (_classLoader == null || !(_classLoader instanceof URLClassLoader))
+            return null;
+        URLClassLoader loader = (URLClassLoader)_classLoader;
+        URL[] urls = loader.getURLs();
+        StringBuilder classpath = new StringBuilder();
+        for (int i = 0; i < urls.length; i++)
+        {
+            try
+            {
+                Resource resource = newResource(urls[i]);
+                File file = resource.getFile();
+                if (file != null && file.exists())
+                {
+                    if (classpath.length() > 0)
+                        classpath.append(File.pathSeparatorChar);
+                    classpath.append(file.getAbsolutePath());
+                }
+            }
+            catch (IOException e)
+            {
+                LOG.debug(e);
+            }
+        }
+        if (classpath.length() == 0)
+            return null;
+        return classpath.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the _contextPath.
+     */
+    public String getContextPath()
+    {
+        return _contextPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+     */
+    public String getInitParameter(String name)
+    {
+        return _initParams.get(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public String setInitParameter(String name, String value)
+    {
+        return _initParams.put(name,value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#getInitParameterNames()
+     */
+    @SuppressWarnings("rawtypes")
+    public Enumeration getInitParameterNames()
+    {
+        return Collections.enumeration(_initParams.keySet());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the initParams.
+     */
+    public Map<String, String> getInitParams()
+    {
+        return _initParams;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#getServletContextName()
+     */
+    public String getDisplayName()
+    {
+        return _displayName;
+    }
+
+    /* ------------------------------------------------------------ */
+    public EventListener[] getEventListeners()
+    {
+        return _eventListeners;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the context event listeners.
+     *
+     * @param eventListeners
+     *            the event listeners
+     * @see ServletContextListener
+     * @see ServletContextAttributeListener
+     * @see ServletRequestListener
+     * @see ServletRequestAttributeListener
+     */
+    public void setEventListeners(EventListener[] eventListeners)
+    {
+        _contextListeners = null;
+        _contextAttributeListeners = null;
+        _requestListeners = null;
+        _requestAttributeListeners = null;
+
+        _eventListeners = eventListeners;
+
+        for (int i = 0; eventListeners != null && i < eventListeners.length; i++)
+        {
+            EventListener listener = _eventListeners[i];
+
+            if (listener instanceof ServletContextListener)
+                _contextListeners = LazyList.add(_contextListeners,listener);
+
+            if (listener instanceof ServletContextAttributeListener)
+                _contextAttributeListeners = LazyList.add(_contextAttributeListeners,listener);
+
+            if (listener instanceof ServletRequestListener)
+                _requestListeners = LazyList.add(_requestListeners,listener);
+
+            if (listener instanceof ServletRequestAttributeListener)
+                _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add a context event listeners.
+     *
+     * @see ServletContextListener
+     * @see ServletContextAttributeListener
+     * @see ServletRequestListener
+     * @see ServletRequestAttributeListener
+     */
+    public void addEventListener(EventListener listener)
+    {
+        //Only listeners added before the context starts last through a stop/start cycle
+        if (!(isStarted() || isStarting()))
+            _durableListeners = LazyList.add(_durableListeners, listener);
+        
+        setEventListeners((EventListener[])LazyList.addToArray(getEventListeners(),listener,EventListener.class));
+    }
+    
+   
+    /**
+     * Apply any necessary restrictions on a programmatically added
+     * listener.
+     * 
+     * Superclasses should implement.
+     * 
+     * @param listener
+     */
+    public void restrictEventListener (EventListener listener)
+    {
+    }
+
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if this context is accepting new requests
+     */
+    public boolean isShutdown()
+    {
+        synchronized (this)
+        {
+            return !_shutdown;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set shutdown status. This field allows for graceful shutdown of a context. A started context may be put into non accepting state so that existing
+     * requests can complete, but no new requests are accepted.
+     *
+     * @param shutdown
+     *            true if this context is (not?) accepting new requests
+     */
+    public void setShutdown(boolean shutdown)
+    {
+        synchronized (this)
+        {
+            _shutdown = shutdown;
+            _availability = isRunning()?(_shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE):__STOPPED;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return false if this context is unavailable (sends 503)
+     */
+    public boolean isAvailable()
+    {
+        synchronized (this)
+        {
+            return _available;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set Available status.
+     */
+    public void setAvailable(boolean available)
+    {
+        synchronized (this)
+        {
+            _available = available;
+            _availability = isRunning()?(_shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE):__STOPPED;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public Logger getLogger()
+    {
+        return _logger;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setLogger(Logger logger)
+    {
+        _logger = logger;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _availability = __STOPPED;
+
+        if (_contextPath == null)
+            throw new IllegalStateException("Null contextPath");
+
+        _logger = Log.getLogger(getDisplayName() == null?getContextPath():getDisplayName());
+        ClassLoader old_classloader = null;
+        Thread current_thread = null;
+        Context old_context = null;
+
+        try
+        {
+            // Set the classloader
+            if (_classLoader != null)
+            {
+                current_thread = Thread.currentThread();
+                old_classloader = current_thread.getContextClassLoader();
+                current_thread.setContextClassLoader(_classLoader);
+            }
+
+            if (_mimeTypes == null)
+                _mimeTypes = new MimeTypes();
+
+            old_context = __context.get();
+            __context.set(_scontext);
+
+            // defers the calling of super.doStart()
+            startContext();
+
+            synchronized(this)
+            {
+                _availability = _shutdown?__SHUTDOWN:_available?__AVAILABLE:__UNAVAILABLE;
+            }
+        }
+        finally
+        {
+            __context.set(old_context);
+
+            // reset the classloader
+            if (_classLoader != null)
+            {
+                current_thread.setContextClassLoader(old_classloader);
+            }
+
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Extensible startContext. this method is called from {@link ContextHandler#doStart()} instead of a call to super.doStart(). This allows derived classes to
+     * insert additional handling (Eg configuration) before the call to super.doStart by this method will start contained handlers.
+     *
+     * @see org.eclipse.jetty.server.handler.ContextHandler.Context
+     */
+    protected void startContext() throws Exception
+    {
+        String managedAttributes = _initParams.get(MANAGED_ATTRIBUTES);
+        if (managedAttributes != null)
+        {
+            _managedAttributes = new HashMap<String, Object>();
+            String[] attributes = managedAttributes.split(",");
+            for (String attribute : attributes)
+                _managedAttributes.put(attribute,null);
+
+            Enumeration e = _scontext.getAttributeNames();
+            while (e.hasMoreElements())
+            {
+                String name = (String)e.nextElement();
+                Object value = _scontext.getAttribute(name);
+                checkManagedAttribute(name,value);
+            }
+        }
+
+        super.doStart();
+
+        if (_errorHandler != null)
+            _errorHandler.start();
+
+        // Context listeners
+        if (_contextListeners != null)
+        {
+            ServletContextEvent event = new ServletContextEvent(_scontext);
+            for (int i = 0; i < LazyList.size(_contextListeners); i++)
+            {
+                callContextInitialized(((ServletContextListener)LazyList.get(_contextListeners, i)), event);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void callContextInitialized (ServletContextListener l, ServletContextEvent e)
+    {
+        l.contextInitialized(e);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void callContextDestroyed (ServletContextListener l, ServletContextEvent e)
+    {
+        l.contextDestroyed(e);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        _availability = __STOPPED;
+
+        ClassLoader old_classloader = null;
+        Thread current_thread = null;
+
+        Context old_context = __context.get();
+        __context.set(_scontext);
+        try
+        {
+            // Set the classloader
+            if (_classLoader != null)
+            {
+                current_thread = Thread.currentThread();
+                old_classloader = current_thread.getContextClassLoader();
+                current_thread.setContextClassLoader(_classLoader);
+            }
+
+            super.doStop();
+
+            // Context listeners
+            if (_contextListeners != null)
+            {
+                ServletContextEvent event = new ServletContextEvent(_scontext);
+                for (int i = LazyList.size(_contextListeners); i-- > 0;)
+                {
+                    ((ServletContextListener)LazyList.get(_contextListeners,i)).contextDestroyed(event);
+                }
+            }
+            
+            //remove all non-durable listeners
+            setEventListeners((EventListener[])LazyList.toArray(_durableListeners, EventListener.class));
+            _durableListeners = null;
+
+            if (_errorHandler != null)
+                _errorHandler.stop();
+
+            Enumeration e = _scontext.getAttributeNames();
+            while (e.hasMoreElements())
+            {
+                String name = (String)e.nextElement();
+                checkManagedAttribute(name,null);
+            }
+        }
+        finally
+        {
+            LOG.info("stopped {}",this);
+            __context.set(old_context);
+            // reset the classloader
+            if (_classLoader != null)
+                current_thread.setContextClassLoader(old_classloader);
+        }
+
+        _contextAttributes.clearAttributes();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    public boolean checkContext(final String target, final Request baseRequest, final HttpServletResponse response) throws IOException, ServletException
+    {
+        DispatcherType dispatch = baseRequest.getDispatcherType();
+
+        switch (_availability)
+        {
+            case __STOPPED:
+            case __SHUTDOWN:
+                return false;
+            case __UNAVAILABLE:
+                baseRequest.setHandled(true);
+                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                return false;
+            default:
+                if ((DispatcherType.REQUEST.equals(dispatch) && baseRequest.isHandled()))
+                    return false;
+        }
+
+        // Check the vhosts
+        if (_vhosts != null && _vhosts.length > 0)
+        {
+            String vhost = normalizeHostname(baseRequest.getServerName());
+
+            boolean match = false;
+
+            // TODO non-linear lookup
+            for (int i = 0; !match && i < _vhosts.length; i++)
+            {
+                String contextVhost = _vhosts[i];
+                if (contextVhost == null)
+                    continue;
+                if (contextVhost.startsWith("*."))
+                {
+                    // wildcard only at the beginning, and only for one additional subdomain level
+                    match = contextVhost.regionMatches(true,2,vhost,vhost.indexOf(".") + 1,contextVhost.length() - 2);
+                }
+                else
+                    match = contextVhost.equalsIgnoreCase(vhost);
+            }
+            if (!match)
+                return false;
+        }
+
+        // Check the connector
+        if (_connectors != null && _connectors.size() > 0)
+        {
+            String connector = AbstractHttpConnection.getCurrentConnection().getConnector().getName();
+            if (connector == null || !_connectors.contains(connector))
+                return false;
+        }
+
+        // Are we not the root context?
+        if (_contextPath.length() > 1)
+        {
+            // reject requests that are not for us
+            if (!target.startsWith(_contextPath))
+                return false;
+            if (target.length() > _contextPath.length() && target.charAt(_contextPath.length()) != '/')
+                return false;
+
+            // redirect null path infos
+            if (!_allowNullPathInfo && _contextPath.length() == target.length())
+            {
+                // context request must end with /
+                baseRequest.setHandled(true);
+                if (baseRequest.getQueryString() != null)
+                    response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH) + "?" + baseRequest.getQueryString());
+                else
+                    response.sendRedirect(URIUtil.addPaths(baseRequest.getRequestURI(),URIUtil.SLASH));
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.ScopedHandler#doScope(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest,
+     *      javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("scope {}|{}|{} @ {}",baseRequest.getContextPath(),baseRequest.getServletPath(),baseRequest.getPathInfo(),this);
+
+        Context old_context = null;
+        String old_context_path = null;
+        String old_servlet_path = null;
+        String old_path_info = null;
+        ClassLoader old_classloader = null;
+        Thread current_thread = null;
+        String pathInfo = target;
+
+        DispatcherType dispatch = baseRequest.getDispatcherType();
+
+        old_context = baseRequest.getContext();
+
+        // Are we already in this context?
+        if (old_context != _scontext)
+        {
+            // check the target.
+            if (DispatcherType.REQUEST.equals(dispatch) || DispatcherType.ASYNC.equals(dispatch) || (DispatcherType.ERROR.equals(dispatch) && baseRequest.getAsyncContinuation().isExpired()))
+            {
+                if (_compactPath)
+                    target = URIUtil.compactPath(target);
+                if (!checkContext(target,baseRequest,response))
+                    return;
+
+                if (target.length() > _contextPath.length())
+                {
+                    if (_contextPath.length() > 1)
+                        target = target.substring(_contextPath.length());
+                    pathInfo = target;
+                }
+                else if (_contextPath.length() == 1)
+                {
+                    target = URIUtil.SLASH;
+                    pathInfo = URIUtil.SLASH;
+                }
+                else
+                {
+                    target = URIUtil.SLASH;
+                    pathInfo = null;
+                }
+            }
+
+            // Set the classloader
+            if (_classLoader != null)
+            {
+                current_thread = Thread.currentThread();
+                old_classloader = current_thread.getContextClassLoader();
+                current_thread.setContextClassLoader(_classLoader);
+            }
+        }
+
+        try
+        {
+            old_context_path = baseRequest.getContextPath();
+            old_servlet_path = baseRequest.getServletPath();
+            old_path_info = baseRequest.getPathInfo();
+
+            // Update the paths
+            baseRequest.setContext(_scontext);
+            __context.set(_scontext);
+            if (!DispatcherType.INCLUDE.equals(dispatch) && target.startsWith("/"))
+            {
+                if (_contextPath.length() == 1)
+                    baseRequest.setContextPath("");
+                else
+                    baseRequest.setContextPath(_contextPath);
+                baseRequest.setServletPath(null);
+                baseRequest.setPathInfo(pathInfo);
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("context={}|{}|{} @ {}",baseRequest.getContextPath(),baseRequest.getServletPath(), baseRequest.getPathInfo(),this);
+
+            // start manual inline of nextScope(target,baseRequest,request,response);
+            if (never())
+                nextScope(target,baseRequest,request,response);
+            else 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 (old_context != _scontext)
+            {
+                // reset the classloader
+                if (_classLoader != null)
+                {
+                    current_thread.setContextClassLoader(old_classloader);
+                }
+
+                // reset the context and servlet path.
+                baseRequest.setContext(old_context);
+                __context.set(old_context);
+                baseRequest.setContextPath(old_context_path);
+                baseRequest.setServletPath(old_servlet_path);
+                baseRequest.setPathInfo(old_path_info);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.ScopedHandler#doHandle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest,
+     *      javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        final DispatcherType dispatch = baseRequest.getDispatcherType();
+        final boolean new_context = baseRequest.takeNewContext();
+        try
+        {
+            if (new_context)
+            {
+                // Handle the REALLY SILLY request events!
+                if (_requestAttributeListeners != null)
+                {
+                    final int s = LazyList.size(_requestAttributeListeners);
+                    for (int i = 0; i < s; i++)
+                        baseRequest.addEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
+                }
+
+                if (_requestListeners != null)
+                {
+                    final int s = LazyList.size(_requestListeners);
+                    final ServletRequestEvent sre = new ServletRequestEvent(_scontext,request);
+                    for (int i = 0; i < s; i++)
+                        ((ServletRequestListener)LazyList.get(_requestListeners,i)).requestInitialized(sre);
+                }
+            }
+
+            if (DispatcherType.REQUEST.equals(dispatch) && isProtectedTarget(target))
+                throw new HttpException(HttpServletResponse.SC_NOT_FOUND);
+
+            // start manual inline of nextHandle(target,baseRequest,request,response);
+            // noinspection ConstantIfStatement
+            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
+        }
+        catch (HttpException e)
+        {
+            LOG.debug(e);
+            baseRequest.setHandled(true);
+            response.sendError(e.getStatus(),e.getReason());
+        }
+        finally
+        {
+            // Handle more REALLY SILLY request events!
+            if (new_context)
+            {
+                if (_requestListeners != null)
+                {
+                    final ServletRequestEvent sre = new ServletRequestEvent(_scontext,request);
+                    for (int i = LazyList.size(_requestListeners); i-- > 0;)
+                        ((ServletRequestListener)LazyList.get(_requestListeners,i)).requestDestroyed(sre);
+                }
+
+                if (_requestAttributeListeners != null)
+                {
+                    for (int i = LazyList.size(_requestAttributeListeners); i-- > 0;)
+                        baseRequest.removeEventListener(((EventListener)LazyList.get(_requestAttributeListeners,i)));
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Handle a runnable in this context
+     */
+    public void handle(Runnable runnable)
+    {
+        ClassLoader old_classloader = null;
+        Thread current_thread = null;
+        Context old_context = null;
+        try
+        {
+            old_context = __context.get();
+            __context.set(_scontext);
+
+            // Set the classloader
+            if (_classLoader != null)
+            {
+                current_thread = Thread.currentThread();
+                old_classloader = current_thread.getContextClassLoader();
+                current_thread.setContextClassLoader(_classLoader);
+            }
+
+            runnable.run();
+        }
+        finally
+        {
+            __context.set(old_context);
+            if (old_classloader != null)
+            {
+                current_thread.setContextClassLoader(old_classloader);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Check the target. Called by {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} when a target within a context is determined. If
+     * the target is protected, 404 is returned. 
+     */
+    /* ------------------------------------------------------------ */
+    public boolean isProtectedTarget(String target)
+    {
+        if (target == null || _protectedTargets == null)
+            return false;
+        
+        while (target.startsWith("//"))
+            target=URIUtil.compactPath(target);
+        
+        boolean isProtected = false;
+        int i=0;
+        while (!isProtected && i<_protectedTargets.length)
+        {
+            isProtected = StringUtil.startsWithIgnoreCase(target, _protectedTargets[i++]);
+        }
+        return isProtected;
+    }
+    
+    
+    public void setProtectedTargets (String[] targets)
+    {
+        if (targets == null)
+        {
+            _protectedTargets = null;
+            return;
+        }
+        
+        _protectedTargets = new String[targets.length];
+        System.arraycopy(targets, 0, _protectedTargets, 0, targets.length);
+    }
+    
+    public String[] getProtectedTargets ()
+    {
+        if (_protectedTargets == null)
+            return null;
+        
+        String[] tmp = new String[_protectedTargets.length];
+        System.arraycopy(_protectedTargets, 0, tmp, 0, _protectedTargets.length);
+        return tmp;
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        checkManagedAttribute(name,null);
+        _attributes.removeAttribute(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Set a context attribute. Attributes set via this API cannot be overriden by the ServletContext.setAttribute API. Their lifecycle spans the stop/start of
+     * a context. No attribute listener events are triggered by this API.
+     *
+     * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value)
+    {
+        checkManagedAttribute(name,value);
+        _attributes.setAttribute(name,value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param attributes
+     *            The attributes to set.
+     */
+    public void setAttributes(Attributes attributes)
+    {
+        _attributes.clearAttributes();
+        _attributes.addAll(attributes);
+        Enumeration e = _attributes.getAttributeNames();
+        while (e.hasMoreElements())
+        {
+            String name = (String)e.nextElement();
+            checkManagedAttribute(name,attributes.getAttribute(name));
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void clearAttributes()
+    {
+        Enumeration e = _attributes.getAttributeNames();
+        while (e.hasMoreElements())
+        {
+            String name = (String)e.nextElement();
+            checkManagedAttribute(name,null);
+        }
+        _attributes.clearAttributes();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void checkManagedAttribute(String name, Object value)
+    {
+        if (_managedAttributes != null && _managedAttributes.containsKey(name))
+        {
+            setManagedAttribute(name,value);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setManagedAttribute(String name, Object value)
+    {
+        Object old = _managedAttributes.put(name,value);
+        getServer().getContainer().update(this,old,value,name,true);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param classLoader
+     *            The classLoader to set.
+     */
+    public void setClassLoader(ClassLoader classLoader)
+    {
+        _classLoader = classLoader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param contextPath
+     *            The _contextPath to set.
+     */
+    public void setContextPath(String contextPath)
+    {
+        if (contextPath != null && contextPath.length() > 1 && contextPath.endsWith("/"))
+            throw new IllegalArgumentException("ends with /");
+        _contextPath = contextPath;
+
+        if (getServer() != null && (getServer().isStarting() || getServer().isStarted()))
+        {
+            Handler[] contextCollections = getServer().getChildHandlersByClass(ContextHandlerCollection.class);
+            for (int h = 0; contextCollections != null && h < contextCollections.length; h++)
+                ((ContextHandlerCollection)contextCollections[h]).mapContexts();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletContextName
+     *            The servletContextName to set.
+     */
+    public void setDisplayName(String servletContextName)
+    {
+        _displayName = servletContextName;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the resourceBase.
+     */
+    public Resource getBaseResource()
+    {
+        if (_baseResource == null)
+            return null;
+        return _baseResource;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the base resource as a string.
+     */
+    public String getResourceBase()
+    {
+        if (_baseResource == null)
+            return null;
+        return _baseResource.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param base
+     *            The resourceBase to set.
+     */
+    public void setBaseResource(Resource base)
+    {
+        _baseResource = base;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param resourceBase
+     *            The base resource as a string.
+     */
+    public void setResourceBase(String resourceBase)
+    {
+        try
+        {
+            setBaseResource(newResource(resourceBase));
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e.toString());
+            LOG.debug(e);
+            throw new IllegalArgumentException(resourceBase);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if aliases are allowed
+     */
+    public boolean isAliases()
+    {
+        return _aliasesAllowed;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param aliases
+     *            aliases are allowed
+     */
+    public void setAliases(boolean aliases)
+    {
+        _aliasesAllowed = aliases;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the mimeTypes.
+     */
+    public MimeTypes getMimeTypes()
+    {
+        if (_mimeTypes == null)
+            _mimeTypes = new MimeTypes();
+        return _mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param mimeTypes
+     *            The mimeTypes to set.
+     */
+    public void setMimeTypes(MimeTypes mimeTypes)
+    {
+        _mimeTypes = mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void setWelcomeFiles(String[] files)
+    {
+        _welcomeFiles = files;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The names of the files which the server should consider to be welcome files in this context.
+     * @see <a href="http://jcp.org/aboutJava/communityprocess/final/jsr154/index.html">The Servlet Specification</a>
+     * @see #setWelcomeFiles
+     */
+    public String[] getWelcomeFiles()
+    {
+        return _welcomeFiles;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the errorHandler.
+     */
+    public ErrorHandler getErrorHandler()
+    {
+        return _errorHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param errorHandler
+     *            The errorHandler to set.
+     */
+    public void setErrorHandler(ErrorHandler errorHandler)
+    {
+        if (errorHandler != null)
+            errorHandler.setServer(getServer());
+        if (getServer() != null)
+            getServer().getContainer().update(this,_errorHandler,errorHandler,"errorHandler",true);
+        _errorHandler = errorHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxFormContentSize()
+    {
+        return _maxFormContentSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the maximum size of a form post, to protect against DOS attacks from large forms.
+     * @param maxSize
+     */
+    public void setMaxFormContentSize(int maxSize)
+    {
+        _maxFormContentSize = maxSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxFormKeys()
+    {
+        return _maxFormKeys;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the maximum number of form Keys to protect against DOS attack from crafted hash keys.
+     * @param max
+     */
+    public void setMaxFormKeys(int max)
+    {
+        _maxFormKeys = max;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if URLs are compacted to replace multiple '/'s with a single '/'
+     */
+    public boolean isCompactPath()
+    {
+        return _compactPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param compactPath
+     *            True if URLs are compacted to replace multiple '/'s with a single '/'
+     */
+    public void setCompactPath(boolean compactPath)
+    {
+        _compactPath = compactPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        String[] vhosts = getVirtualHosts();
+
+        StringBuilder b = new StringBuilder();
+
+        Package pkg = getClass().getPackage();
+        if (pkg != null)
+        {
+            String p = pkg.getName();
+            if (p != null && p.length() > 0)
+            {
+                String[] ss = p.split("\\.");
+                for (String s : ss)
+                    b.append(s.charAt(0)).append('.');
+            }
+        }
+        b.append(getClass().getSimpleName());
+        b.append('{').append(getContextPath()).append(',').append(getBaseResource());
+
+        if (vhosts != null && vhosts.length > 0)
+            b.append(',').append(vhosts[0]);
+        b.append('}');
+
+        return b.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized Class<?> loadClass(String className) throws ClassNotFoundException
+    {
+        if (className == null)
+            return null;
+
+        if (_classLoader == null)
+            return Loader.loadClass(this.getClass(),className);
+
+        return _classLoader.loadClass(className);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addLocaleEncoding(String locale, String encoding)
+    {
+        if (_localeEncodingMap == null)
+            _localeEncodingMap = new HashMap<String, String>();
+        _localeEncodingMap.put(locale,encoding);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getLocaleEncoding(String locale)
+    {
+        if (_localeEncodingMap == null)
+            return null;
+        String encoding = _localeEncodingMap.get(locale);
+        return encoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the character encoding for a locale. The full locale name is first looked up in the map of encodings. If no encoding is found, then the locale
+     * language is looked up.
+     *
+     * @param locale
+     *            a <code>Locale</code> value
+     * @return a <code>String</code> representing the character encoding for the locale or null if none found.
+     */
+    public String getLocaleEncoding(Locale locale)
+    {
+        if (_localeEncodingMap == null)
+            return null;
+        String encoding = _localeEncodingMap.get(locale.toString());
+        if (encoding == null)
+            encoding = _localeEncodingMap.get(locale.getLanguage());
+        return encoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public Resource getResource(String path) throws MalformedURLException
+    {
+        if (path == null || !path.startsWith(URIUtil.SLASH))
+            throw new MalformedURLException(path);
+
+        if (_baseResource == null)
+            return null;
+
+        try
+        {
+            path = URIUtil.canonicalPath(path);
+            Resource resource = _baseResource.addPath(path);
+            
+            if (checkAlias(path,resource))
+                return resource;
+            return null;
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean checkAlias(String path, Resource resource)
+    {
+        // Is the resource aliased?
+        if (!_aliasesAllowed && resource.getAlias() != null)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("Aliased resource: " + resource + "~=" + resource.getAlias());
+
+            // alias checks
+            for (Iterator<AliasCheck> i=_aliasChecks.iterator();i.hasNext();)
+            {
+                AliasCheck check = i.next();
+                if (check.check(path,resource))
+                {
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("Aliased resource: " + resource + " approved by " + check);
+                    return true;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Convert URL to Resource wrapper for {@link Resource#newResource(URL)} enables extensions to provide alternate resource implementations.
+     */
+    public Resource newResource(URL url) throws IOException
+    {
+        return Resource.newResource(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Convert a URL or path to a Resource. The default implementation is a wrapper for {@link Resource#newResource(String)}.
+     *
+     * @param urlOrPath
+     *            The URL or path to convert
+     * @return The Resource for the URL/path
+     * @throws IOException
+     *             The Resource could not be created.
+     */
+    public Resource newResource(String urlOrPath) throws IOException
+    {
+        return Resource.newResource(urlOrPath);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public Set<String> getResourcePaths(String path)
+    {
+        try
+        {
+            path = URIUtil.canonicalPath(path);
+            Resource resource = getResource(path);
+
+            if (resource != null && resource.exists())
+            {
+                if (!path.endsWith(URIUtil.SLASH))
+                    path = path + URIUtil.SLASH;
+
+                String[] l = resource.list();
+                if (l != null)
+                {
+                    HashSet<String> set = new HashSet<String>();
+                    for (int i = 0; i < l.length; i++)
+                        set.add(path + l[i]);
+                    return set;
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+        return Collections.emptySet();
+    }
+
+    /* ------------------------------------------------------------ */
+    private String normalizeHostname(String host)
+    {
+        if (host == null)
+            return null;
+
+        if (host.endsWith("."))
+            return host.substring(0,host.length() - 1);
+
+        return host;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Add an AliasCheck instance to possibly permit aliased resources
+     * @param check The alias checker
+     */
+    public void addAliasCheck(AliasCheck check)
+    {
+        _aliasChecks.add(check);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Mutable list of Alias checks
+     */
+    public List<AliasCheck> getAliasChecks()
+    {
+        return _aliasChecks;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Context.
+     * <p>
+     * A partial implementation of {@link javax.servlet.ServletContext}. A complete implementation is provided by the derived {@link ContextHandler}.
+     * </p>
+     *
+     *
+     */
+    public class Context implements ServletContext
+    {
+        protected int _majorVersion = 3;
+        protected int _minorVersion = 0;
+        protected boolean _enabled = true; //whether or not the dynamic API is enabled for callers
+
+        /* ------------------------------------------------------------ */
+        protected Context()
+        {
+        }
+
+        /* ------------------------------------------------------------ */
+        public ContextHandler getContextHandler()
+        {
+            // TODO reduce visibility of this method
+            return ContextHandler.this;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getContext(java.lang.String)
+         */
+        @Override
+        public ServletContext getContext(String uripath)
+        {
+            List<ContextHandler> contexts = new ArrayList<ContextHandler>();
+            Handler[] handlers = getServer().getChildHandlersByClass(ContextHandler.class);
+            String matched_path = null;
+
+            for (Handler handler : handlers)
+            {
+                if (handler == null)
+                    continue;
+                ContextHandler ch = (ContextHandler)handler;
+                String context_path = ch.getContextPath();
+
+                if (uripath.equals(context_path) || (uripath.startsWith(context_path) && uripath.charAt(context_path.length()) == '/')
+                        || "/".equals(context_path))
+                {
+                    // look first for vhost matching context only
+                    if (getVirtualHosts() != null && getVirtualHosts().length > 0)
+                    {
+                        if (ch.getVirtualHosts() != null && ch.getVirtualHosts().length > 0)
+                        {
+                            for (String h1 : getVirtualHosts())
+                                for (String h2 : ch.getVirtualHosts())
+                                    if (h1.equals(h2))
+                                    {
+                                        if (matched_path == null || context_path.length() > matched_path.length())
+                                        {
+                                            contexts.clear();
+                                            matched_path = context_path;
+                                        }
+
+                                        if (matched_path.equals(context_path))
+                                            contexts.add(ch);
+                                    }
+                        }
+                    }
+                    else
+                    {
+                        if (matched_path == null || context_path.length() > matched_path.length())
+                        {
+                            contexts.clear();
+                            matched_path = context_path;
+                        }
+
+                        if (matched_path.equals(context_path))
+                            contexts.add(ch);
+                    }
+                }
+            }
+
+            if (contexts.size() > 0)
+                return contexts.get(0)._scontext;
+
+            // try again ignoring virtual hosts
+            matched_path = null;
+            for (Handler handler : handlers)
+            {
+                if (handler == null)
+                    continue;
+                ContextHandler ch = (ContextHandler)handler;
+                String context_path = ch.getContextPath();
+
+                if (uripath.equals(context_path) || (uripath.startsWith(context_path) && uripath.charAt(context_path.length()) == '/')
+                        || "/".equals(context_path))
+                {
+                    if (matched_path == null || context_path.length() > matched_path.length())
+                    {
+                        contexts.clear();
+                        matched_path = context_path;
+                    }
+
+                    if (matched_path.equals(context_path))
+                        contexts.add(ch);
+                }
+            }
+
+            if (contexts.size() > 0)
+                return contexts.get(0)._scontext;
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getMajorVersion()
+         */
+        @Override
+        public int getMajorVersion()
+        {
+            return 3;
+        }
+      
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+         */
+        @Override
+        public String getMimeType(String file)
+        {
+            if (_mimeTypes == null)
+                return null;
+            Buffer mime = _mimeTypes.getMimeByExtension(file);
+            if (mime != null)
+                return mime.toString();
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getMinorVersion()
+         */
+        @Override
+        public int getMinorVersion()
+        {
+            return 0;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+         */
+        @Override
+        public RequestDispatcher getNamedDispatcher(String name)
+        {
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
+         */
+        @Override
+        public RequestDispatcher getRequestDispatcher(String uriInContext)
+        {
+            if (uriInContext == null)
+                return null;
+
+            if (!uriInContext.startsWith("/"))
+                return null;
+
+            try
+            {
+                String query = null;
+                int q = 0;
+                if ((q = uriInContext.indexOf('?')) > 0)
+                {
+                    query = uriInContext.substring(q + 1);
+                    uriInContext = uriInContext.substring(0,q);
+                }
+
+                String pathInContext = URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
+                if (pathInContext!=null)
+                {
+                    String uri = URIUtil.addPaths(getContextPath(),uriInContext);
+                    ContextHandler context = ContextHandler.this;
+                    return new Dispatcher(context,uri,pathInContext,query);
+                }
+            }
+            catch (Exception e)
+            {
+                LOG.ignore(e);
+            }
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+         */
+        @Override
+        public String getRealPath(String path)
+        {
+            if (path == null)
+                return null;
+            if (path.length() == 0)
+                path = URIUtil.SLASH;
+            else if (path.charAt(0) != '/')
+                path = URIUtil.SLASH + path;
+
+            try
+            {
+                Resource resource = ContextHandler.this.getResource(path);
+                if (resource != null)
+                {
+                    File file = resource.getFile();
+                    if (file != null)
+                        return file.getCanonicalPath();
+                }
+            }
+            catch (Exception e)
+            {
+                LOG.ignore(e);
+            }
+
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public URL getResource(String path) throws MalformedURLException
+        {
+            Resource resource = ContextHandler.this.getResource(path);
+            if (resource != null && resource.exists())
+                return resource.getURL();
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+         */
+        @Override
+        public InputStream getResourceAsStream(String path)
+        {
+            try
+            {
+                URL url = getResource(path);
+                if (url == null)
+                    return null;
+                Resource r = Resource.newResource(url);
+                return r.getInputStream();
+            }
+            catch (Exception e)
+            {
+                LOG.ignore(e);
+                return null;
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+         */
+        @Override
+        public Set getResourcePaths(String path)
+        {
+            return ContextHandler.this.getResourcePaths(path);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getServerInfo()
+         */
+        @Override
+        public String getServerInfo()
+        {
+            return "jetty/" + Server.getVersion();
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+         */
+        @Override
+        @Deprecated
+        public Servlet getServlet(String name) throws ServletException
+        {
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getServletNames()
+         */
+        @SuppressWarnings("unchecked")
+        @Override
+        @Deprecated
+        public Enumeration getServletNames()
+        {
+            return Collections.enumeration(Collections.EMPTY_LIST);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getServlets()
+         */
+        @SuppressWarnings("unchecked")
+        @Override
+        @Deprecated
+        public Enumeration getServlets()
+        {
+            return Collections.enumeration(Collections.EMPTY_LIST);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String)
+         */
+        @Override
+        public void log(Exception exception, String msg)
+        {
+            _logger.warn(msg,exception);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#log(java.lang.String)
+         */
+        @Override
+        public void log(String msg)
+        {
+            _logger.info(msg);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable)
+         */
+        @Override
+        public void log(String message, Throwable throwable)
+        {
+            _logger.warn(message,throwable);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+         */
+        @Override
+        public String getInitParameter(String name)
+        {
+            return ContextHandler.this.getInitParameter(name);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getInitParameterNames()
+         */
+        @SuppressWarnings("unchecked")
+        @Override
+        public Enumeration getInitParameterNames()
+        {
+            return ContextHandler.this.getInitParameterNames();
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+         */
+        @Override
+        public synchronized Object getAttribute(String name)
+        {
+            Object o = ContextHandler.this.getAttribute(name);
+            if (o == null && _contextAttributes != null)
+                o = _contextAttributes.getAttribute(name);
+            return o;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getAttributeNames()
+         */
+        @SuppressWarnings("unchecked")
+        @Override
+        public synchronized Enumeration getAttributeNames()
+        {
+            HashSet<String> set = new HashSet<String>();
+            if (_contextAttributes != null)
+            {
+                Enumeration<String> e = _contextAttributes.getAttributeNames();
+                while (e.hasMoreElements())
+                    set.add(e.nextElement());
+            }
+            Enumeration<String> e = _attributes.getAttributeNames();
+            while (e.hasMoreElements())
+                set.add(e.nextElement());
+
+            return Collections.enumeration(set);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
+         */
+        @Override
+        public synchronized void setAttribute(String name, Object value)
+        {
+            checkManagedAttribute(name,value);
+            Object old_value = _contextAttributes.getAttribute(name);
+
+            if (value == null)
+                _contextAttributes.removeAttribute(name);
+            else
+                _contextAttributes.setAttribute(name,value);
+
+            if (_contextAttributeListeners != null)
+            {
+                ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext,name,old_value == null?value:old_value);
+
+                for (int i = 0; i < LazyList.size(_contextAttributeListeners); i++)
+                {
+                    ServletContextAttributeListener l = (ServletContextAttributeListener)LazyList.get(_contextAttributeListeners,i);
+
+                    if (old_value == null)
+                        l.attributeAdded(event);
+                    else if (value == null)
+                        l.attributeRemoved(event);
+                    else
+                        l.attributeReplaced(event);
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+         */
+        @Override
+        public synchronized void removeAttribute(String name)
+        {
+            checkManagedAttribute(name,null);
+
+            if (_contextAttributes == null)
+            {
+                // Set it on the handler
+                _attributes.removeAttribute(name);
+                return;
+            }
+
+            Object old_value = _contextAttributes.getAttribute(name);
+            _contextAttributes.removeAttribute(name);
+            if (old_value != null)
+            {
+                if (_contextAttributeListeners != null)
+                {
+                    ServletContextAttributeEvent event = new ServletContextAttributeEvent(_scontext,name,old_value);
+
+                    for (int i = 0; i < LazyList.size(_contextAttributeListeners); i++)
+                        ((ServletContextAttributeListener)LazyList.get(_contextAttributeListeners,i)).attributeRemoved(event);
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * @see javax.servlet.ServletContext#getServletContextName()
+         */
+        @Override
+        public String getServletContextName()
+        {
+            String name = ContextHandler.this.getDisplayName();
+            if (name == null)
+                name = ContextHandler.this.getContextPath();
+            return name;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String getContextPath()
+        {
+            if ((_contextPath != null) && _contextPath.equals(URIUtil.SLASH))
+                return "";
+
+            return _contextPath;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return "ServletContext@" + ContextHandler.this.toString();
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public boolean setInitParameter(String name, String value)
+        {
+            if (ContextHandler.this.getInitParameter(name) != null)
+                return false;
+            ContextHandler.this.getInitParams().put(name,value);
+            return true;
+        }
+
+        /* ------------------------------------------------------------ */
+        final private static String __unimplmented="Unimplemented - use org.eclipse.jetty.servlet.ServletContextHandler";
+
+        @Override
+        public Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Dynamic addFilter(String filterName, Filter filter)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Dynamic addFilter(String filterName, String className)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, String className)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public <T extends Filter> T createFilter(Class<T> c) throws ServletException
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public <T extends Servlet> T createServlet(Class<T> c) throws ServletException
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public FilterRegistration getFilterRegistration(String filterName)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Map<String, ? extends FilterRegistration> getFilterRegistrations()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public ServletRegistration getServletRegistration(String servletName)
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public Map<String, ? extends ServletRegistration> getServletRegistrations()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public SessionCookieConfig getSessionCookieConfig()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        @Override
+        public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
+        {
+            LOG.warn(__unimplmented);
+        }
+
+        @Override
+        public void addListener(String className)
+        {
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            try
+            {
+                Class<? extends EventListener> clazz = _classLoader==null?Loader.loadClass(ContextHandler.class,className):_classLoader.loadClass(className);
+                addListener(clazz);
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        @Override
+        public <T extends EventListener> void addListener(T t)
+        {            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            ContextHandler.this.addEventListener(t);
+            ContextHandler.this.restrictEventListener(t);
+        }
+
+        @Override
+        public void addListener(Class<? extends EventListener> listenerClass)
+        {            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+
+            try
+            {
+                EventListener e = createListener(listenerClass);
+                ContextHandler.this.addEventListener(e);
+                ContextHandler.this.restrictEventListener(e);
+            }
+            catch (ServletException e)
+            {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        @Override
+        public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
+        {
+            try
+            {
+                return clazz.newInstance();
+            }
+            catch (InstantiationException e)
+            {
+                throw new ServletException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new ServletException(e);
+            }
+        }
+
+        @Override
+        public ClassLoader getClassLoader()
+        {
+            AccessController.checkPermission(new RuntimePermission("getClassLoader"));
+            return _classLoader;
+        }
+
+        @Override
+        public int getEffectiveMajorVersion()
+        {
+            return _majorVersion;
+        }
+
+        @Override
+        public int getEffectiveMinorVersion()
+        {
+            return _minorVersion;
+        }
+
+        public void setEffectiveMajorVersion (int v)
+        {
+            _majorVersion = v;
+        }
+        
+        public void setEffectiveMinorVersion (int v)
+        {
+            _minorVersion = v;
+        }
+        
+        @Override
+        public JspConfigDescriptor getJspConfigDescriptor()
+        {
+            LOG.warn(__unimplmented);
+            return null;
+        }
+
+        public void setJspConfigDescriptor(JspConfigDescriptor d)
+        {
+            
+        }
+        
+        @Override
+        public void declareRoles(String... roleNames)
+        {
+            if (!isStarting())
+                throw new IllegalStateException ();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void setEnabled(boolean enabled)
+        {
+            _enabled = enabled;
+        }
+
+        public boolean isEnabled()
+        {
+            return _enabled;
+        }
+    }
+
+    private static class CLDump implements Dumpable
+    {
+        final ClassLoader _loader;
+
+        CLDump(ClassLoader loader)
+        {
+            _loader = loader;
+        }
+
+        public String dump()
+        {
+            return AggregateLifeCycle.dump(this);
+        }
+
+        public void dump(Appendable out, String indent) throws IOException
+        {
+            out.append(String.valueOf(_loader)).append("\n");
+
+            if (_loader != null)
+            {
+                Object parent = _loader.getParent();
+                if (parent != null)
+                {
+                    if (!(parent instanceof Dumpable))
+                        parent = new CLDump((ClassLoader)parent);
+
+                    if (_loader instanceof URLClassLoader)
+                        AggregateLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent));
+                    else
+                        AggregateLifeCycle.dump(out,indent,Collections.singleton(parent));
+                }
+            }
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Interface to check aliases
+     */
+    public interface AliasCheck
+    {
+        /* ------------------------------------------------------------ */
+        /** Check an alias
+         * @param path The path the aliased resource was created for
+         * @param resource The aliased resourced
+         * @return True if the resource is OK to be served.
+         */
+        boolean check(String path, Resource resource);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Approve Aliases with same suffix.
+     * Eg. a symbolic link from /foobar.html to /somewhere/wibble.html would be
+     * approved because both the resource and alias end with ".html".
+     */
+    @Deprecated
+    public static class ApproveSameSuffixAliases implements AliasCheck
+    {
+        {
+            LOG.warn("ApproveSameSuffixAlias is not safe for production");
+        }
+        
+        public boolean check(String path, Resource resource)
+        {
+            int dot = path.lastIndexOf('.');
+            if (dot<0)
+                return false;
+            String suffix=path.substring(dot);
+            return resource.toString().endsWith(suffix);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Approve Aliases with a path prefix.
+     * Eg. a symbolic link from /dirA/foobar.html to /dirB/foobar.html would be
+     * approved because both the resource and alias end with "/foobar.html".
+     */
+    @Deprecated
+    public static class ApprovePathPrefixAliases implements AliasCheck
+    {
+        {
+            LOG.warn("ApprovePathPrefixAliases is not safe for production");
+        }
+        
+        public boolean check(String path, Resource resource)
+        {
+            int slash = path.lastIndexOf('/');
+            if (slash<0 || slash==path.length()-1)
+                return false;
+            String suffix=path.substring(slash);
+            return resource.toString().endsWith(suffix);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Approve Aliases of a non existent directory.
+     * If a directory "/foobar/" does not exist, then the resource is 
+     * aliased to "/foobar".  Accept such aliases.
+     */
+    public static class ApproveNonExistentDirectoryAliases implements AliasCheck
+    {
+        public boolean check(String path, Resource resource)
+        {
+            if (resource.exists())
+                return false;
+            
+            String a=resource.getAlias().toString();
+            String r=resource.getURL().toString();
+            
+            if (a.length()>r.length())
+                return a.startsWith(r) && a.length()==r.length()+1 && a.endsWith("/");
+            else
+                return r.startsWith(a) && r.length()==a.length()+1 && r.endsWith("/");
+        }
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/src/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
new file mode 100644
index 0000000..47d4c20
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java
@@ -0,0 +1,332 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.AsyncContinuation;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** ContextHandlerCollection.
+ * 
+ * This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a 
+ * {@link org.eclipse.jetty.http.PathMap} to it's contained handlers based
+ * on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s.
+ * The contexts do not need to be directly contained, only children of the contained handlers.
+ * Multiple contexts may have the same context path and they are called in order until one
+ * handles the request.  
+ * 
+ * @org.apache.xbean.XBean element="contexts"
+ */
+public class ContextHandlerCollection extends HandlerCollection
+{
+    private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class);
+ 
+    private volatile PathMap _contextMap;
+    private Class<? extends ContextHandler> _contextClass = ContextHandler.class;
+    
+    /* ------------------------------------------------------------ */
+    public ContextHandlerCollection()
+    {
+        super(true);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Remap the context paths.
+     */
+    public void mapContexts()
+    {
+        PathMap contextMap = new PathMap();
+        Handler[] branches = getHandlers();
+        
+        
+        for (int b=0;branches!=null && b<branches.length;b++)
+        {
+            Handler[] handlers=null;
+            
+            if (branches[b] instanceof ContextHandler)
+            {
+                handlers = new Handler[]{ branches[b] };
+            }
+            else if (branches[b] instanceof HandlerContainer)
+            {
+                handlers = ((HandlerContainer)branches[b]).getChildHandlersByClass(ContextHandler.class);
+            }
+            else 
+                continue;
+            
+            for (int i=0;i<handlers.length;i++)
+            {
+                ContextHandler handler=(ContextHandler)handlers[i];
+
+                String contextPath=handler.getContextPath();
+
+                if (contextPath==null || contextPath.indexOf(',')>=0 || contextPath.startsWith("*"))
+                    throw new IllegalArgumentException ("Illegal context spec:"+contextPath);
+
+                if(!contextPath.startsWith("/"))
+                    contextPath='/'+contextPath;
+
+                if (contextPath.length()>1)
+                {
+                    if (contextPath.endsWith("/"))
+                        contextPath+="*";
+                    else if (!contextPath.endsWith("/*"))
+                        contextPath+="/*";
+                }
+
+                Object contexts=contextMap.get(contextPath);
+                String[] vhosts=handler.getVirtualHosts();
+
+                
+                if (vhosts!=null && vhosts.length>0)
+                {
+                    Map hosts;
+
+                    if (contexts instanceof Map)
+                        hosts=(Map)contexts;
+                    else
+                    {
+                        hosts=new HashMap(); 
+                        hosts.put("*",contexts);
+                        contextMap.put(contextPath, hosts);
+                    }
+
+                    for (int j=0;j<vhosts.length;j++)
+                    {
+                        String vhost=vhosts[j];
+                        contexts=hosts.get(vhost);
+                        contexts=LazyList.add(contexts,branches[b]);
+                        hosts.put(vhost,contexts);
+                    }
+                }
+                else if (contexts instanceof Map)
+                {
+                    Map hosts=(Map)contexts;
+                    contexts=hosts.get("*");
+                    contexts= LazyList.add(contexts, branches[b]);
+                    hosts.put("*",contexts);
+                }
+                else
+                {
+                    contexts= LazyList.add(contexts, branches[b]);
+                    contextMap.put(contextPath, contexts);
+                }
+            }
+        }
+        _contextMap=contextMap;
+
+    }
+    
+
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.HandlerCollection#setHandlers(org.eclipse.jetty.server.server.Handler[])
+     */
+    @Override
+    public void setHandlers(Handler[] handlers)
+    {
+        _contextMap=null;
+        super.setHandlers(handlers);
+        if (isStarted())
+            mapContexts();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        mapContexts();
+        super.doStart();
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        Handler[] handlers = getHandlers();
+        if (handlers==null || handlers.length==0)
+	    return;
+	
+	AsyncContinuation async = baseRequest.getAsyncContinuation();
+	if (async.isAsync())
+	{
+	    ContextHandler context=async.getContextHandler();
+	    if (context!=null)
+	    {
+	        context.handle(target,baseRequest,request, response);
+	        return;
+	    }
+	}
+	
+	// data structure which maps a request to a context; first-best match wins
+	// { context path => 
+	//     { virtual host => context } 
+	// }
+	PathMap map = _contextMap;
+	if (map!=null && target!=null && target.startsWith("/"))
+	{
+	    // first, get all contexts matched by context path
+	    Object contexts = map.getLazyMatches(target);
+
+            for (int i=0; i<LazyList.size(contexts); i++)
+            {
+                // then, match against the virtualhost of each context
+                Map.Entry entry = (Map.Entry)LazyList.get(contexts, i);
+                Object list = entry.getValue();
+
+                if (list instanceof Map)
+                {
+                    Map hosts = (Map)list;
+                    String host = normalizeHostname(request.getServerName());
+           
+                    // explicitly-defined virtual hosts, most specific
+                    list=hosts.get(host);
+                    for (int j=0; j<LazyList.size(list); j++)
+                    {
+                        Handler handler = (Handler)LazyList.get(list,j);
+                        handler.handle(target,baseRequest, request, response);
+                        if (baseRequest.isHandled())
+                            return;
+                    }
+                    
+                    // wildcard for one level of names 
+                    list=hosts.get("*."+host.substring(host.indexOf(".")+1));
+                    for (int j=0; j<LazyList.size(list); j++)
+                    {
+                        Handler handler = (Handler)LazyList.get(list,j);
+                        handler.handle(target,baseRequest, request, response);
+                        if (baseRequest.isHandled())
+                            return;
+                    }
+                    
+                    // no virtualhosts defined for the context, least specific
+                    // will handle any request that does not match to a specific virtual host above
+                    list=hosts.get("*");
+                    for (int j=0; j<LazyList.size(list); j++)
+                    {
+                        Handler handler = (Handler)LazyList.get(list,j);
+                        handler.handle(target,baseRequest, request, response);
+                        if (baseRequest.isHandled())
+                            return;
+                    }
+                }
+                else
+                {
+                    for (int j=0; j<LazyList.size(list); j++)
+                    {
+                        Handler handler = (Handler)LazyList.get(list,j);
+                        handler.handle(target,baseRequest, request, response);
+                        if (baseRequest.isHandled())
+                            return;
+                    }
+                }
+	    }
+	}
+	else
+	{
+            // This may not work in all circumstances... but then I think it should never be called
+	    for (int i=0;i<handlers.length;i++)
+	    {
+		handlers[i].handle(target,baseRequest, request, response);
+		if ( baseRequest.isHandled())
+		    return;
+	    }
+	}
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Add a context handler.
+     * @param contextPath  The context path to add
+     * @return the ContextHandler just added
+     */
+    public ContextHandler addContext(String contextPath,String resourceBase) 
+    {
+        try
+        {
+            ContextHandler context = _contextClass.newInstance();
+            context.setContextPath(contextPath);
+            context.setResourceBase(resourceBase);
+            addHandler(context);
+            return context;
+        }
+        catch (Exception e)
+        {
+            LOG.debug(e);
+            throw new Error(e);
+        }
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The class to use to add new Contexts
+     */
+    public Class getContextClass()
+    {
+        return _contextClass;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param contextClass The class to use to add new Contexts
+     */
+    public void setContextClass(Class contextClass)
+    {
+        if (contextClass ==null || !(ContextHandler.class.isAssignableFrom(contextClass)))
+            throw new IllegalArgumentException();
+        _contextClass = contextClass;
+    }
+    
+    /* ------------------------------------------------------------ */
+    private String normalizeHostname( String host )
+    {
+        if ( host == null )
+            return null;
+        
+        if ( host.endsWith( "." ) )
+            return host.substring( 0, host.length() -1);
+      
+        return host;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/DebugHandler.java b/src/java/org/eclipse/jetty/server/handler/DebugHandler.java
new file mode 100644
index 0000000..1bcc043
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/DebugHandler.java
@@ -0,0 +1,158 @@
+//
+//  ========================================================================
+//  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.handler; 
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Locale;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.DateCache;
+import org.eclipse.jetty.util.RolloverFileOutputStream;
+
+
+/** 
+ * Debug Handler.
+ * A lightweight debug handler that can be used in production code.
+ * Details of the request and response are written to an output stream
+ * and the current thread name is updated with information that will link
+ * to the details in that output.
+ */
+public class DebugHandler extends HandlerWrapper
+{
+    private DateCache _date=new DateCache("HH:mm:ss", Locale.US);
+    private OutputStream _out;
+    private PrintStream _print;
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, ServletException
+    {
+        final Response base_response = baseRequest.getResponse();
+        final Thread thread=Thread.currentThread();
+        final String old_name=thread.getName();
+
+        boolean suspend=false;
+        boolean retry=false;
+        String name=(String)request.getAttribute("org.eclipse.jetty.thread.name");
+        if (name==null)
+            name=old_name+":"+baseRequest.getScheme()+"://"+baseRequest.getLocalAddr()+":"+baseRequest.getLocalPort()+baseRequest.getUri();
+        else
+            retry=true;
+        
+        String ex=null;
+        try
+        {
+            final String d=_date.now();
+            final int ms=_date.lastMs();
+            
+            if (retry)
+                _print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" RETRY");
+            else
+                _print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" "+baseRequest.getRemoteAddr()+" "+request.getMethod()+" "+baseRequest.getHeader("Cookie")+"; "+baseRequest.getHeader("User-Agent"));
+            thread.setName(name);
+            
+            getHandler().handle(target,baseRequest,request,response);
+        }
+        catch(IOException ioe)
+        {
+            ex=ioe.toString();
+            throw ioe;
+        }
+        catch(ServletException se)
+        {
+            ex=se.toString()+":"+se.getCause();
+            throw se;
+        }
+        catch(RuntimeException rte)
+        {
+            ex=rte.toString();
+            throw rte;
+        }
+        catch(Error e)
+        {
+            ex=e.toString();
+            throw e;
+        }
+        finally
+        {
+            thread.setName(old_name);
+            final String d=_date.now();
+            final int ms=_date.lastMs();
+            suspend=baseRequest.getAsyncContinuation().isSuspended();
+            if (suspend)
+            {
+                request.setAttribute("org.eclipse.jetty.thread.name",name);
+                _print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" SUSPEND");
+            }
+            else
+                _print.println(d+(ms>99?".":(ms>9?".0":".00"))+ms+":"+name+" "+base_response.getStatus()+
+		        (ex==null?"":("/"+ex))+
+		        " "+base_response.getContentType()+" "+base_response.getContentCount());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_out==null)
+            _out=new RolloverFileOutputStream("./logs/yyyy_mm_dd.debug.log",true);
+        _print=new PrintStream(_out);
+        super.doStart();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        _print.close();
+    }
+
+    /**
+     * @return the out
+     */
+    public OutputStream getOutputStream()
+    {
+        return _out;
+    }
+
+    /**
+     * @param out the out to set
+     */
+    public void setOutputStream(OutputStream out)
+    {
+        _out = out;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/src/java/org/eclipse/jetty/server/handler/DefaultHandler.java
new file mode 100644
index 0000000..ee5a51c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/DefaultHandler.java
@@ -0,0 +1,208 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.ByteArrayISO8859Writer;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+
+/* ------------------------------------------------------------ */
+/** Default Handler.
+ * 
+ * This handle will deal with unhandled requests in the server.
+ * For requests for favicon.ico, the Jetty icon is served. 
+ * For reqests to '/' a 404 with a list of known contexts is served.
+ * For all other requests a normal 404 is served.
+ * TODO Implement OPTIONS and TRACE methods for the server.
+ * 
+ * 
+ * @org.apache.xbean.XBean
+ */
+public class DefaultHandler extends AbstractHandler
+{
+    private static final Logger LOG = Log.getLogger(DefaultHandler.class);
+
+    final long _faviconModified=(System.currentTimeMillis()/1000)*1000L;
+    byte[] _favicon;
+    boolean _serveIcon=true;
+    boolean _showContexts=true;
+    
+    public DefaultHandler()
+    {
+        try
+        {
+            URL fav = this.getClass().getClassLoader().getResource("org/eclipse/jetty/favicon.ico");
+            if (fav!=null)
+            {
+                Resource r = Resource.newResource(fav);
+                _favicon=IO.readBytes(r.getInputStream());
+            }
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {              
+        if (response.isCommitted() || baseRequest.isHandled())
+            return;
+        
+        baseRequest.setHandled(true);
+        
+        String method=request.getMethod();
+
+        // little cheat for common request
+        if (_serveIcon && _favicon!=null && method.equals(HttpMethods.GET) && request.getRequestURI().equals("/favicon.ico"))
+        {
+            if (request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE)==_faviconModified)
+                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+            else
+            {
+                response.setStatus(HttpServletResponse.SC_OK);
+                response.setContentType("image/x-icon");
+                response.setContentLength(_favicon.length);
+                response.setDateHeader(HttpHeaders.LAST_MODIFIED, _faviconModified);
+                response.setHeader(HttpHeaders.CACHE_CONTROL,"max-age=360000,public");
+                response.getOutputStream().write(_favicon);
+            }
+            return;
+        }
+        
+        
+        if (!method.equals(HttpMethods.GET) || !request.getRequestURI().equals("/"))
+        {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;   
+        }
+
+        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+        response.setContentType(MimeTypes.TEXT_HTML);
+        
+        ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500);
+        
+        writer.write("<HTML>\n<HEAD>\n<TITLE>Error 404 - Not Found");
+        writer.write("</TITLE>\n<BODY>\n<H2>Error 404 - Not Found.</H2>\n");
+        writer.write("No context on this server matched or handled this request.<BR>");
+        
+        if (_showContexts)
+        {
+            writer.write("Contexts known to this server are: <ul>");
+            
+            Server server = getServer();
+            Handler[] handlers = server==null?null:server.getChildHandlersByClass(ContextHandler.class);
+     
+            for (int i=0;handlers!=null && i<handlers.length;i++)
+            {
+                ContextHandler context = (ContextHandler)handlers[i];
+                if (context.isRunning())
+                {
+                    writer.write("<li><a href=\"");
+                    if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+                        writer.write("http://"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+                    writer.write(context.getContextPath());
+                    if (context.getContextPath().length()>1 && context.getContextPath().endsWith("/"))
+                        writer.write("/");
+                    writer.write("\">");
+                    writer.write(context.getContextPath());
+                    if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+                        writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+                    writer.write("&nbsp;--->&nbsp;");
+                    writer.write(context.toString());
+                    writer.write("</a></li>\n");
+                }
+                else
+                {
+                    writer.write("<li>");
+                    writer.write(context.getContextPath());
+                    if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0)
+                        writer.write("&nbsp;@&nbsp;"+context.getVirtualHosts()[0]+":"+request.getLocalPort());
+                    writer.write("&nbsp;--->&nbsp;");
+                    writer.write(context.toString());
+                    if (context.isFailed())
+                        writer.write(" [failed]");
+                    if (context.isStopped())
+                        writer.write(" [stopped]");
+                    writer.write("</li>\n");
+                }
+            }
+        }
+        
+        for (int i=0;i<10;i++)
+            writer.write("\n<!-- Padding for IE                  -->");
+        
+        writer.write("\n</BODY>\n</HTML>\n");
+        writer.flush();
+        response.setContentLength(writer.size());
+        OutputStream out=response.getOutputStream();
+        writer.writeTo(out);
+        out.close();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns true if the handle can server the jetty favicon.ico
+     */
+    public boolean getServeIcon()
+    {
+        return _serveIcon;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param serveIcon true if the handle can server the jetty favicon.ico
+     */
+    public void setServeIcon(boolean serveIcon)
+    {
+        _serveIcon = serveIcon;
+    }
+    
+    public boolean getShowContexts()
+    {
+        return _showContexts;
+    }
+
+    public void setShowContexts(boolean show)
+    {
+        _showContexts = show;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/src/java/org/eclipse/jetty/server/handler/ErrorHandler.java
new file mode 100644
index 0000000..8863449
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ErrorHandler.java
@@ -0,0 +1,285 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.ByteArrayISO8859Writer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Handler for Error pages
+ * An ErrorHandler is registered with {@link ContextHandler#setErrorHandler(ErrorHandler)} or 
+ * {@link org.eclipse.jetty.server.Server#addBean(Object)}.   
+ * It is called by the HttpResponse.sendError method to write a error page.
+ * 
+ */
+public class ErrorHandler extends AbstractHandler
+{    
+    private static final Logger LOG = Log.getLogger(ErrorHandler.class);
+    public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
+    
+    boolean _showStacks=true;
+    boolean _showMessageInTitle=true;
+    String _cacheControl="must-revalidate,no-cache,no-store";
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
+    {
+        AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
+        String method = request.getMethod();
+        if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
+        {
+            connection.getRequest().setHandled(true);
+            return;
+        }
+        
+        if (this instanceof ErrorPageMapper)
+        {
+            String error_page=((ErrorPageMapper)this).getErrorPage(request);
+            if (error_page!=null && request.getServletContext()!=null)
+            {
+                String old_error_page=(String)request.getAttribute(ERROR_PAGE);
+                if (old_error_page==null || !old_error_page.equals(error_page))
+                {
+                    request.setAttribute(ERROR_PAGE, error_page);
+
+                    Dispatcher dispatcher = (Dispatcher) request.getServletContext().getRequestDispatcher(error_page);
+                    try
+                    {
+                        if(dispatcher!=null)
+                        {
+                            dispatcher.error(request, response);
+                            return;
+                        }
+                        LOG.warn("No error page "+error_page);
+                    }
+                    catch (ServletException e)
+                    {
+                        LOG.warn(Log.EXCEPTION, e);
+                        return;
+                    }
+                }
+            }
+        }
+        
+        connection.getRequest().setHandled(true);
+        response.setContentType(MimeTypes.TEXT_HTML_8859_1);    
+        if (_cacheControl!=null)
+            response.setHeader(HttpHeaders.CACHE_CONTROL, _cacheControl);
+        ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(4096);
+        handleErrorPage(request, writer, connection.getResponse().getStatus(), connection.getResponse().getReason());
+        writer.flush();
+        response.setContentLength(writer.size());
+        writer.writeTo(response.getOutputStream());
+        writer.destroy();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
+        throws IOException
+    {
+        writeErrorPage(request, writer, code, message, _showStacks);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
+        throws IOException
+    {
+        if (message == null)
+            message=HttpStatus.getMessage(code);
+
+        writer.write("<html>\n<head>\n");
+        writeErrorPageHead(request,writer,code,message);
+        writer.write("</head>\n<body>");
+        writeErrorPageBody(request,writer,code,message,showStacks);
+        writer.write("\n</body>\n</html>\n");
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message)
+        throws IOException
+        {
+        writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/>\n");
+        writer.write("<title>Error ");
+        writer.write(Integer.toString(code));
+
+        if (_showMessageInTitle)
+        {
+            writer.write(' ');
+            write(writer,message);
+        }
+        writer.write("</title>\n");    
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
+        throws IOException
+    {
+        String uri= request.getRequestURI();
+        
+        writeErrorPageMessage(request,writer,code,message,uri);
+        if (showStacks)
+            writeErrorPageStacks(request,writer);
+        writer.write("<hr /><i><small>Powered by Jetty://</small></i>");
+        for (int i= 0; i < 20; i++)
+            writer.write("<br/>                                                \n");
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message,String uri)
+    throws IOException
+    {
+        writer.write("<h2>HTTP ERROR ");
+        writer.write(Integer.toString(code));
+        writer.write("</h2>\n<p>Problem accessing ");
+        write(writer,uri);
+        writer.write(". Reason:\n<pre>    ");
+        write(writer,message);
+        writer.write("</pre></p>");
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeErrorPageStacks(HttpServletRequest request, Writer writer)
+        throws IOException
+    {
+        Throwable th = (Throwable)request.getAttribute("javax.servlet.error.exception");
+        while(th!=null)
+        {
+            writer.write("<h3>Caused by:</h3><pre>");
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            th.printStackTrace(pw);
+            pw.flush();
+            write(writer,sw.getBuffer().toString());
+            writer.write("</pre>\n");
+
+            th =th.getCause();
+        }
+    }
+        
+
+    /* ------------------------------------------------------------ */
+    /** Get the cacheControl.
+     * @return the cacheControl header to set on error responses.
+     */
+    public String getCacheControl()
+    {
+        return _cacheControl;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the cacheControl.
+     * @param cacheControl the cacheControl header to set on error responses.
+     */
+    public void setCacheControl(String cacheControl)
+    {
+        _cacheControl = cacheControl;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if stack traces are shown in the error pages
+     */
+    public boolean isShowStacks()
+    {
+        return _showStacks;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param showStacks True if stack traces are shown in the error pages
+     */
+    public void setShowStacks(boolean showStacks)
+    {
+        _showStacks = showStacks;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param showMessageInTitle if true, the error message appears in page title
+     */
+    public void setShowMessageInTitle(boolean showMessageInTitle)
+    {
+        _showMessageInTitle = showMessageInTitle;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public boolean getShowMessageInTitle()
+    {
+        return _showMessageInTitle;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void write(Writer writer,String string)
+        throws IOException
+    {
+        if (string==null)
+            return;
+        
+        for (int i=0;i<string.length();i++)
+        {
+            char c=string.charAt(i);
+            
+            switch(c)
+            {
+                case '&' :
+                    writer.write("&amp;");
+                    break;
+                case '<' :
+                    writer.write("&lt;");
+                    break;
+                case '>' :
+                    writer.write("&gt;");
+                    break;
+                    
+                default:
+                    if (Character.isISOControl(c) && !Character.isWhitespace(c))
+                        writer.write('?');
+                    else 
+                        writer.write(c);
+            }          
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public interface ErrorPageMapper
+    {
+        String getErrorPage(HttpServletRequest request);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/GzipHandler.java b/src/java/org/eclipse/jetty/server/handler/GzipHandler.java
new file mode 100644
index 0000000..c0c3b68
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/GzipHandler.java
@@ -0,0 +1,356 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
+import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * GZIP Handler This handler will gzip the content of a response if:
+ * <ul>
+ * <li>The filter is mapped to a matching path</li>
+ * <li>The response status code is >=200 and <300
+ * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li>
+ * <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or if no mimeTypes are defined the
+ * content-type is not "application/gzip"</li>
+ * <li>No content-encoding is specified by the resource</li>
+ * </ul>
+ * 
+ * <p>
+ * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and CPU cycles. If this handler is used for static content,
+ * then use of efficient direct NIO may be prevented, thus use of the gzip mechanism of the <code>org.eclipse.jetty.servlet.DefaultServlet</code> is advised instead.
+ * </p>
+ */
+public class GzipHandler extends HandlerWrapper
+{
+    private static final Logger LOG = Log.getLogger(GzipHandler.class);
+
+    protected Set<String> _mimeTypes;
+    protected Set<String> _excluded;
+    protected int _bufferSize = 8192;
+    protected int _minGzipSize = 256;
+    protected String _vary = "Accept-Encoding, User-Agent";
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Instantiates a new gzip handler.
+     */
+    public GzipHandler()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the mime types.
+     * 
+     * @return mime types to set
+     */
+    public Set<String> getMimeTypes()
+    {
+        return _mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the mime types.
+     * 
+     * @param mimeTypes
+     *            the mime types to set
+     */
+    public void setMimeTypes(Set<String> mimeTypes)
+    {
+        _mimeTypes = mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the mime types.
+     * 
+     * @param mimeTypes
+     *            the mime types to set
+     */
+    public void setMimeTypes(String mimeTypes)
+    {
+        if (mimeTypes != null)
+        {
+            _mimeTypes = new HashSet<String>();
+            StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
+            while (tok.hasMoreTokens())
+            {
+                _mimeTypes.add(tok.nextToken());
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the excluded user agents.
+     * 
+     * @return excluded user agents
+     */
+    public Set<String> getExcluded()
+    {
+        return _excluded;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the excluded user agents.
+     * 
+     * @param excluded
+     *            excluded user agents to set
+     */
+    public void setExcluded(Set<String> excluded)
+    {
+        _excluded = excluded;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the excluded user agents.
+     * 
+     * @param excluded
+     *            excluded user agents to set
+     */
+    public void setExcluded(String excluded)
+    {
+        if (excluded != null)
+        {
+            _excluded = new HashSet<String>();
+            StringTokenizer tok = new StringTokenizer(excluded,",",false);
+            while (tok.hasMoreTokens())
+                _excluded.add(tok.nextToken());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The value of the Vary header set if a response can be compressed.
+     */
+    public String getVary()
+    {
+        return _vary;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the value of the Vary header sent with responses that could be compressed.  
+     * <p>
+     * By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by 
+     * default from the excludedAgents. If user-agents are not to be excluded, then 
+     * this can be set to 'Accept-Encoding'.  Note also that shared caches may cache 
+     * many copies of a resource that is varied by User-Agent - one per variation of the 
+     * User-Agent, unless the cache does some normalization of the UA string.
+     * @param vary The value of the Vary header set if a response can be compressed.
+     */
+    public void setVary(String vary)
+    {
+        _vary = vary;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the buffer size.
+     * 
+     * @return the buffer size
+     */
+    public int getBufferSize()
+    {
+        return _bufferSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the buffer size.
+     * 
+     * @param bufferSize
+     *            buffer size to set
+     */
+    public void setBufferSize(int bufferSize)
+    {
+        _bufferSize = bufferSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the minimum reponse size.
+     * 
+     * @return minimum reponse size
+     */
+    public int getMinGzipSize()
+    {
+        return _minGzipSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the minimum reponse size.
+     * 
+     * @param minGzipSize
+     *            minimum reponse size
+     */
+    public void setMinGzipSize(int minGzipSize)
+    {
+        _minGzipSize = minGzipSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (_handler!=null && isStarted())
+        {
+            String ae = request.getHeader("accept-encoding");
+            if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding")
+                    && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod()))
+            {
+                if (_excluded!=null)
+                {
+                    String ua = request.getHeader("User-Agent");
+                    if (_excluded.contains(ua))
+                    {
+                        _handler.handle(target,baseRequest, request, response);
+                        return;
+                    }
+                }
+
+                final CompressedResponseWrapper wrappedResponse = newGzipResponseWrapper(request,response);
+                
+                boolean exceptional=true;
+                try
+                {
+                    _handler.handle(target, baseRequest, request, wrappedResponse);
+                    exceptional=false;
+                }
+                finally
+                {
+                    Continuation continuation = ContinuationSupport.getContinuation(request);
+                    if (continuation.isSuspended() && continuation.isResponseWrapped())   
+                    {
+                        continuation.addContinuationListener(new ContinuationListener()
+                        {
+                            public void onComplete(Continuation continuation)
+                            {
+                                try
+                                {
+                                    wrappedResponse.finish();
+                                }
+                                catch(IOException e)
+                                {
+                                    LOG.warn(e);
+                                }
+                            }
+
+                            public void onTimeout(Continuation continuation)
+                            {}
+                        });
+                    }
+                    else if (exceptional && !response.isCommitted())
+                    {
+                        wrappedResponse.resetBuffer();
+                        wrappedResponse.noCompression();
+                    }
+                    else
+                        wrappedResponse.finish();
+                }
+            }
+            else
+            {
+                _handler.handle(target,baseRequest, request, response);
+            }
+        }
+    }
+
+    /**
+     * Allows derived implementations to replace ResponseWrapper implementation.
+     *
+     * @param request the request
+     * @param response the response
+     * @return the gzip response wrapper
+     */
+    protected CompressedResponseWrapper newGzipResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+    {
+        return new CompressedResponseWrapper(request,response)
+        {
+            {
+                super.setMimeTypes(GzipHandler.this._mimeTypes);
+                super.setBufferSize(GzipHandler.this._bufferSize);
+                super.setMinCompressSize(GzipHandler.this._minGzipSize);
+            }
+            
+            @Override
+            protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+            {
+                return new AbstractCompressedStream("gzip",request,this,_vary)
+                {
+                    @Override
+                    protected DeflaterOutputStream createStream() throws IOException
+                    {
+                        return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
+                    }
+                };
+            }
+            
+            @Override
+            protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+            {
+                return GzipHandler.this.newWriter(out,encoding);
+            }
+        };
+    }
+    
+    /**
+     * Allows derived implementations to replace PrintWriter implementation.
+     *
+     * @param out the out
+     * @param encoding the encoding
+     * @return the prints the writer
+     * @throws UnsupportedEncodingException
+     */
+    protected PrintWriter newWriter(OutputStream out,String encoding) throws UnsupportedEncodingException
+    {
+        return encoding==null?new PrintWriter(out):new PrintWriter(new OutputStreamWriter(out,encoding));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/src/java/org/eclipse/jetty/server/handler/HandlerCollection.java
new file mode 100644
index 0000000..282a8fc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/HandlerCollection.java
@@ -0,0 +1,316 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiException;
+
+/* ------------------------------------------------------------ */
+/** A collection of handlers.  
+ * <p>
+ * The default implementations  calls all handlers in list order, 
+ * regardless of the response status or exceptions. Derived implementation
+ * may alter the order or the conditions of calling the contained 
+ * handlers.
+ * <p>
+ * 
+ * @org.apache.xbean.XBean
+ */
+public class HandlerCollection extends AbstractHandlerContainer
+{
+    private final boolean _mutableWhenRunning;
+    private volatile Handler[] _handlers;
+    private boolean _parallelStart=false; 
+
+    /* ------------------------------------------------------------ */
+    public HandlerCollection()
+    {
+        _mutableWhenRunning=false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public HandlerCollection(boolean mutableWhenRunning)
+    {
+        _mutableWhenRunning=mutableWhenRunning;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the handlers.
+     */
+    public Handler[] getHandlers()
+    {
+        return _handlers;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     * @param handlers The handlers to set.
+     */
+    public void setHandlers(Handler[] handlers)
+    {
+        if (!_mutableWhenRunning && isStarted())
+            throw new IllegalStateException(STARTED);
+        
+        Handler [] old_handlers = _handlers==null?null:_handlers.clone();
+        _handlers = handlers;
+        
+        Server server = getServer();
+        MultiException mex = new MultiException();
+        for (int i=0;handlers!=null && i<handlers.length;i++)
+        {
+            if (handlers[i].getServer()!=server)
+                handlers[i].setServer(server);
+        }
+
+        if (getServer()!=null)
+            getServer().getContainer().update(this, old_handlers, handlers, "handler");
+        
+        // stop old handlers
+        for (int i=0;old_handlers!=null && i<old_handlers.length;i++)
+        {
+            if (old_handlers[i]!=null)
+            {
+                try
+                {
+                    if (old_handlers[i].isStarted())
+                        old_handlers[i].stop();
+                }
+                catch (Throwable e)
+                {
+                    mex.add(e);
+                }
+            }
+        }
+                
+        mex.ifExceptionThrowRuntime();
+    }
+    
+
+    
+    /* ------------------------------------------------------------ */
+    /** Get the parrallelStart.
+     * @return true if the contained handlers are started in parallel.
+     */
+    public boolean isParallelStart()
+    {
+        return _parallelStart;
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    /** Set the parallelStart.
+     * @param parallelStart If true, contained handlers are started in parallel.
+     */
+    public void setParallelStart(boolean parallelStart)
+    {
+        this._parallelStart = parallelStart;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
+        throws IOException, ServletException
+    {
+        if (_handlers!=null && isStarted())
+        {
+            MultiException mex=null;
+            
+            for (int i=0;i<_handlers.length;i++)
+            {
+                try
+                {
+                    _handlers[i].handle(target,baseRequest, request, response);
+                }
+                catch(IOException e)
+                {
+                    throw e;
+                }
+                catch(RuntimeException e)
+                {
+                    throw e;
+                }
+                catch(Exception e)
+                {
+                    if (mex==null)
+                        mex=new MultiException();
+                    mex.add(e);
+                }
+            }
+            if (mex!=null)
+            {
+                if (mex.size()==1)
+                    throw new ServletException(mex.getThrowable(0));
+                else
+                    throw new ServletException(mex);
+            }
+            
+        }    
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.AbstractHandler#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        final MultiException mex=new MultiException();
+        if (_handlers!=null)
+        {
+            if (_parallelStart)
+            {
+                final CountDownLatch latch = new CountDownLatch(_handlers.length);
+                final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                for (int i=0;i<_handlers.length;i++)
+                {
+                    final int h=i;
+                    getServer().getThreadPool().dispatch(
+                            new Runnable()
+                            {
+                                public void run()
+                                {
+                                    ClassLoader orig = Thread.currentThread().getContextClassLoader();
+                                    try
+                                    {
+                                        Thread.currentThread().setContextClassLoader(loader);
+                                        _handlers[h].start();
+                                    }
+                                    catch(Throwable e)
+                                    {
+                                        mex.add(e);
+                                    }
+                                    finally
+                                    {
+                                        Thread.currentThread().setContextClassLoader(orig);
+                                        latch.countDown();
+                                    }
+                                }
+                            }
+                    );
+                }
+                latch.await();
+            }
+            else
+            {
+                for (int i=0;i<_handlers.length;i++)
+                {
+                    try{_handlers[i].start();}
+                    catch(Throwable e){mex.add(e);}
+                }
+            }
+        }
+        super.doStart();
+        mex.ifExceptionThrow();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.AbstractHandler#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        MultiException mex=new MultiException();
+        try { super.doStop(); } catch(Throwable e){mex.add(e);}
+        if (_handlers!=null)
+        {
+            for (int i=_handlers.length;i-->0;)
+                try{_handlers[i].stop();}catch(Throwable e){mex.add(e);}
+        }
+        mex.ifExceptionThrow();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setServer(Server server)
+    {
+        if (isStarted())
+            throw new IllegalStateException(STARTED);
+        
+        Server old_server=getServer();
+        
+        super.setServer(server);
+
+        Handler[] h=getHandlers();
+        for (int i=0;h!=null && i<h.length;i++)
+            h[i].setServer(server);
+        
+        if (server!=null && server!=old_server)
+            server.getContainer().update(this, null,_handlers, "handler");
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    /* Add a handler.
+     * This implementation adds the passed handler to the end of the existing collection of handlers. 
+     * @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
+     */
+    public void addHandler(Handler handler)
+    {
+        setHandlers((Handler[])LazyList.addToArray(getHandlers(), handler, Handler.class));
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void removeHandler(Handler handler)
+    {
+        Handler[] handlers = getHandlers();
+        
+        if (handlers!=null && handlers.length>0 )
+            setHandlers((Handler[])LazyList.removeFromArray(handlers, handler));
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected Object expandChildren(Object list, Class byClass)
+    {
+        Handler[] handlers = getHandlers();
+        for (int i=0;handlers!=null && i<handlers.length;i++)
+            list=expandHandler(handlers[i], list, byClass);
+        return list;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroy()
+    {
+        if (!isStopped())
+            throw new IllegalStateException("!STOPPED");
+        Handler[] children=getChildHandlers();
+        setHandlers(null);
+        for (Handler child: children)
+            child.destroy();
+        super.destroy();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/HandlerList.java b/src/java/org/eclipse/jetty/server/handler/HandlerList.java
new file mode 100644
index 0000000..6d7fc94
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/HandlerList.java
@@ -0,0 +1,58 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+
+/* ------------------------------------------------------------ */
+/** HandlerList.
+ * This extension of {@link HandlerCollection} will call
+ * each contained handler in turn until either an exception is thrown, the response 
+ * is committed or a positive response status is set.
+ */
+public class HandlerList extends HandlerCollection
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
+     */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
+        throws IOException, ServletException
+    {
+        Handler[] handlers = getHandlers();
+        
+        if (handlers!=null && isStarted())
+        {
+            for (int i=0;i<handlers.length;i++)
+            {
+                handlers[i].handle(target,baseRequest, request, response);
+                if ( baseRequest.isHandled())
+                    return;
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/HandlerWrapper.java b/src/java/org/eclipse/jetty/server/handler/HandlerWrapper.java
new file mode 100644
index 0000000..e28eeb3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/HandlerWrapper.java
@@ -0,0 +1,182 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/* ------------------------------------------------------------ */
+/** A <code>HandlerWrapper</code> acts as a {@link Handler} but delegates the {@link Handler#handle handle} method and
+ * {@link LifeCycle life cycle} events to a delegate. This is primarily used to implement the <i>Decorator</i> pattern.
+ *
+ */
+public class HandlerWrapper extends AbstractHandlerContainer
+{
+    protected Handler _handler;
+
+    /* ------------------------------------------------------------ */
+    /**
+     *
+     */
+    public HandlerWrapper()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the handlers.
+     */
+    public Handler getHandler()
+    {
+        return _handler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the handlers.
+     */
+    public Handler[] getHandlers()
+    {
+        if (_handler==null)
+            return new Handler[0];
+        return new Handler[] {_handler};
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param handler Set the {@link Handler} which should be wrapped.
+     */
+    public void setHandler(Handler handler)
+    {
+        if (isStarted())
+            throw new IllegalStateException(STARTED);
+
+        Handler old_handler = _handler;
+        _handler = handler;
+        if (handler!=null)
+            handler.setServer(getServer());
+        
+        if (getServer()!=null)
+            getServer().getContainer().update(this, old_handler, handler, "handler");
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_handler!=null)
+            _handler.start();
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        if (_handler!=null)
+            _handler.stop();
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (_handler!=null && isStarted())
+        {
+            _handler.handle(target,baseRequest, request, response);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setServer(Server server)
+    {
+        Server old_server=getServer();
+        if (server==old_server)
+            return;
+
+        if (isStarted())
+            throw new IllegalStateException(STARTED);
+
+        super.setServer(server);
+
+        Handler h=getHandler();
+        if (h!=null)
+            h.setServer(server);
+
+        if (server!=null && server!=old_server)
+            server.getContainer().update(this, null,_handler, "handler");
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected Object expandChildren(Object list, Class byClass)
+    {
+        return expandHandler(_handler,list,byClass);
+    }
+
+    /* ------------------------------------------------------------ */
+    public <H extends Handler> H getNestedHandlerByClass(Class<H> byclass)
+    {
+        HandlerWrapper h=this;
+        while (h!=null)
+        {
+            if (byclass.isInstance(h))
+                return (H)h;
+            Handler w = h.getHandler();
+            if (w instanceof HandlerWrapper)
+                h=(HandlerWrapper)w;
+            else break;
+        }
+        return null;
+
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroy()
+    {
+        if (!isStopped())
+            throw new IllegalStateException("!STOPPED");
+        Handler child=getHandler();
+        if (child!=null)
+        {
+            setHandler(null);
+            child.destroy();
+        }
+        super.destroy();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/HotSwapHandler.java b/src/java/org/eclipse/jetty/server/handler/HotSwapHandler.java
new file mode 100644
index 0000000..711744d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/HotSwapHandler.java
@@ -0,0 +1,176 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+
+/* ------------------------------------------------------------ */
+/**
+ * A <code>HandlerContainer</code> that allows a hot swap of a wrapped handler.
+ * 
+ */
+public class HotSwapHandler extends AbstractHandlerContainer
+{
+    private volatile Handler _handler;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     */
+    public HotSwapHandler()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the handlers.
+     */
+    public Handler getHandler()
+    {
+        return _handler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the handlers.
+     */
+    public Handler[] getHandlers()
+    {
+        return new Handler[]
+        { _handler };
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param handler
+     *            Set the {@link Handler} which should be wrapped.
+     */
+    public void setHandler(Handler handler)
+    {
+        if (handler == null)
+            throw new IllegalArgumentException("Parameter handler is null.");
+        try
+        {
+            Handler old_handler = _handler;
+            _handler = handler;
+            Server server = getServer();
+            handler.setServer(server);
+            addBean(handler);
+
+            if (server != null)
+                server.getContainer().update(this,old_handler,handler,"handler");
+
+            // if there is an old handler and it was started, stop it
+            if (old_handler != null)
+            {
+                removeBean(old_handler);
+            }
+
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.server.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (_handler != null && isStarted())
+        {
+            _handler.handle(target,baseRequest,request,response);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setServer(Server server)
+    {
+        Server old_server = getServer();
+        if (server == old_server)
+            return;
+
+        if (isRunning())
+            throw new IllegalStateException(RUNNING);
+
+        super.setServer(server);
+
+        Handler h = getHandler();
+        if (h != null)
+            h.setServer(server);
+
+        if (server != null && server != old_server)
+            server.getContainer().update(this,null,_handler,"handler");
+    }
+
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings(
+    { "rawtypes", "unchecked" })
+    @Override
+    protected Object expandChildren(Object list, Class byClass)
+    {
+        return expandHandler(_handler,list,byClass);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroy()
+    {
+        if (!isStopped())
+            throw new IllegalStateException("!STOPPED");
+        Handler child = getHandler();
+        if (child != null)
+        {
+            setHandler(null);
+            child.destroy();
+        }
+        super.destroy();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/IPAccessHandler.java b/src/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
new file mode 100644
index 0000000..46e5f1c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/IPAccessHandler.java
@@ -0,0 +1,382 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.IPAddressMap;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/**
+ * IP Access Handler
+ * <p>
+ * Controls access to the wrapped handler by the real remote IP. Control is provided
+ * by white/black lists that include both internet addresses and URIs. This handler
+ * uses the real internet address of the connection, not one reported in the forwarded
+ * for headers, as this cannot be as easily forged. 
+ * <p>
+ * Typically, the black/white lists will be used in one of three modes:
+ * <ul>
+ * <li>Blocking a few specific IPs/URLs by specifying several black list entries.
+ * <li>Allowing only some specific IPs/URLs by specifying several white lists entries.
+ * <li>Allowing a general range of IPs/URLs by specifying several general white list
+ * entries, that are then further refined by several specific black list exceptions
+ * </ul>
+ * <p>
+ * An empty white list is treated as match all. If there is at least one entry in
+ * the white list, then a request must match a white list entry. Black list entries
+ * are always applied, so that even if an entry matches the white list, a black list 
+ * entry will override it.
+ * <p>
+ * Internet addresses may be specified as absolute address or as a combination of 
+ * four octet wildcard specifications (a.b.c.d) that are defined as follows.
+ * </p>
+ * <pre>
+ * nnn - an absolute value (0-255)
+ * mmm-nnn - an inclusive range of absolute values, 
+ *           with following shorthand notations:
+ *           nnn- => nnn-255
+ *           -nnn => 0-nnn
+ *           -    => 0-255
+ * a,b,... - a list of wildcard specifications
+ * </pre>
+ * <p>
+ * Internet address specification is separated from the URI pattern using the "|" (pipe)
+ * character. URI patterns follow the servlet specification for simple * prefix and 
+ * suffix wild cards (e.g. /, /foo, /foo/bar, /foo/bar/*, *.baz).
+ * <p>
+ * Earlier versions of the handler used internet address prefix wildcard specification
+ * to define a range of the internet addresses (e.g. 127., 10.10., 172.16.1.).
+ * They also used the first "/" character of the URI pattern to separate it from the 
+ * internet address. Both of these features have been deprecated in the current version. 
+ * <p>
+ * Examples of the entry specifications are:
+ * <ul>
+ * <li>10.10.1.2 - all requests from IP 10.10.1.2
+ * <li>10.10.1.2|/foo/bar - all requests from IP 10.10.1.2 to URI /foo/bar
+ * <li>10.10.1.2|/foo/* - all requests from IP 10.10.1.2 to URIs starting with /foo/
+ * <li>10.10.1.2|*.html - all requests from IP 10.10.1.2 to URIs ending with .html
+ * <li>10.10.0-255.0-255 - all requests from IPs within 10.10.0.0/16 subnet
+ * <li>10.10.0-.-255|/foo/bar - all requests from IPs within 10.10.0.0/16 subnet to URI /foo/bar
+ * <li>10.10.0-3,1,3,7,15|/foo/* - all requests from IPs addresses with last octet equal
+ *                                  to 1,3,7,15 in subnet 10.10.0.0/22 to URIs starting with /foo/
+ * </ul>
+ * <p>
+ * Earlier versions of the handler used internet address prefix wildcard specification
+ * to define a range of the internet addresses (e.g. 127., 10.10., 172.16.1.).
+ * They also used the first "/" character of the URI pattern to separate it from the 
+ * internet address. Both of these features have been deprecated in the current version. 
+ */
+public class IPAccessHandler extends HandlerWrapper
+{
+    private static final Logger LOG = Log.getLogger(IPAccessHandler.class);
+
+    IPAddressMap<PathMap> _white = new IPAddressMap<PathMap>();
+    IPAddressMap<PathMap> _black = new IPAddressMap<PathMap>();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Creates new handler object
+     */
+    public IPAccessHandler()
+    {
+        super();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Creates new handler object and initializes white- and black-list
+     * 
+     * @param white array of whitelist entries
+     * @param black array of blacklist entries
+     */
+    public IPAccessHandler(String[] white, String []black)
+    {
+        super();
+        
+        if (white != null && white.length > 0)
+            setWhite(white);
+        if (black != null && black.length > 0)
+            setBlack(black);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Add a whitelist entry to an existing handler configuration
+     * 
+     * @param entry new whitelist entry
+     */
+    public void addWhite(String entry)
+    {
+        add(entry, _white);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Add a blacklist entry to an existing handler configuration
+     * 
+     * @param entry new blacklist entry
+     */
+    public void addBlack(String entry)
+    {
+        add(entry, _black);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Re-initialize the whitelist of existing handler object
+     * 
+     * @param entries array of whitelist entries
+     */
+    public void setWhite(String[] entries)
+    {
+        set(entries, _white);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Re-initialize the blacklist of existing handler object
+     * 
+     * @param entries array of blacklist entries
+     */
+    public void setBlack(String[] entries)
+    {
+        set(entries, _black);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Checks the incoming request against the whitelist and blacklist
+     * 
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        // Get the real remote IP (not the one set by the forwarded headers (which may be forged))
+        AbstractHttpConnection connection = baseRequest.getConnection();
+        if (connection!=null)
+        {
+            EndPoint endp=connection.getEndPoint();
+            if (endp!=null)
+            {
+                String addr = endp.getRemoteAddr();
+                if (addr!=null && !isAddrUriAllowed(addr,baseRequest.getPathInfo()))
+                {
+                    response.sendError(HttpStatus.FORBIDDEN_403);
+                    baseRequest.setHandled(true);
+                    return;
+                }
+            }
+        }
+        
+        getHandler().handle(target,baseRequest, request, response);
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Helper method to parse the new entry and add it to 
+     * the specified address pattern map.
+     * 
+     * @param entry new entry
+     * @param patternMap target address pattern map
+     */
+    protected void add(String entry, IPAddressMap<PathMap> patternMap)
+    {
+        if (entry != null && entry.length() > 0)
+        {
+            boolean deprecated = false;
+            int idx;
+            if (entry.indexOf('|') > 0 )
+            {
+                idx = entry.indexOf('|');
+            }
+            else
+            {
+                idx = entry.indexOf('/');
+                deprecated = (idx >= 0);
+            }
+            
+            String addr = idx > 0 ? entry.substring(0,idx) : entry;        
+            String path = idx > 0 ? entry.substring(idx) : "/*";
+            
+            if (addr.endsWith("."))
+                deprecated = true;
+            if (path!=null && (path.startsWith("|") || path.startsWith("/*.")))
+                path=path.substring(1);
+           
+            PathMap pathMap = patternMap.get(addr);
+            if (pathMap == null)
+            {
+                pathMap = new PathMap(true);
+                patternMap.put(addr,pathMap);
+            }
+            if (path != null && !"".equals(path))
+                pathMap.put(path,path);
+            
+            if (deprecated)
+                LOG.debug(toString() +" - deprecated specification syntax: "+entry);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Helper method to process a list of new entries and replace 
+     * the content of the specified address pattern map
+     * 
+     * @param entries new entries
+     * @param patternMap target address pattern map
+     */
+    protected void set(String[] entries,  IPAddressMap<PathMap> patternMap)
+    {
+        patternMap.clear();
+        
+        if (entries != null && entries.length > 0)
+        {
+            for (String addrPath:entries)
+            {
+                add(addrPath, patternMap);
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Check if specified request is allowed by current IPAccess rules.
+     * 
+     * @param addr internet address
+     * @param path context path
+     * @return true if request is allowed
+     *
+     */
+    protected boolean isAddrUriAllowed(String addr, String path)
+    {
+        if (_white.size()>0)
+        {
+            boolean match = false;
+            
+            Object whiteObj = _white.getLazyMatches(addr);
+            if (whiteObj != null) 
+            {
+                List whiteList = (whiteObj instanceof List) ? (List)whiteObj : Collections.singletonList(whiteObj);
+
+                for (Object entry: whiteList)
+                {
+                    PathMap pathMap = ((Map.Entry<String,PathMap>)entry).getValue();
+                    if (match = (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null)))
+                        break;
+                }
+            }
+            
+            if (!match)
+                return false;
+        }
+
+        if (_black.size() > 0)
+        {
+            Object blackObj = _black.getLazyMatches(addr);
+            if (blackObj != null) 
+            {
+                List blackList = (blackObj instanceof List) ? (List)blackObj : Collections.singletonList(blackObj);
+    
+                for (Object entry: blackList)
+                {
+                    PathMap pathMap = ((Map.Entry<String,PathMap>)entry).getValue();
+                    if (pathMap!=null && (pathMap.size()==0 || pathMap.match(path)!=null))
+                        return false;
+                }
+            }
+        }
+        
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Dump the white- and black-list configurations when started
+     * 
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
+     */
+    @Override
+    protected void doStart()
+        throws Exception
+    {
+        super.doStart();
+        
+        if (LOG.isDebugEnabled())
+        {
+            System.err.println(dump());
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Dump the handler configuration
+     */
+    public String dump()
+    {
+        StringBuilder buf = new StringBuilder();
+        
+        buf.append(toString());
+        buf.append(" WHITELIST:\n");
+        dump(buf, _white);
+        buf.append(toString());
+        buf.append(" BLACKLIST:\n");
+        dump(buf, _black);
+        
+        return buf.toString();
+    }    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Dump a pattern map into a StringBuilder buffer
+     * 
+     * @param buf buffer
+     * @param patternMap pattern map to dump
+     */
+    protected void dump(StringBuilder buf, IPAddressMap<PathMap> patternMap)
+    {
+        for (String addr: patternMap.keySet())
+        {
+            for (Object path: ((PathMap)patternMap.get(addr)).values())
+            {
+                buf.append("# ");
+                buf.append(addr);
+                buf.append("|");
+                buf.append(path);
+                buf.append("\n");
+            }       
+        }
+    }
+ }
diff --git a/src/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java b/src/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
new file mode 100644
index 0000000..f06a4e8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
@@ -0,0 +1,138 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.AsyncEvent;
+import javax.servlet.AsyncListener;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+
+/**
+ * Handler to adjust the idle timeout of requests while dispatched.
+ * 
+ * <p>Can be applied in jetty.xml with
+ * <pre>
+ *   &lt;Get id='handler' name='Handler'/>
+ *   &lt;Set name='Handler'>
+ *     &lt;New id='idleTimeoutHandler' class='org.eclipse.jetty.server.handler.IdleTimeoutHandler'>
+ *       &lt;Set name='Handler'>&lt;Ref id='handler'/>&lt;/Set>
+ *       &lt;Set name='IdleTimeoutMs'>5000&lt;/Set>
+ *     &lt;/New>
+ *   &lt;/Set>
+ * </pre>
+ */
+public class IdleTimeoutHandler extends HandlerWrapper
+{
+    private int _idleTimeoutMs = 1000;
+    private boolean _applyToAsync = false;
+    
+    
+    public boolean isApplyToAsync()
+    {
+        return _applyToAsync;
+    }
+
+    /**
+     * Should the adjusted idle time be maintained for asynchronous requests
+     * @param applyToAsync true if alternate idle timeout is applied to asynchronous requests
+     */
+    public void setApplyToAsync(boolean applyToAsync)
+    {
+        _applyToAsync = applyToAsync;
+    }
+
+    public long getIdleTimeoutMs()
+    {
+        return _idleTimeoutMs;
+    }
+
+    /**
+     * @param idleTimeoutMs The idle timeout in MS to apply while dispatched or async
+     */
+    public void setIdleTimeoutMs(int _idleTimeoutMs)
+    {
+        this._idleTimeoutMs = _idleTimeoutMs;
+    }
+    
+   
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
+        final EndPoint endp = connection==null?null:connection.getEndPoint();
+        
+        final int idle_timeout;
+        if (endp==null)
+            idle_timeout=-1;
+        else
+        {
+            idle_timeout=endp.getMaxIdleTime();
+            endp.setMaxIdleTime(_idleTimeoutMs);
+        }
+        
+        try
+        {
+            super.handle(target,baseRequest,request,response);
+        }
+        finally
+        {
+            if (endp!=null)
+            {
+                if (_applyToAsync && request.isAsyncStarted())
+                {
+                    request.getAsyncContext().addListener(new AsyncListener()
+                    {
+                        @Override
+                        public void onTimeout(AsyncEvent event) throws IOException
+                        {                            
+                        }
+                        
+                        @Override
+                        public void onStartAsync(AsyncEvent event) throws IOException
+                        {
+                        }
+                        
+                        @Override
+                        public void onError(AsyncEvent event) throws IOException
+                        {
+                            endp.setMaxIdleTime(idle_timeout);
+                        }
+                        
+                        @Override
+                        public void onComplete(AsyncEvent event) throws IOException
+                        {
+                            endp.setMaxIdleTime(idle_timeout);
+                        }
+                    });
+                }
+                else 
+                {
+                    endp.setMaxIdleTime(idle_timeout);
+                }
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/MovedContextHandler.java b/src/java/org/eclipse/jetty/server/handler/MovedContextHandler.java
new file mode 100644
index 0000000..410454c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/MovedContextHandler.java
@@ -0,0 +1,154 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.URIUtil;
+
+/* ------------------------------------------------------------ */
+/** Moved ContextHandler.
+ * This context can be used to replace a context that has changed
+ * location.  Requests are redirected (either to a fixed URL or to a
+ * new context base). 
+ */
+public class MovedContextHandler extends ContextHandler
+{
+    final Redirector _redirector;
+    String _newContextURL;
+    boolean _discardPathInfo;
+    boolean _discardQuery;
+    boolean _permanent;
+    String _expires;
+
+    public MovedContextHandler()
+    {
+        _redirector=new Redirector();
+        setHandler(_redirector);
+        setAllowNullPathInfo(true);
+    }
+    
+    public MovedContextHandler(HandlerContainer parent, String contextPath, String newContextURL)
+    {
+        super(parent,contextPath);
+        _newContextURL=newContextURL;
+        _redirector=new Redirector();
+        setHandler(_redirector);
+    }
+
+    public boolean isDiscardPathInfo()
+    {
+        return _discardPathInfo;
+    }
+
+    public void setDiscardPathInfo(boolean discardPathInfo)
+    {
+        _discardPathInfo = discardPathInfo;
+    }
+
+    public String getNewContextURL()
+    {
+        return _newContextURL;
+    }
+
+    public void setNewContextURL(String newContextURL)
+    {
+        _newContextURL = newContextURL;
+    }
+
+    public boolean isPermanent()
+    {
+        return _permanent;
+    }
+
+    public void setPermanent(boolean permanent)
+    {
+        _permanent = permanent;
+    }
+
+    public boolean isDiscardQuery()
+    {
+        return _discardQuery;
+    }
+
+    public void setDiscardQuery(boolean discardQuery)
+    {
+        _discardQuery = discardQuery;
+    }
+    
+    private class Redirector extends AbstractHandler
+    {
+        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+        {
+            if (_newContextURL==null)
+                return;
+
+            String path=_newContextURL;
+            if (!_discardPathInfo && request.getPathInfo()!=null)
+                path=URIUtil.addPaths(path, request.getPathInfo());
+            
+            StringBuilder location = URIUtil.hasScheme(path)?new StringBuilder():baseRequest.getRootURL();
+
+            location.append(path);
+            if (!_discardQuery && request.getQueryString()!=null)
+            {
+                location.append('?');
+                String q=request.getQueryString();
+                q=q.replaceAll("\r\n?&=","!");
+                location.append(q);
+            }
+            
+            response.setHeader(HttpHeaders.LOCATION,location.toString());
+
+            if (_expires!=null)
+                response.setHeader(HttpHeaders.EXPIRES,_expires);
+            
+            response.setStatus(_permanent?HttpServletResponse.SC_MOVED_PERMANENTLY:HttpServletResponse.SC_FOUND);
+            response.setContentLength(0);
+            baseRequest.setHandled(true);
+        }
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the expires header value or null if no expires header
+     */
+    public String getExpires()
+    {
+        return _expires;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param expires the expires header value or null if no expires header
+     */
+    public void setExpires(String expires)
+    {
+        _expires = expires;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ProxyHandler.java b/src/java/org/eclipse/jetty/server/handler/ProxyHandler.java
new file mode 100644
index 0000000..a5f82ca
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ProxyHandler.java
@@ -0,0 +1,51 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import org.eclipse.jetty.server.Handler;
+
+
+/* ------------------------------------------------------------ */
+/** ProxyHandler.
+ * <p>This class has been renamed to ConnectHandler, as it only implements
+ * the CONNECT method (and a ProxyServlet must be used for full proxy handling).
+ * @deprecated Use {@link ConnectHandler}
+ */
+public class ProxyHandler extends ConnectHandler
+{
+    public ProxyHandler()
+    {
+        super();
+    }
+
+    public ProxyHandler(Handler handler, String[] white, String[] black)
+    {
+        super(handler,white,black);
+    }
+
+    public ProxyHandler(Handler handler)
+    {
+        super(handler);
+    }
+
+    public ProxyHandler(String[] white, String[] black)
+    {
+        super(white,black);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/src/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
new file mode 100644
index 0000000..e80c5f3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/RequestLogHandler.java
@@ -0,0 +1,192 @@
+//
+//  ========================================================================
+//  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.handler; 
+
+import java.io.IOException;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.server.AsyncContinuation;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/** 
+ * RequestLogHandler.
+ * This handler can be used to wrap an individual context for context logging.
+ * 
+ * @org.apache.xbean.XBean
+ */
+public class RequestLogHandler extends HandlerWrapper
+{
+    private static final Logger LOG = Log.getLogger(RequestLogHandler.class);
+
+    private RequestLog _requestLog;
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    @Override
+    public void handle(String target, final Request baseRequest, HttpServletRequest request, final HttpServletResponse response)
+            throws IOException, ServletException
+    {
+        AsyncContinuation continuation = baseRequest.getAsyncContinuation();
+        if (!continuation.isInitial())
+        {
+            baseRequest.setDispatchTime(System.currentTimeMillis());
+        }
+        
+        try
+        {
+            super.handle(target, baseRequest, request, response);
+        }
+        finally
+        {
+            if (_requestLog != null && baseRequest.getDispatcherType().equals(DispatcherType.REQUEST))
+            {
+                if (continuation.isAsync())
+                {
+                    if (continuation.isInitial())
+                        continuation.addContinuationListener(new ContinuationListener()
+                        {
+
+                            public void onTimeout(Continuation continuation)
+                            {
+
+                            }
+
+                            public void onComplete(Continuation continuation)
+                            {
+                                _requestLog.log(baseRequest, (Response)response);
+                            }
+                        });
+                }
+                else
+                    _requestLog.log(baseRequest, (Response)response);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setRequestLog(RequestLog requestLog)
+    {
+        //are we changing the request log impl?
+        try
+        {
+            if (_requestLog != null)
+                _requestLog.stop();
+        }
+        catch (Exception e)
+        {
+            LOG.warn (e);
+        }
+        
+        if (getServer()!=null)
+            getServer().getContainer().update(this, _requestLog, requestLog, "logimpl",true);
+        
+        _requestLog = requestLog;
+        
+        //if we're already started, then start our request log
+        try
+        {
+            if (isStarted() && (_requestLog != null))
+                _requestLog.start();
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException (e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#setServer(org.eclipse.jetty.server.server.Server)
+     */
+    @Override
+    public void setServer(Server server)
+    {
+        if (_requestLog!=null)
+        {
+            if (getServer()!=null && getServer()!=server)
+                getServer().getContainer().update(this, _requestLog, null, "logimpl",true);
+            super.setServer(server);
+            if (server!=null && server!=getServer())
+                server.getContainer().update(this, null,_requestLog, "logimpl",true);
+        }
+        else
+            super.setServer(server);
+    }
+
+    /* ------------------------------------------------------------ */
+    public RequestLog getRequestLog() 
+    {
+        return _requestLog;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_requestLog==null)
+        {
+            LOG.warn("!RequestLog");
+            _requestLog=new NullRequestLog();
+        }
+        super.doStart();
+        _requestLog.start();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        _requestLog.stop();
+        if (_requestLog instanceof NullRequestLog)
+            _requestLog=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class NullRequestLog extends AbstractLifeCycle implements RequestLog
+    {
+        public void log(Request request, Response response)
+        {            
+        }
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/src/java/org/eclipse/jetty/server/handler/ResourceHandler.java
new file mode 100644
index 0000000..11a3f2a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ResourceHandler.java
@@ -0,0 +1,545 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.util.resource.Resource;
+
+
+/* ------------------------------------------------------------ */
+/** Resource Handler.
+ *
+ * This handle will serve static content and handle If-Modified-Since headers.
+ * No caching is done.
+ * Requests for resources that do not exist are let pass (Eg no 404's).
+ *
+ *
+ * @org.apache.xbean.XBean
+ */
+public class ResourceHandler extends HandlerWrapper
+{
+    private static final Logger LOG = Log.getLogger(ResourceHandler.class);
+
+    ContextHandler _context;
+    Resource _baseResource;
+    Resource _defaultStylesheet;
+    Resource _stylesheet;
+    String[] _welcomeFiles={"index.html"};
+    MimeTypes _mimeTypes = new MimeTypes();
+    ByteArrayBuffer _cacheControl;
+    boolean _aliases;
+    boolean _directory;
+    boolean _etags;
+
+    /* ------------------------------------------------------------ */
+    public ResourceHandler()
+    {
+    	
+    }
+
+    /* ------------------------------------------------------------ */
+    public MimeTypes getMimeTypes()
+    {
+        return _mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setMimeTypes(MimeTypes mimeTypes)
+    {
+        _mimeTypes = mimeTypes;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if resource aliases are allowed.
+     */
+    public boolean isAliases()
+    {
+        return _aliases;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if resource aliases (eg symlink, 8.3 names, case insensitivity) are allowed.
+     * Allowing aliases can significantly increase security vulnerabilities.
+     * If this handler is deployed inside a ContextHandler, then the
+     * {@link ContextHandler#isAliases()} takes precedent.
+     * @param aliases True if aliases are supported.
+     */
+    public void setAliases(boolean aliases)
+    {
+        _aliases = aliases;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the directory option.
+     * @return true if directories are listed.
+     */
+    public boolean isDirectoriesListed()
+    {
+        return _directory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the directory.
+     * @param directory true if directories are listed.
+     */
+    public void setDirectoriesListed(boolean directory)
+    {
+        _directory = directory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if ETag processing is done
+     */
+    public boolean isEtags()
+    {
+        return _etags;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param etags True if ETag processing is done
+     */
+    public void setEtags(boolean etags)
+    {
+        _etags = etags;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void doStart()
+    throws Exception
+    {
+        Context scontext = ContextHandler.getCurrentContext();
+        _context = (scontext==null?null:scontext.getContextHandler());
+
+        if (_context!=null)
+            _aliases=_context.isAliases();
+
+        if (!_aliases && !FileResource.getCheckAliases())
+            throw new IllegalStateException("Alias checking disabled");
+
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the resourceBase.
+     */
+    public Resource getBaseResource()
+    {
+        if (_baseResource==null)
+            return null;
+        return _baseResource;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the base resource as a string.
+     */
+    public String getResourceBase()
+    {
+        if (_baseResource==null)
+            return null;
+        return _baseResource.toString();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param base The resourceBase to set.
+     */
+    public void setBaseResource(Resource base)
+    {
+        _baseResource=base;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param resourceBase The base resource as a string.
+     */
+    public void setResourceBase(String resourceBase)
+    {
+        try
+        {
+            setBaseResource(Resource.newResource(resourceBase));
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e.toString());
+            LOG.debug(e);
+            throw new IllegalArgumentException(resourceBase);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the stylesheet as a Resource.
+     */
+    public Resource getStylesheet()
+    {
+    	if(_stylesheet != null)
+    	{
+    	    return _stylesheet;
+    	}
+    	else
+    	{
+    	    if(_defaultStylesheet == null)
+    	    {
+    	        try
+    	        {
+    	            _defaultStylesheet =  Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
+    	        }
+    	        catch(IOException e)
+    	        {
+    	            LOG.warn(e.toString());
+    	            LOG.debug(e);
+    	        }	 
+    	    }
+    	    return _defaultStylesheet;
+    	}
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param stylesheet The location of the stylesheet to be used as a String.
+     */
+    public void setStylesheet(String stylesheet)
+    {
+        try
+        {
+            _stylesheet = Resource.newResource(stylesheet);
+            if(!_stylesheet.exists())
+            {
+                LOG.warn("unable to find custom stylesheet: " + stylesheet);
+                _stylesheet = null;
+            }
+        }
+    	catch(Exception e)
+    	{
+    		LOG.warn(e.toString());
+            LOG.debug(e);
+            throw new IllegalArgumentException(stylesheet.toString());
+    	}
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the cacheControl header to set on all static content.
+     */
+    public String getCacheControl()
+    {
+        return _cacheControl.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cacheControl the cacheControl header to set on all static content.
+     */
+    public void setCacheControl(String cacheControl)
+    {
+        _cacheControl=cacheControl==null?null:new ByteArrayBuffer(cacheControl);
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     */
+    public Resource getResource(String path) throws MalformedURLException
+    {
+        if (path==null || !path.startsWith("/"))
+            throw new MalformedURLException(path);
+
+        Resource base = _baseResource;
+        if (base==null)
+        {
+            if (_context==null)
+                return null;
+            base=_context.getBaseResource();
+            if (base==null)
+                return null;
+        }
+
+        try
+        {
+            path=URIUtil.canonicalPath(path);
+            return base.addPath(path);
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+        }
+
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected Resource getResource(HttpServletRequest request) throws MalformedURLException
+    {
+        String servletPath;
+        String pathInfo;
+        Boolean included = request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI) != null;
+        if (included != null && included.booleanValue())
+        {
+            servletPath = (String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
+            pathInfo = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
+ 
+            if (servletPath == null && pathInfo == null)
+            {
+                servletPath = request.getServletPath();
+                pathInfo = request.getPathInfo();
+            }
+        }
+        else
+        {
+            servletPath = request.getServletPath();
+            pathInfo = request.getPathInfo();
+        }
+        
+        String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
+        return getResource(pathInContext);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public String[] getWelcomeFiles()
+    {
+        return _welcomeFiles;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setWelcomeFiles(String[] welcomeFiles)
+    {
+        _welcomeFiles=welcomeFiles;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected Resource getWelcome(Resource directory) throws MalformedURLException, IOException
+    {
+        for (int i=0;i<_welcomeFiles.length;i++)
+        {
+            Resource welcome=directory.addPath(_welcomeFiles[i]);
+            if (welcome.exists() && !welcome.isDirectory())
+                return welcome;
+        }
+
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
+     */
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (baseRequest.isHandled())
+            return;
+
+        boolean skipContentBody = false;
+
+        if(!HttpMethods.GET.equals(request.getMethod()))
+        {
+            if(!HttpMethods.HEAD.equals(request.getMethod()))
+            {
+                //try another handler
+                super.handle(target, baseRequest, request, response);
+                return;
+            }
+            skipContentBody = true;
+        }
+        
+        Resource resource = getResource(request);
+        
+        if (resource==null || !resource.exists())
+        {
+            if (target.endsWith("/jetty-dir.css"))
+            {	                
+                resource = getStylesheet();
+                if (resource==null)
+                    return;
+                response.setContentType("text/css");
+            }
+            else 
+            {
+                //no resource - try other handlers
+                super.handle(target, baseRequest, request, response);
+                return;
+            }
+        }
+            
+        if (!_aliases && resource.getAlias()!=null)
+        {
+            LOG.info(resource+" aliased to "+resource.getAlias());
+            return;
+        }
+
+        // We are going to serve something
+        baseRequest.setHandled(true);
+
+        if (resource.isDirectory())
+        {
+            if (!request.getPathInfo().endsWith(URIUtil.SLASH))
+            {
+                response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH)));
+                return;
+            }
+
+            Resource welcome=getWelcome(resource);
+            if (welcome!=null && welcome.exists())
+                resource=welcome;
+            else
+            {
+                doDirectory(request,response,resource);
+                baseRequest.setHandled(true);
+                return;
+            }
+        }
+
+        // set some headers
+        long last_modified=resource.lastModified();
+        String etag=null;
+        if (_etags)
+        {
+            // simple handling of only a single etag
+            String ifnm = request.getHeader(HttpHeaders.IF_NONE_MATCH);
+            etag=resource.getWeakETag();
+            if (ifnm!=null && resource!=null && ifnm.equals(etag))
+            {
+                response.setStatus(HttpStatus.NOT_MODIFIED_304);
+                baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag);
+                return;
+            }
+        }
+        
+        
+        if (last_modified>0)
+        {
+            long if_modified=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
+            if (if_modified>0 && last_modified/1000<=if_modified/1000)
+            {
+                response.setStatus(HttpStatus.NOT_MODIFIED_304);
+                return;
+            }
+        }
+
+        Buffer mime=_mimeTypes.getMimeByExtension(resource.toString());
+        if (mime==null)
+            mime=_mimeTypes.getMimeByExtension(request.getPathInfo());
+
+        // set the headers
+        doResponseHeaders(response,resource,mime!=null?mime.toString():null);
+        response.setDateHeader(HttpHeaders.LAST_MODIFIED,last_modified);
+        if (_etags)
+            baseRequest.getResponse().getHttpFields().put(HttpHeaders.ETAG_BUFFER,etag);
+        
+        if(skipContentBody)
+            return;
+        // Send the content
+        OutputStream out =null;
+        try {out = response.getOutputStream();}
+        catch(IllegalStateException e) {out = new WriterOutputStream(response.getWriter());}
+
+        // See if a short direct method can be used?
+        if (out instanceof AbstractHttpConnection.Output)
+        {
+            // TODO file mapped buffers
+            ((AbstractHttpConnection.Output)out).sendContent(resource.getInputStream());
+        }
+        else
+        {
+            // Write content normally
+            resource.writeTo(out,0,resource.length());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void doDirectory(HttpServletRequest request,HttpServletResponse response, Resource resource)
+        throws IOException
+    {
+        if (_directory)
+        {
+            String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0);
+            response.setContentType("text/html; charset=UTF-8");
+            response.getWriter().println(listing);
+        }
+        else
+            response.sendError(HttpStatus.FORBIDDEN_403);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the response headers.
+     * This method is called to set the response headers such as content type and content length.
+     * May be extended to add additional headers.
+     * @param response
+     * @param resource
+     * @param mimeType
+     */
+    protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType)
+    {
+        if (mimeType!=null)
+            response.setContentType(mimeType);
+
+        long length=resource.length();
+
+        if (response instanceof Response)
+        {
+            HttpFields fields = ((Response)response).getHttpFields();
+
+            if (length>0)
+                fields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER,length);
+
+            if (_cacheControl!=null)
+                fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
+        }
+        else
+        {
+            if (length>0)
+                response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(length));
+
+            if (_cacheControl!=null)
+                response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
+        }
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ScopedHandler.java b/src/java/org/eclipse/jetty/server/handler/ScopedHandler.java
new file mode 100644
index 0000000..0acfff2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ScopedHandler.java
@@ -0,0 +1,193 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+
+
+/* ------------------------------------------------------------ */
+/** ScopedHandler.
+ * 
+ * A ScopedHandler is a HandlerWrapper where the wrapped handlers
+ * each define a scope.   When {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)}
+ * is called on the first ScopedHandler in a chain of HandlerWrappers,
+ * the {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)} method is 
+ * called on all contained ScopedHandlers, before the 
+ * {@link #doHandle(String, Request, HttpServletRequest, HttpServletResponse)} method 
+ * is called on all contained handlers.
+ * 
+ * <p>For example if Scoped handlers A, B & C were chained together, then 
+ * the calling order would be:<pre>
+ * A.handle(...)
+ *   A.doScope(...)
+ *     B.doScope(...)
+ *       C.doScope(...)
+ *         A.doHandle(...)
+ *           B.doHandle(...)
+ *              C.doHandle(...)   
+ * <pre>
+ * 
+ * <p>If non scoped handler X was in the chained A, B, X & C, then 
+ * the calling order would be:<pre>
+ * A.handle(...)
+ *   A.doScope(...)
+ *     B.doScope(...)
+ *       C.doScope(...)
+ *         A.doHandle(...)
+ *           B.doHandle(...)
+ *             X.handle(...)
+ *               C.handle(...)
+ *                 C.doHandle(...)   
+ * <pre>
+ * 
+ * <p>A typical usage pattern is:<pre>
+ *     private static class MyHandler extends ScopedHandler
+ *     {
+ *         public void doScope(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ *         {
+ *             try
+ *             {
+ *                 setUpMyScope();
+ *                 super.doScope(target,request,response);
+ *             }
+ *             finally
+ *             {
+ *                 tearDownMyScope();
+ *             }
+ *         }
+ *         
+ *         public void doHandle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ *         {
+ *             try
+ *             {
+ *                 doMyHandling();
+ *                 super.doHandle(target,request,response);
+ *             }
+ *             finally
+ *             {
+ *                 cleanupMyHandling();
+ *             }
+ *         }
+ *     }
+ * </pre>
+ */
+public abstract class ScopedHandler extends HandlerWrapper
+{
+    private static final ThreadLocal<ScopedHandler> __outerScope= new ThreadLocal<ScopedHandler>();
+    protected ScopedHandler _outerScope;
+    protected ScopedHandler _nextScope;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        try
+        {
+            _outerScope=__outerScope.get();
+            if (_outerScope==null)
+                __outerScope.set(this);
+            
+            super.doStart();
+            
+            _nextScope= (ScopedHandler)getChildHandlerByClass(ScopedHandler.class);
+            
+        }
+        finally
+        {
+            if (_outerScope==null)
+                __outerScope.set(null);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* 
+     */
+    @Override
+    public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (_outerScope==null)  
+            doScope(target,baseRequest,request, response);
+        else 
+            doHandle(target,baseRequest,request, response);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * Scope the handler
+     */
+    public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
+        throws IOException, ServletException;
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * Scope the handler
+     */
+    public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
+        throws IOException, ServletException
+    {
+        // this method has been manually inlined in several locations, but
+        // is called protected by an if(never()), so your IDE can find those
+        // locations if this code is changed.
+        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);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * Do the handler work within the scope.
+     */
+    public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
+        throws IOException, ServletException;
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * Do the handler work within the scope.
+     */
+    public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        // this method has been manually inlined in several locations, but
+        // is called protected by an if(never()), so your IDE can find those
+        // locations if this code is changed.
+        if (_nextScope!=null && _nextScope==_handler)
+            _nextScope.doHandle(target,baseRequest,request, response);
+        else if (_handler!=null)
+            _handler.handle(target,baseRequest, request, response);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected boolean never()
+    {
+        return false;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/ShutdownHandler.java b/src/java/org/eclipse/jetty/server/handler/ShutdownHandler.java
new file mode 100644
index 0000000..a8669e4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/ShutdownHandler.java
@@ -0,0 +1,170 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * A handler that shuts the server down on a valid request. Used to do "soft" restarts from Java. If _exitJvm ist set to true a hard System.exit() call is being
+ * made.
+ *
+ * This handler is a contribution from Johannes Brodwall: https://bugs.eclipse.org/bugs/show_bug.cgi?id=357687
+ *
+ * Usage:
+ *
+ * <pre>
+    Server server = new Server(8080);
+    HandlerList handlers = new HandlerList();
+    handlers.setHandlers(new Handler[]
+    { someOtherHandler, new ShutdownHandler(server,&quot;secret password&quot;) });
+    server.setHandler(handlers);
+    server.start();
+   </pre>
+ * 
+   <pre>
+   public static void attemptShutdown(int port, String shutdownCookie) {
+        try {
+            URL url = new URL("http://localhost:" + port + "/shutdown?token=" + shutdownCookie);
+            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.getResponseCode();
+            logger.info("Shutting down " + url + ": " + connection.getResponseMessage());
+        } catch (SocketException e) {
+            logger.debug("Not running");
+            // Okay - the server is not running
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+  </pre>
+ */
+public class ShutdownHandler extends AbstractHandler
+{
+    private static final Logger LOG = Log.getLogger(ShutdownHandler.class);
+
+    private final String _shutdownToken;
+
+    private final Server _server;
+
+    private boolean _exitJvm = false;
+  
+    
+
+    /**
+     * Creates a listener that lets the server be shut down remotely (but only from localhost).
+     *
+     * @param server
+     *            the Jetty instance that should be shut down
+     * @param shutdownToken
+     *            a secret password to avoid unauthorized shutdown attempts
+     */
+    public ShutdownHandler(Server server, String shutdownToken)
+    {
+        this._server = server;
+        this._shutdownToken = shutdownToken;
+    }
+
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (!target.equals("/shutdown"))
+        {
+            return;
+        }
+
+        if (!request.getMethod().equals("POST"))
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+        if (!hasCorrectSecurityToken(request))
+        {
+            LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request));
+            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            return;
+        }
+        if (!requestFromLocalhost(request))
+        {
+            LOG.warn("Unauthorized shutdown attempt from " + getRemoteAddr(request));
+            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            return;
+        }
+
+        LOG.info("Shutting down by request from " + getRemoteAddr(request));
+        
+        new Thread()
+        {
+            public void run ()
+            {
+                try
+                {
+                    shutdownServer();
+                }
+                catch (InterruptedException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (Exception e)
+                {
+                    throw new RuntimeException("Shutting down server",e);
+                }
+            }
+        }.start();
+    }
+
+    private boolean requestFromLocalhost(HttpServletRequest request)
+    {
+        return "127.0.0.1".equals(getRemoteAddr(request));
+    }
+
+    protected String getRemoteAddr(HttpServletRequest request)
+    {
+        return request.getRemoteAddr();
+    }
+
+    private boolean hasCorrectSecurityToken(HttpServletRequest request)
+    {
+        return _shutdownToken.equals(request.getParameter("token"));
+    }
+
+    private void shutdownServer() throws Exception
+    {
+        _server.stop();
+        
+        if (_exitJvm)
+        {
+            System.exit(0);
+        }
+    }
+
+    public void setExitJvm(boolean exitJvm)
+    {
+        this._exitJvm = exitJvm;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/StatisticsHandler.java b/src/java/org/eclipse/jetty/server/handler/StatisticsHandler.java
new file mode 100644
index 0000000..6949dbd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/StatisticsHandler.java
@@ -0,0 +1,474 @@
+//
+//  ========================================================================
+//  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.handler;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.server.AsyncContinuation;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.statistic.CounterStatistic;
+import org.eclipse.jetty.util.statistic.SampleStatistic;
+
+public class StatisticsHandler extends HandlerWrapper
+{
+    private final AtomicLong _statsStartedAt = new AtomicLong();
+    
+    private final CounterStatistic _requestStats = new CounterStatistic();
+    private final SampleStatistic _requestTimeStats = new SampleStatistic();
+    private final CounterStatistic _dispatchedStats = new CounterStatistic();
+    private final SampleStatistic _dispatchedTimeStats = new SampleStatistic();
+    private final CounterStatistic _suspendStats = new CounterStatistic();
+
+    private final AtomicInteger _resumes = new AtomicInteger();
+    private final AtomicInteger _expires = new AtomicInteger();
+    
+    private final AtomicInteger _responses1xx = new AtomicInteger();
+    private final AtomicInteger _responses2xx = new AtomicInteger();
+    private final AtomicInteger _responses3xx = new AtomicInteger();
+    private final AtomicInteger _responses4xx = new AtomicInteger();
+    private final AtomicInteger _responses5xx = new AtomicInteger();
+    private final AtomicLong _responsesTotalBytes = new AtomicLong();
+
+    private final ContinuationListener _onCompletion = new ContinuationListener()
+    {
+        public void onComplete(Continuation continuation)
+        {
+            final Request request = ((AsyncContinuation)continuation).getBaseRequest();
+            final long elapsed = System.currentTimeMillis()-request.getTimeStamp();
+            
+            _requestStats.decrement();
+            _requestTimeStats.set(elapsed);
+            
+            updateResponse(request);
+            
+            if (!continuation.isResumed())
+                _suspendStats.decrement();
+        }
+
+        public void onTimeout(Continuation continuation)
+        {
+            _expires.incrementAndGet();
+        }
+    };
+    
+    /**
+     * Resets the current request statistics.
+     */
+    public void statsReset()
+    {
+        _statsStartedAt.set(System.currentTimeMillis());
+        
+        _requestStats.reset();
+        _requestTimeStats.reset();
+        _dispatchedStats.reset();
+        _dispatchedTimeStats.reset();
+        _suspendStats.reset();
+
+        _resumes.set(0);
+        _expires.set(0);
+        _responses1xx.set(0);
+        _responses2xx.set(0);
+        _responses3xx.set(0);
+        _responses4xx.set(0);
+        _responses5xx.set(0);
+        _responsesTotalBytes.set(0L);
+    }
+
+    @Override
+    public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
+    {
+        _dispatchedStats.increment();
+
+        final long start;
+        AsyncContinuation continuation = request.getAsyncContinuation();
+        if (continuation.isInitial())
+        {
+            // new request
+            _requestStats.increment();
+            start = request.getTimeStamp();
+        }
+        else
+        {
+            // resumed request
+            start = System.currentTimeMillis();
+            _suspendStats.decrement();
+            if (continuation.isResumed())
+                _resumes.incrementAndGet();
+        }
+
+        try
+        {
+            super.handle(path, request, httpRequest, httpResponse);
+        }
+        finally
+        {
+            final long now = System.currentTimeMillis();
+            final long dispatched=now-start;
+            
+            _dispatchedStats.decrement();
+            _dispatchedTimeStats.set(dispatched);
+            
+            if (continuation.isSuspended())
+            {
+                if (continuation.isInitial())
+                    continuation.addContinuationListener(_onCompletion);
+                _suspendStats.increment();
+            }
+            else if (continuation.isInitial())
+            {
+                _requestStats.decrement();
+                _requestTimeStats.set(dispatched);
+                updateResponse(request);
+            }
+            // else onCompletion will handle it.
+        }
+    }
+
+    private void updateResponse(Request request)
+    {
+        Response response = request.getResponse();
+        switch (response.getStatus() / 100)
+        {
+            case 1:
+                _responses1xx.incrementAndGet();
+                break;
+            case 2:
+                _responses2xx.incrementAndGet();
+                break;
+            case 3:
+                _responses3xx.incrementAndGet();
+                break;
+            case 4:
+                _responses4xx.incrementAndGet();
+                break;
+            case 5:
+                _responses5xx.incrementAndGet();
+                break;
+            default:
+                break;
+        }
+        _responsesTotalBytes.addAndGet(response.getContentCount());
+    }
+
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+        statsReset();
+    }
+
+    /**
+     * @return the number of requests handled by this handler
+     * since {@link #statsReset()} was last called, excluding
+     * active requests
+     * @see #getResumes()
+     */
+    public int getRequests()
+    {
+        return (int)_requestStats.getTotal();
+    }
+
+    /**
+     * @return the number of requests currently active.
+     * since {@link #statsReset()} was last called.
+     */
+    public int getRequestsActive()
+    {
+        return (int)_requestStats.getCurrent();
+    }
+
+    /**
+     * @return the maximum number of active requests
+     * since {@link #statsReset()} was last called.
+     */
+    public int getRequestsActiveMax()
+    {
+        return (int)_requestStats.getMax();
+    }
+
+    /**
+     * @return the maximum time (in milliseconds) of request handling
+     * since {@link #statsReset()} was last called.
+     */
+    public long getRequestTimeMax()
+    {
+        return _requestTimeStats.getMax();
+    }
+
+    /**
+     * @return the total time (in milliseconds) of requests handling
+     * since {@link #statsReset()} was last called.
+     */
+    public long getRequestTimeTotal()
+    {
+        return _requestTimeStats.getTotal();
+    }
+
+    /**
+     * @return the mean time (in milliseconds) of request handling
+     * since {@link #statsReset()} was last called.
+     * @see #getRequestTimeTotal()
+     * @see #getRequests()
+     */
+    public double getRequestTimeMean()
+    {
+        return _requestTimeStats.getMean();
+    }
+
+    /**
+     * @return the standard deviation of time (in milliseconds) of request handling
+     * since {@link #statsReset()} was last called.
+     * @see #getRequestTimeTotal()
+     * @see #getRequests()
+     */
+    public double getRequestTimeStdDev()
+    {
+        return _requestTimeStats.getStdDev();
+    }
+
+    /**
+     * @return the number of dispatches seen by this handler
+     * since {@link #statsReset()} was last called, excluding
+     * active dispatches
+     */
+    public int getDispatched()
+    {
+        return (int)_dispatchedStats.getTotal();
+    }
+
+    /**
+     * @return the number of dispatches currently in this handler
+     * since {@link #statsReset()} was last called, including
+     * resumed requests
+     */
+    public int getDispatchedActive()
+    {
+        return (int)_dispatchedStats.getCurrent();
+    }
+
+    /**
+     * @return the max number of dispatches currently in this handler
+     * since {@link #statsReset()} was last called, including
+     * resumed requests
+     */
+    public int getDispatchedActiveMax()
+    {
+        return (int)_dispatchedStats.getMax();
+    }
+
+    /**
+     * @return the maximum time (in milliseconds) of request dispatch
+     * since {@link #statsReset()} was last called.
+     */
+    public long getDispatchedTimeMax()
+    {
+        return _dispatchedTimeStats.getMax();
+    }
+    
+    /**
+     * @return the total time (in milliseconds) of requests handling
+     * since {@link #statsReset()} was last called.
+     */
+    public long getDispatchedTimeTotal()
+    {
+        return _dispatchedTimeStats.getTotal();
+    }
+
+    /**
+     * @return the mean time (in milliseconds) of request handling
+     * since {@link #statsReset()} was last called.
+     * @see #getRequestTimeTotal()
+     * @see #getRequests()
+     */
+    public double getDispatchedTimeMean()
+    {
+        return _dispatchedTimeStats.getMean();
+    }
+    
+    /**
+     * @return the standard deviation of time (in milliseconds) of request handling
+     * since {@link #statsReset()} was last called.
+     * @see #getRequestTimeTotal()
+     * @see #getRequests()
+     */
+    public double getDispatchedTimeStdDev()
+    {
+        return _dispatchedTimeStats.getStdDev();
+    }
+    
+    /**
+     * @return the number of requests handled by this handler
+     * since {@link #statsReset()} was last called, including
+     * resumed requests
+     * @see #getResumes()
+     */
+    public int getSuspends()
+    {
+        return (int)_suspendStats.getTotal();
+    }
+
+    /**
+     * @return the number of requests currently suspended.
+     * since {@link #statsReset()} was last called.
+     */
+    public int getSuspendsActive()
+    {
+        return (int)_suspendStats.getCurrent();
+    }
+
+    /**
+     * @return the maximum number of current suspended requests
+     * since {@link #statsReset()} was last called.
+     */
+    public int getSuspendsActiveMax()
+    {
+        return (int)_suspendStats.getMax();
+    }
+    
+    /**
+     * @return the number of requests that have been resumed
+     * @see #getExpires()
+     */
+    public int getResumes()
+    {
+        return _resumes.get();
+    }
+
+    /**
+     * @return the number of requests that expired while suspended.
+     * @see #getResumes()
+     */
+    public int getExpires()
+    {
+        return _expires.get();
+    }
+
+    /**
+     * @return the number of responses with a 1xx status returned by this context
+     * since {@link #statsReset()} was last called.
+     */
+    public int getResponses1xx()
+    {
+        return _responses1xx.get();
+    }
+
+    /**
+     * @return the number of responses with a 2xx status returned by this context
+     * since {@link #statsReset()} was last called.
+     */
+    public int getResponses2xx()
+    {
+        return _responses2xx.get();
+    }
+
+    /**
+     * @return the number of responses with a 3xx status returned by this context
+     * since {@link #statsReset()} was last called.
+     */
+    public int getResponses3xx()
+    {
+        return _responses3xx.get();
+    }
+
+    /**
+     * @return the number of responses with a 4xx status returned by this context
+     * since {@link #statsReset()} was last called.
+     */
+    public int getResponses4xx()
+    {
+        return _responses4xx.get();
+    }
+
+    /**
+     * @return the number of responses with a 5xx status returned by this context
+     * since {@link #statsReset()} was last called.
+     */
+    public int getResponses5xx()
+    {
+        return _responses5xx.get();
+    }
+
+    /**
+     * @return the milliseconds since the statistics were started with {@link #statsReset()}.
+     */
+    public long getStatsOnMs()
+    {
+        return System.currentTimeMillis() - _statsStartedAt.get();
+    }
+    
+    /**
+     * @return the total bytes of content sent in responses
+     */
+    public long getResponsesBytesTotal()
+    {
+        return _responsesTotalBytes.get();
+    }
+    
+    public String toStatsHTML()
+    {   
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<h1>Statistics:</h1>\n");
+        sb.append("Statistics gathering started ").append(getStatsOnMs()).append("ms ago").append("<br />\n");
+
+        sb.append("<h2>Requests:</h2>\n");
+        sb.append("Total requests: ").append(getRequests()).append("<br />\n");
+        sb.append("Active requests: ").append(getRequestsActive()).append("<br />\n");
+        sb.append("Max active requests: ").append(getRequestsActiveMax()).append("<br />\n");
+        sb.append("Total requests time: ").append(getRequestTimeTotal()).append("<br />\n");
+        sb.append("Mean request time: ").append(getRequestTimeMean()).append("<br />\n");
+        sb.append("Max request time: ").append(getRequestTimeMax()).append("<br />\n");
+        sb.append("Request time standard deviation: ").append(getRequestTimeStdDev()).append("<br />\n");
+        
+
+        sb.append("<h2>Dispatches:</h2>\n");
+        sb.append("Total dispatched: ").append(getDispatched()).append("<br />\n");
+        sb.append("Active dispatched: ").append(getDispatchedActive()).append("<br />\n");
+        sb.append("Max active dispatched: ").append(getDispatchedActiveMax()).append("<br />\n");
+        sb.append("Total dispatched time: ").append(getDispatchedTimeTotal()).append("<br />\n");
+        sb.append("Mean dispatched time: ").append(getDispatchedTimeMean()).append("<br />\n");
+        sb.append("Max dispatched time: ").append(getDispatchedTimeMax()).append("<br />\n");
+        sb.append("Dispatched time standard deviation: ").append(getDispatchedTimeStdDev()).append("<br />\n");
+
+
+        sb.append("Total requests suspended: ").append(getSuspends()).append("<br />\n");
+        sb.append("Total requests expired: ").append(getExpires()).append("<br />\n");
+        sb.append("Total requests resumed: ").append(getResumes()).append("<br />\n");
+        
+        sb.append("<h2>Responses:</h2>\n");
+        sb.append("1xx responses: ").append(getResponses1xx()).append("<br />\n");
+        sb.append("2xx responses: ").append(getResponses2xx()).append("<br />\n");
+        sb.append("3xx responses: ").append(getResponses3xx()).append("<br />\n");
+        sb.append("4xx responses: ").append(getResponses4xx()).append("<br />\n");
+        sb.append("5xx responses: ").append(getResponses5xx()).append("<br />\n");
+        sb.append("Bytes sent total: ").append(getResponsesBytesTotal()).append("<br />\n");
+
+        return sb.toString();
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java b/src/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java
new file mode 100644
index 0000000..e43af98
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java
@@ -0,0 +1,121 @@
+//
+//  ========================================================================
+//  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.handler.jmx;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class AbstractHandlerMBean extends ObjectMBean
+{
+    private static final Logger LOG = Log.getLogger(AbstractHandlerMBean.class);
+
+    /* ------------------------------------------------------------ */
+    public AbstractHandlerMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String getObjectContextBasis()
+    {
+        if (_managed != null )
+        {
+            String basis = null;
+            if (_managed instanceof ContextHandler)
+            {
+                return null;
+            }
+            else if (_managed instanceof AbstractHandler)
+            {
+                AbstractHandler handler = (AbstractHandler)_managed;
+                Server server = handler.getServer();
+                if (server != null)
+                {
+                    ContextHandler context = 
+                        AbstractHandlerContainer.findContainerOf(server,
+                                ContextHandler.class, handler);
+                    
+                    if (context != null)
+                        basis = getContextName(context);
+                }
+            }
+            if (basis != null)
+                return basis;
+        }
+        return super.getObjectContextBasis();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public String getObjectNameBasis()
+    {
+        if (_managed != null )
+        {
+            String name = null;
+            if (_managed instanceof ContextHandler)
+            {
+                ContextHandler context = (ContextHandler)_managed;
+                name = getContextName(context);
+            }
+            
+            if (name != null)
+                return name;
+        }
+        
+        return super.getObjectNameBasis();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected String getContextName(ContextHandler context)
+    {
+        String name = null;
+        
+        if (context.getContextPath()!=null && context.getContextPath().length()>0)
+        {
+            int idx = context.getContextPath().lastIndexOf('/');
+            name = idx < 0 ? context.getContextPath() : context.getContextPath().substring(++idx);
+            if (name==null || name.length()==0)
+                name= "ROOT";
+        }
+        
+        if (name==null && context.getBaseResource()!=null)
+        {
+            try
+            {
+                if (context.getBaseResource().getFile()!=null)
+                    name = context.getBaseResource().getFile().getName();
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+                name=context.getBaseResource().getName();
+            }
+        }
+        
+        return name;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java b/src/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java
new file mode 100644
index 0000000..3848e1d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java
@@ -0,0 +1,66 @@
+//
+//  ========================================================================
+//  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.handler.jmx;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Attributes;
+
+public class ContextHandlerMBean extends AbstractHandlerMBean
+{
+    public ContextHandlerMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    public Map getContextAttributes()
+    {
+        Map map = new HashMap();
+        Attributes attrs = ((ContextHandler)_managed).getAttributes();
+        Enumeration en = attrs.getAttributeNames();
+        while (en.hasMoreElements())
+        {
+            String name = (String)en.nextElement();
+            Object value = attrs.getAttribute(name);
+            map.put(name,value);
+        }
+        return map;
+    }
+    
+    public void setContextAttribute(String name, Object value)
+    {
+        Attributes attrs = ((ContextHandler)_managed).getAttributes();
+        attrs.setAttribute(name,value);
+    }
+    
+    public void setContextAttribute(String name, String value)
+    {
+        Attributes attrs = ((ContextHandler)_managed).getAttributes();
+        attrs.setAttribute(name,value);
+    }
+    
+    public void removeContextAttribute(String name)
+    {
+        Attributes attrs = ((ContextHandler)_managed).getAttributes();
+        attrs.removeAttribute(name);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/jmx/ServerMBean.java b/src/java/org/eclipse/jetty/server/jmx/ServerMBean.java
new file mode 100644
index 0000000..c0fa28f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/jmx/ServerMBean.java
@@ -0,0 +1,50 @@
+//
+//  ========================================================================
+//  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.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ContextHandler;
+
+/**
+ *
+ */
+public class ServerMBean extends ObjectMBean
+{
+    private final long startupTime;
+    private final Server server;
+
+    public ServerMBean(Object managedObject)
+    {
+        super(managedObject);
+        startupTime = System.currentTimeMillis();
+        server = (Server)managedObject;
+    }
+
+    public Handler[] getContexts()
+    {
+        return server.getChildHandlersByClass(ContextHandler.class);
+    }
+
+    public long getStartupTime()
+    {
+        return startupTime;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java b/src/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java
new file mode 100644
index 0000000..ecea8af
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java
@@ -0,0 +1,53 @@
+//
+//  ========================================================================
+//  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.nio;
+
+import org.eclipse.jetty.io.Buffers.Type;
+import org.eclipse.jetty.server.AbstractConnector;
+
+public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector
+{
+    public AbstractNIOConnector()
+    {
+        _buffers.setRequestBufferType(Type.DIRECT);
+        _buffers.setRequestHeaderType(Type.INDIRECT);
+        _buffers.setResponseBufferType(Type.DIRECT);
+        _buffers.setResponseHeaderType(Type.INDIRECT);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public boolean getUseDirectBuffers()
+    {
+        return getRequestBufferType()==Type.DIRECT;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @param direct If True (the default), the connector can use NIO direct buffers.
+     * Some JVMs have memory management issues (bugs) with direct buffers.
+     */
+    public void setUseDirectBuffers(boolean direct)
+    {
+        _buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT);
+        _buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java b/src/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
new file mode 100644
index 0000000..b8f5c84
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/BlockingChannelConnector.java
@@ -0,0 +1,366 @@
+//
+//  ========================================================================
+//  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.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.Set;
+
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.nio.ChannelEndPoint;
+import org.eclipse.jetty.server.BlockingHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.ConcurrentHashSet;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------------------------- */
+/**  Blocking NIO connector.
+ * This connector uses efficient NIO buffers with a traditional blocking thread model.
+ * Direct NIO buffers are used and a thread is allocated per connections.
+ *
+ * This connector is best used when there are a few very active connections.
+ *
+ * @org.apache.xbean.XBean element="blockingNioConnector" description="Creates a blocking NIO based socket connector"
+ *
+ *
+ *
+ */
+public class BlockingChannelConnector extends AbstractNIOConnector
+{
+    private static final Logger LOG = Log.getLogger(BlockingChannelConnector.class);
+
+    private transient ServerSocketChannel _acceptChannel;
+    private final Set<BlockingChannelEndPoint> _endpoints = new ConcurrentHashSet<BlockingChannelEndPoint>();
+
+
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     *
+     */
+    public BlockingChannelConnector()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object getConnection()
+    {
+        return _acceptChannel;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.AbstractConnector#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+        getThreadPool().dispatch(new Runnable()
+        {
+
+            public void run()
+            {
+                while (isRunning())
+                {
+                    try
+                    {
+                        Thread.sleep(400);
+                        long now=System.currentTimeMillis();
+                        for (BlockingChannelEndPoint endp : _endpoints)
+                        {
+                            endp.checkIdleTimestamp(now);
+                        }
+                    }
+                    catch(InterruptedException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch(Exception e)
+                    {
+                        LOG.warn(e);
+                    }
+                }
+            }
+
+        });
+
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void open() throws IOException
+    {
+        // Create a new server socket and set to non blocking mode
+        _acceptChannel= ServerSocketChannel.open();
+        _acceptChannel.configureBlocking(true);
+
+        // Bind the server socket to the local host and port
+        InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort());
+        _acceptChannel.socket().bind(addr,getAcceptQueueSize());
+    }
+
+    /* ------------------------------------------------------------ */
+    public void close() throws IOException
+    {
+        if (_acceptChannel != null)
+            _acceptChannel.close();
+        _acceptChannel=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void accept(int acceptorID)
+    	throws IOException, InterruptedException
+    {
+        SocketChannel channel = _acceptChannel.accept();
+        channel.configureBlocking(true);
+        Socket socket=channel.socket();
+        configure(socket);
+
+        BlockingChannelEndPoint connection=new BlockingChannelEndPoint(channel);
+        connection.dispatch();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void customize(EndPoint endpoint, Request request)
+        throws IOException
+    {
+        super.customize(endpoint, request);
+        endpoint.setMaxIdleTime(_maxIdleTime);
+        configure(((SocketChannel)endpoint.getTransport()).socket());
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    public int getLocalPort()
+    {
+        if (_acceptChannel==null || !_acceptChannel.isOpen())
+            return -1;
+        return _acceptChannel.socket().getLocalPort();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    private class BlockingChannelEndPoint extends ChannelEndPoint implements Runnable, ConnectedEndPoint
+    {
+        private Connection _connection;
+        private int _timeout;
+        private volatile long _idleTimestamp;
+
+        BlockingChannelEndPoint(ByteChannel channel)
+            throws IOException
+        {
+            super(channel,BlockingChannelConnector.this._maxIdleTime);
+            _connection = new BlockingHttpConnection(BlockingChannelConnector.this,this,getServer());
+        }
+
+        /* ------------------------------------------------------------ */
+        /** Get the connection.
+         * @return the connection
+         */
+        public Connection getConnection()
+        {
+            return _connection;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setConnection(Connection connection)
+        {
+            _connection=connection;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void checkIdleTimestamp(long now)
+        {
+            if (_idleTimestamp!=0 && _timeout>0 && now>(_idleTimestamp+_timeout))
+            {
+                idleExpired();
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        protected void idleExpired()
+        {
+            try
+            {
+                super.close();
+            }
+            catch (IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        void dispatch() throws IOException
+        {
+            if (!getThreadPool().dispatch(this))
+            {
+                LOG.warn("dispatch failed for  {}",_connection);
+                super.close();
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @see org.eclipse.jetty.io.nio.ChannelEndPoint#fill(org.eclipse.jetty.io.Buffer)
+         */
+        @Override
+        public int fill(Buffer buffer) throws IOException
+        {
+            _idleTimestamp=System.currentTimeMillis();
+            return super.fill(buffer);
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @see org.eclipse.jetty.io.nio.ChannelEndPoint#flush(org.eclipse.jetty.io.Buffer)
+         */
+        @Override
+        public int flush(Buffer buffer) throws IOException
+        {
+            _idleTimestamp=System.currentTimeMillis();
+            return super.flush(buffer);
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @see org.eclipse.jetty.io.nio.ChannelEndPoint#flush(org.eclipse.jetty.io.Buffer, org.eclipse.jetty.io.Buffer, org.eclipse.jetty.io.Buffer)
+         */
+        @Override
+        public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+        {
+            _idleTimestamp=System.currentTimeMillis();
+            return super.flush(header,buffer,trailer);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void run()
+        {
+            try
+            {
+                _timeout=getMaxIdleTime();
+                connectionOpened(_connection);
+                _endpoints.add(this);
+
+                while (isOpen())
+                {
+                    _idleTimestamp=System.currentTimeMillis();
+                    if (_connection.isIdle())
+                    {
+                        if (getServer().getThreadPool().isLowOnThreads())
+                        {
+                            int lrmit = getLowResourcesMaxIdleTime();
+                            if (lrmit>=0 && _timeout!= lrmit)
+                            {
+                                _timeout=lrmit;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (_timeout!=getMaxIdleTime())
+                        {
+                            _timeout=getMaxIdleTime();
+                        }
+                    }
+
+                    _connection = _connection.handle();
+
+                }
+            }
+            catch (EofException e)
+            {
+                LOG.debug("EOF", e);
+                try{BlockingChannelEndPoint.this.close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch (HttpException e)
+            {
+                LOG.debug("BAD", e);
+                try{super.close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch(Throwable e)
+            {
+                LOG.warn("handle failed",e);
+                try{super.close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            finally
+            {
+                connectionClosed(_connection);
+                _endpoints.remove(this);
+
+                // wait for client to close, but if not, close ourselves.
+                try
+                {
+                    if (!_socket.isClosed())
+                    {
+                        long timestamp=System.currentTimeMillis();
+                        int max_idle=getMaxIdleTime();
+
+                        _socket.setSoTimeout(getMaxIdleTime());
+                        int c=0;
+                        do
+                        {
+                            c = _socket.getInputStream().read();
+                        }
+                        while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle);
+                        if (!_socket.isClosed())
+                            _socket.close();
+                    }
+                }
+                catch(IOException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return String.format("BCEP@%x{l(%s)<->r(%s),open=%b,ishut=%b,oshut=%b}-{%s}",
+                    hashCode(),
+                    _socket.getRemoteSocketAddress(),
+                    _socket.getLocalSocketAddress(),
+                    isOpen(),
+                    isInputShutdown(),
+                    isOutputShutdown(),
+                    _connection);
+        }
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/InheritedChannelConnector.java b/src/java/org/eclipse/jetty/server/nio/InheritedChannelConnector.java
new file mode 100644
index 0000000..c7cdc1d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/InheritedChannelConnector.java
@@ -0,0 +1,75 @@
+//
+//  ========================================================================
+//  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.nio;
+
+import java.io.IOException;
+import java.nio.channels.Channel;
+import java.nio.channels.ServerSocketChannel;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * An implementation of the SelectChannelConnector which first tries to  
+ * inherit from a channel provided by the system. If there is no inherited
+ * channel available, or if the inherited channel provided not usable, then 
+ * it will fall back upon normal ServerSocketChannel creation.
+ * <p> 
+ * Note that System.inheritedChannel() is only available from Java 1.5 onwards.
+ * Trying to use this class under Java 1.4 will be the same as using a normal
+ * SelectChannelConnector. 
+ * <p> 
+ * Use it with xinetd/inetd, to launch an instance of Jetty on demand. The port
+ * used to access pages on the Jetty instance is the same as the port used to
+ * launch Jetty. 
+ * 
+ * @author athena
+ */
+public class InheritedChannelConnector extends SelectChannelConnector
+{
+    private static final Logger LOG = Log.getLogger(InheritedChannelConnector.class);
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void open() throws IOException
+    {
+        synchronized(this)
+        {
+            try 
+            {
+                Channel channel = System.inheritedChannel();
+                if ( channel instanceof ServerSocketChannel )
+                    _acceptChannel = (ServerSocketChannel)channel;
+                else
+                    LOG.warn("Unable to use System.inheritedChannel() [" +channel+ "]. Trying a new ServerSocketChannel at " + getHost() + ":" + getPort());
+                
+                if ( _acceptChannel != null )
+                    _acceptChannel.configureBlocking(true);
+            }
+            catch(NoSuchMethodError e)
+            {
+                LOG.warn("Need at least Java 5 to use socket inherited from xinetd/inetd.");
+            }
+
+            if (_acceptChannel == null)
+                super.open();
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/NIOConnector.java b/src/java/org/eclipse/jetty/server/nio/NIOConnector.java
new file mode 100644
index 0000000..b80b6a8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/NIOConnector.java
@@ -0,0 +1,31 @@
+//
+//  ========================================================================
+//  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.nio; 
+
+/** 
+ * NIOConnector.
+ * A marker interface that indicates that NIOBuffers can be handled (efficiently) by this Connector.
+ * 
+ * 
+ * 
+ */
+public interface NIOConnector
+{
+    boolean getUseDirectBuffers();
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java b/src/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java
new file mode 100644
index 0000000..17be3fb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/NetworkTrafficSelectChannelConnector.java
@@ -0,0 +1,73 @@
+//
+//  ========================================================================
+//  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.nio;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.io.NetworkTrafficListener;
+import org.eclipse.jetty.io.nio.NetworkTrafficSelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+
+/**
+ * <p>A specialized version of {@link SelectChannelConnector} that supports {@link NetworkTrafficListener}s.</p>
+ * <p>{@link NetworkTrafficListener}s can be added and removed dynamically before and after this connector has
+ * been started without causing {@link ConcurrentModificationException}s.</p>
+ */
+public class NetworkTrafficSelectChannelConnector extends SelectChannelConnector
+{
+    private final List<NetworkTrafficListener> listeners = new CopyOnWriteArrayList<NetworkTrafficListener>();
+
+    /**
+     * @param listener the listener to add
+     */
+    public void addNetworkTrafficListener(NetworkTrafficListener listener)
+    {
+        listeners.add(listener);
+    }
+
+    /**
+     * @param listener the listener to remove
+     */
+    public void removeNetworkTrafficListener(NetworkTrafficListener listener)
+    {
+        listeners.remove(listener);
+    }
+
+    @Override
+    protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey key) throws IOException
+    {
+        NetworkTrafficSelectChannelEndPoint endPoint = new NetworkTrafficSelectChannelEndPoint(channel, selectSet, key, _maxIdleTime, listeners);
+        endPoint.setConnection(selectSet.getManager().newConnection(channel,endPoint, key.attachment()));
+        endPoint.notifyOpened();
+        return endPoint;
+    }
+
+    @Override
+    protected void endPointClosed(SelectChannelEndPoint endpoint)
+    {
+        super.endPointClosed(endpoint);
+        ((NetworkTrafficSelectChannelEndPoint)endpoint).notifyClosed();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/src/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
new file mode 100644
index 0000000..8ed6249
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java
@@ -0,0 +1,334 @@
+//
+//  ========================================================================
+//  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.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
+import org.eclipse.jetty.server.AsyncHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/* ------------------------------------------------------------------------------- */
+/**
+ * Selecting NIO connector.
+ * <p>
+ * This connector uses efficient NIO buffers with a non blocking threading model. Direct NIO buffers
+ * are used and threads are only allocated to connections with requests. Synchronization is used to
+ * simulate blocking for the servlet API, and any unflushed content at the end of request handling
+ * is written asynchronously.
+ * </p>
+ * <p>
+ * This connector is best used when there are a many connections that have idle periods.
+ * </p>
+ * <p>
+ * When used with {@link org.eclipse.jetty.continuation.Continuation}, threadless waits are supported.
+ * If a filter or servlet returns after calling {@link Continuation#suspend()} or when a
+ * runtime exception is thrown from a call to {@link Continuation#undispatch()}, Jetty will
+ * will not send a response to the client. Instead the thread is released and the Continuation is
+ * placed on the timer queue. If the Continuation timeout expires, or it's
+ * resume method is called, then the request is again allocated a thread and the request is retried.
+ * The limitation of this approach is that request content is not available on the retried request,
+ * thus if possible it should be read after the continuation or saved as a request attribute or as the
+ * associated object of the Continuation instance.
+ * </p>
+ *
+ * @org.apache.xbean.XBean element="nioConnector" description="Creates an NIO based socket connector"
+ */
+public class SelectChannelConnector extends AbstractNIOConnector
+{
+    protected ServerSocketChannel _acceptChannel;
+    private int _lowResourcesConnections;
+    private int _lowResourcesMaxIdleTime;
+    private int _localPort=-1;
+
+    private final SelectorManager _manager = new ConnectorSelectorManager();
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Constructor.
+     *
+     */
+    public SelectChannelConnector()
+    {
+        _manager.setMaxIdleTime(getMaxIdleTime());
+        addBean(_manager,true);
+        setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4));
+    }
+    
+    @Override
+    public void setThreadPool(ThreadPool pool)
+    {
+        super.setThreadPool(pool);
+        // preserve start order
+        removeBean(_manager);
+        addBean(_manager,true);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void accept(int acceptorID) throws IOException
+    {
+        ServerSocketChannel server;
+        synchronized(this)
+        {
+            server = _acceptChannel;
+        }
+
+        if (server!=null && server.isOpen() && _manager.isStarted())
+        {
+            SocketChannel channel = server.accept();
+            channel.configureBlocking(false);
+            Socket socket = channel.socket();
+            configure(socket);
+            _manager.register(channel);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void close() throws IOException
+    {
+        synchronized(this)
+        {
+            if (_acceptChannel != null)
+            {
+                removeBean(_acceptChannel);
+                if (_acceptChannel.isOpen())
+                    _acceptChannel.close();
+            }
+            _acceptChannel = null;
+            _localPort=-2;
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void customize(EndPoint endpoint, Request request) throws IOException
+    {
+        request.setTimeStamp(System.currentTimeMillis());
+        endpoint.setMaxIdleTime(_maxIdleTime);
+        super.customize(endpoint, request);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void persist(EndPoint endpoint) throws IOException
+    {
+        AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint);
+        aEndp.setCheckForIdle(true);
+        super.persist(endpoint);
+    }
+
+    /* ------------------------------------------------------------ */
+    public SelectorManager getSelectorManager()
+    {
+        return _manager;
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized Object getConnection()
+    {
+        return _acceptChannel;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    public int getLocalPort()
+    {
+        synchronized(this)
+        {
+            return _localPort;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void open() throws IOException
+    {
+        synchronized(this)
+        {
+            if (_acceptChannel == null)
+            {
+                // Create a new server socket
+                _acceptChannel = ServerSocketChannel.open();
+                // Set to blocking mode
+                _acceptChannel.configureBlocking(true);
+
+                // Bind the server socket to the local host and port
+                _acceptChannel.socket().setReuseAddress(getReuseAddress());
+                InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort());
+                _acceptChannel.socket().bind(addr,getAcceptQueueSize());
+
+                _localPort=_acceptChannel.socket().getLocalPort();
+                if (_localPort<=0)
+                    throw new IOException("Server channel not bound");
+
+                addBean(_acceptChannel);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setMaxIdleTime(int maxIdleTime)
+    {
+        _manager.setMaxIdleTime(maxIdleTime);
+        super.setMaxIdleTime(maxIdleTime);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the lowResourcesConnections
+     */
+    public int getLowResourcesConnections()
+    {
+        return _lowResourcesConnections;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the number of connections, which if exceeded places this manager in low resources state.
+     * This is not an exact measure as the connection count is averaged over the select sets.
+     * @param lowResourcesConnections the number of connections
+     * @see #setLowResourcesMaxIdleTime(int)
+     */
+    public void setLowResourcesConnections(int lowResourcesConnections)
+    {
+        _lowResourcesConnections=lowResourcesConnections;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the lowResourcesMaxIdleTime
+     */
+    @Override
+    public int getLowResourcesMaxIdleTime()
+    {
+        return _lowResourcesMaxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the period in ms that a connection is allowed to be idle when this there are more
+     * than {@link #getLowResourcesConnections()} connections.  This allows the server to rapidly close idle connections
+     * in order to gracefully handle high load situations.
+     * @param lowResourcesMaxIdleTime the period in ms that a connection is allowed to be idle when resources are low.
+     * @see #setMaxIdleTime(int)
+     */
+    @Override
+    public void setLowResourcesMaxIdleTime(int lowResourcesMaxIdleTime)
+    {
+        _lowResourcesMaxIdleTime=lowResourcesMaxIdleTime;
+        super.setLowResourcesMaxIdleTime(lowResourcesMaxIdleTime);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.jetty.server.server.AbstractConnector#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _manager.setSelectSets(getAcceptors());
+        _manager.setMaxIdleTime(getMaxIdleTime());
+        _manager.setLowResourcesConnections(getLowResourcesConnections());
+        _manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime());
+
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+    {
+        SelectChannelEndPoint endp= new SelectChannelEndPoint(channel,selectSet,key, SelectChannelConnector.this._maxIdleTime);
+        endp.setConnection(selectSet.getManager().newConnection(channel,endp, key.attachment()));
+        return endp;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    protected void endPointClosed(SelectChannelEndPoint endpoint)
+    {
+        connectionClosed(endpoint.getConnection());
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    protected AsyncConnection newConnection(SocketChannel channel,final AsyncEndPoint endpoint)
+    {
+        return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer());
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private final class ConnectorSelectorManager extends SelectorManager
+    {
+        @Override
+        public boolean dispatch(Runnable task)
+        {
+            ThreadPool pool=getThreadPool();
+            if (pool==null)
+                pool=getServer().getThreadPool();
+            return pool.dispatch(task);
+        }
+
+        @Override
+        protected void endPointClosed(final SelectChannelEndPoint endpoint)
+        {
+            SelectChannelConnector.this.endPointClosed(endpoint);
+        }
+
+        @Override
+        protected void endPointOpened(SelectChannelEndPoint endpoint)
+        {
+            // TODO handle max connections and low resources
+            connectionOpened(endpoint.getConnection());
+        }
+
+        @Override
+        protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
+        {
+            connectionUpgraded(oldConnection,endpoint.getConnection());
+        }
+
+        @Override
+        public AsyncConnection newConnection(SocketChannel channel,AsyncEndPoint endpoint, Object attachment)
+        {
+            return SelectChannelConnector.this.newConnection(channel,endpoint);
+        }
+
+        @Override
+        protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException
+        {
+            return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/session/AbstractSession.java b/src/java/org/eclipse/jetty/server/session/AbstractSession.java
new file mode 100644
index 0000000..1352fff
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/AbstractSession.java
@@ -0,0 +1,568 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/src/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
new file mode 100644
index 0000000..076d1cc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
@@ -0,0 +1,220 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/src/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
new file mode 100644
index 0000000..f38be8b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
@@ -0,0 +1,1026 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/src/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
new file mode 100644
index 0000000..ffd0430
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
@@ -0,0 +1,222 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/HashSessionManager.java b/src/java/org/eclipse/jetty/server/session/HashSessionManager.java
new file mode 100644
index 0000000..49bce68
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -0,0 +1,640 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/HashedSession.java b/src/java/org/eclipse/jetty/server/session/HashedSession.java
new file mode 100644
index 0000000..d3251e1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/HashedSession.java
@@ -0,0 +1,241 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/src/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
new file mode 100644
index 0000000..05a82d1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -0,0 +1,1040 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/src/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
new file mode 100644
index 0000000..fc50b77
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -0,0 +1,1174 @@
+//
+//  ========================================================================
+//  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 --git a/src/java/org/eclipse/jetty/server/session/SessionHandler.java b/src/java/org/eclipse/jetty/server/session/SessionHandler.java
new file mode 100644
index 0000000..19f5f05
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/SessionHandler.java
@@ -0,0 +1,346 @@
+//
+//  ========================================================================
+//  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();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java b/src/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java
new file mode 100644
index 0000000..a9dd4a9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java
@@ -0,0 +1,58 @@
+//
+//  ========================================================================
+//  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.jmx;
+
+import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.jmx.AbstractHandlerMBean;
+import org.eclipse.jetty.server.session.AbstractSessionManager;
+import org.eclipse.jetty.server.session.SessionHandler;
+
+public class AbstractSessionManagerMBean extends AbstractHandlerMBean
+{
+    public AbstractSessionManagerMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getObjectContextBasis()
+    {
+        if (_managed != null && _managed instanceof AbstractSessionManager)
+        {
+            AbstractSessionManager manager = (AbstractSessionManager)_managed;
+            
+            String basis = null;
+            SessionHandler handler = manager.getSessionHandler();
+            if (handler != null)
+            {
+                ContextHandler context = 
+                    AbstractHandlerContainer.findContainerOf(handler.getServer(), 
+                                                             ContextHandler.class,
+                                                             handler);
+                if (context != null)
+                    basis = getContextName(context);
+            }
+
+            if (basis != null)
+                return basis;
+        }
+        return super.getObjectContextBasis();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/ssl/ServletSSL.java b/src/java/org/eclipse/jetty/server/ssl/ServletSSL.java
new file mode 100644
index 0000000..6003b68
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ssl/ServletSSL.java
@@ -0,0 +1,88 @@
+//
+//  ========================================================================
+//  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.ssl;
+
+/* --------------------------------------------------------------------- */
+/**
+ * Jetty Servlet SSL support utilities.
+ * <p>
+ * A collection of utilities required to support the SSL requirements of the Servlet 2.2 and 2.3
+ * specs.
+ * 
+ * <p>
+ * Used by the SSL listener classes.
+ * 
+ * 
+ */
+public class ServletSSL
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * Given the name of a TLS/SSL cipher suite, return an int representing it effective stream
+     * cipher key strength. i.e. How much entropy material is in the key material being fed into the
+     * encryption routines.
+     * 
+     * <p>
+     * This is based on the information on effective key lengths in RFC 2246 - The TLS Protocol
+     * Version 1.0, Appendix C. CipherSuite definitions:
+     * 
+     * <pre>
+     *                         Effective 
+     *     Cipher       Type    Key Bits 
+     * 		       	       
+     *     NULL       * Stream     0     
+     *     IDEA_CBC     Block    128     
+     *     RC2_CBC_40 * Block     40     
+     *     RC4_40     * Stream    40     
+     *     RC4_128      Stream   128     
+     *     DES40_CBC  * Block     40     
+     *     DES_CBC      Block     56     
+     *     3DES_EDE_CBC Block    168     
+     * </pre>
+     * 
+     * @param cipherSuite String name of the TLS cipher suite.
+     * @return int indicating the effective key entropy bit-length.
+     */
+    public static int deduceKeyLength(String cipherSuite)
+    {
+        // Roughly ordered from most common to least common.
+        if (cipherSuite == null)
+            return 0;
+        else if (cipherSuite.indexOf("WITH_AES_256_") >= 0)
+            return 256;
+        else if (cipherSuite.indexOf("WITH_RC4_128_") >= 0)
+            return 128;
+        else if (cipherSuite.indexOf("WITH_AES_128_") >= 0)
+            return 128;
+        else if (cipherSuite.indexOf("WITH_RC4_40_") >= 0)
+            return 40;
+        else if (cipherSuite.indexOf("WITH_3DES_EDE_CBC_") >= 0)
+            return 168;
+        else if (cipherSuite.indexOf("WITH_IDEA_CBC_") >= 0)
+            return 128;
+        else if (cipherSuite.indexOf("WITH_RC2_CBC_40_") >= 0)
+            return 40;
+        else if (cipherSuite.indexOf("WITH_DES40_CBC_") >= 0)
+            return 40;
+        else if (cipherSuite.indexOf("WITH_DES_CBC_") >= 0)
+            return 56;
+        else
+            return 0;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/ssl/SslCertificates.java b/src/java/org/eclipse/jetty/server/ssl/SslCertificates.java
new file mode 100644
index 0000000..655b814
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ssl/SslCertificates.java
@@ -0,0 +1,182 @@
+//
+//  ========================================================================
+//  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.ssl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class SslCertificates
+{
+    private static final Logger LOG = Log.getLogger(SslCertificates.class);
+
+    /**
+     * The name of the SSLSession attribute that will contain any cached information.
+     */
+    static final String CACHED_INFO_ATTR = CachedInfo.class.getName();
+
+    public static X509Certificate[] getCertChain(SSLSession sslSession)
+    {
+        try
+        {
+            javax.security.cert.X509Certificate javaxCerts[]=sslSession.getPeerCertificateChain();
+            if (javaxCerts==null||javaxCerts.length==0)
+                return null;
+
+            int length=javaxCerts.length;
+            X509Certificate[] javaCerts=new X509Certificate[length];
+
+            java.security.cert.CertificateFactory cf=java.security.cert.CertificateFactory.getInstance("X.509");
+            for (int i=0; i<length; i++)
+            {
+                byte bytes[]=javaxCerts[i].getEncoded();
+                ByteArrayInputStream stream=new ByteArrayInputStream(bytes);
+                javaCerts[i]=(X509Certificate)cf.generateCertificate(stream);
+            }
+
+            return javaCerts;
+        }
+        catch (SSLPeerUnverifiedException pue)
+        {
+            return null;
+        }
+        catch (Exception e)
+        {
+            LOG.warn(Log.EXCEPTION,e);
+            return null;
+        }
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Allow the Listener a chance to customise the request. before the server
+     * does its stuff. <br>
+     * This allows the required attributes to be set for SSL requests. <br>
+     * The requirements of the Servlet specs are:
+     * <ul>
+     * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
+     * String (since Servlet Spec 3.0).</li>
+     * <li> an attribute named "javax.servlet.request.cipher_suite" of type
+     * String.</li>
+     * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
+     * <li> an attribute named "javax.servlet.request.X509Certificate" of type
+     * java.security.cert.X509Certificate[]. This is an array of objects of type
+     * X509Certificate, the order of this array is defined as being in ascending
+     * order of trust. The first certificate in the chain is the one set by the
+     * client, the next is the one used to authenticate the first, and so on.
+     * </li>
+     * </ul>
+     * 
+     * @param endpoint
+     *                The Socket the request arrived on. This should be a
+     *                {@link SocketEndPoint} wrapping a {@link SSLSocket}.
+     * @param request
+     *                HttpRequest to be customised.
+     */
+    public static void customize(SSLSession sslSession, EndPoint endpoint, Request request) throws IOException
+    {
+        request.setScheme(HttpSchemes.HTTPS);
+
+        try
+        {
+            String cipherSuite=sslSession.getCipherSuite();
+            Integer keySize;
+            X509Certificate[] certs;
+            String idStr;
+
+            CachedInfo cachedInfo=(CachedInfo)sslSession.getValue(CACHED_INFO_ATTR);
+            if (cachedInfo!=null)
+            {
+                keySize=cachedInfo.getKeySize();
+                certs=cachedInfo.getCerts();
+                idStr=cachedInfo.getIdStr();
+            }
+            else
+            {
+                keySize=new Integer(ServletSSL.deduceKeyLength(cipherSuite));
+                certs=SslCertificates.getCertChain(sslSession);
+                byte[] bytes = sslSession.getId();
+                idStr = TypeUtil.toHexString(bytes);
+                cachedInfo=new CachedInfo(keySize,certs,idStr);
+                sslSession.putValue(CACHED_INFO_ATTR,cachedInfo);
+            }
+
+            if (certs!=null)
+                request.setAttribute("javax.servlet.request.X509Certificate",certs);
+
+            request.setAttribute("javax.servlet.request.cipher_suite",cipherSuite);
+            request.setAttribute("javax.servlet.request.key_size",keySize);
+            request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
+        }
+        catch (Exception e)
+        {
+            LOG.warn(Log.EXCEPTION,e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * Simple bundle of information that is cached in the SSLSession. Stores the
+     * effective keySize and the client certificate chain.
+     */
+    private static class CachedInfo
+    {
+        private final X509Certificate[] _certs;
+        private final Integer _keySize;
+        private final String _idStr;
+
+        CachedInfo(Integer keySize, X509Certificate[] certs,String idStr)
+        {
+            this._keySize=keySize;
+            this._certs=certs;
+            this._idStr=idStr;
+        }
+
+        X509Certificate[] getCerts()
+        {
+            return _certs;
+        }
+
+        Integer getKeySize()
+        {
+            return _keySize;
+        }
+        
+        String getIdStr()
+        {
+            return _idStr;
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/server/ssl/SslConnector.java b/src/java/org/eclipse/jetty/server/ssl/SslConnector.java
new file mode 100644
index 0000000..88aed2a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ssl/SslConnector.java
@@ -0,0 +1,348 @@
+//
+//  ========================================================================
+//  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.ssl;
+
+import java.io.File;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+
+/* ------------------------------------------------------------ */
+/** The interface for SSL connectors and their configuration methods.
+ * 
+ */
+public interface SslConnector extends Connector
+{
+    @Deprecated
+    public static final String DEFAULT_KEYSTORE_ALGORITHM=(Security.getProperty("ssl.KeyManagerFactory.algorithm")==null?"SunX509":Security.getProperty("ssl.KeyManagerFactory.algorithm"));
+    @Deprecated
+    public static final String DEFAULT_TRUSTSTORE_ALGORITHM=(Security.getProperty("ssl.TrustManagerFactory.algorithm")==null?"SunX509":Security.getProperty("ssl.TrustManagerFactory.algorithm"));
+
+    /** Default value for the keystore location path. @deprecated */
+    @Deprecated
+    public static final String DEFAULT_KEYSTORE = System.getProperty("user.home") + File.separator + ".keystore";
+    
+    /** String name of key password property. @deprecated */
+    @Deprecated
+    public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";
+    
+    /** String name of keystore password property. @deprecated */
+    @Deprecated
+    public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the instance of SslContextFactory associated with the connector
+     */
+    public SslContextFactory getSslContextFactory();
+        
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of Ciphersuite names to exclude from 
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String[] getExcludeCipherSuites();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cipherSuites The array of Ciphersuite names to exclude from 
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setExcludeCipherSuites(String[] cipherSuites);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of Ciphersuite names to include in
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String[] getIncludeCipherSuites();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cipherSuites The array of Ciphersuite names to include in 
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setIncludeCipherSuites(String[] cipherSuites);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password The password for the key store
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setPassword(String password);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password The password for the trust store
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setTrustPassword(String password);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password The password (if any) for the specific key within 
+     * the key store
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setKeyPassword(String password);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSL protocol (default "TLS") passed to {@link SSLContext#getInstance(String, String)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getProtocol();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocol The SSL protocol (default "TLS") passed to {@link SSLContext#getInstance(String, String)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setProtocol(String protocol);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keystore The file or URL of the SSL Key store.
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setKeystore(String keystore);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file or URL of the SSL Key store.
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getKeystore();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the key store (default "JKS")
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getKeystoreType();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL needs client authentication.
+     * @see SSLEngine#getNeedClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public abstract boolean getNeedClientAuth();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL wants client authentication.
+     * @see SSLEngine#getWantClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public abstract boolean getWantClientAuth();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param needClientAuth True if SSL needs client authentication.
+     * @see SSLEngine#getNeedClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setNeedClientAuth(boolean needClientAuth);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param wantClientAuth True if SSL wants client authentication.
+     * @see SSLEngine#getWantClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setWantClientAuth(boolean wantClientAuth);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keystoreType The type of the key store (default "JKS")
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setKeystoreType(String keystoreType);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSL provider name, which if set is passed to 
+     * {@link SSLContext#getInstance(String, String)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getProvider();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name, which if set is passed to 
+     * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom}
+     * instance passed to {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getSecureRandomAlgorithm();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getSslKeyManagerFactoryAlgorithm();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getSslTrustManagerFactoryAlgorithm();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file name or URL of the trust store location
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getTruststore();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the trust store (default "JKS")
+     * @deprecated
+     */
+    @Deprecated
+    public abstract String getTruststoreType();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param provider The SSL provider name, which if set is passed to 
+     * {@link SSLContext#getInstance(String, String)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setProvider(String provider);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm The algorithm name, which if set is passed to 
+     * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom}
+     * instance passed to {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setSecureRandomAlgorithm(String algorithm);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm The algorithm name (default "SunX509") used by 
+     * the {@link KeyManagerFactory}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setSslKeyManagerFactoryAlgorithm(String algorithm);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setSslTrustManagerFactoryAlgorithm(String algorithm);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param truststore The file name or URL of the trust store location
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setTruststore(String truststore);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param truststoreType The type of the trust store (default "JKS")
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setTruststoreType(String truststoreType);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param sslContext Set a preconfigured SSLContext
+     * @deprecated
+     */
+    @Deprecated
+    public abstract void setSslContext(SSLContext sslContext);
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSLContext
+     * @deprecated
+     */
+    @Deprecated
+    public abstract SSLContext getSslContext();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL re-negotiation is allowed (default false)
+     * @deprecated
+     */
+    @Deprecated
+    public boolean isAllowRenegotiate();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
+     * does not have CVE-2009-3555 fixed, then re-negotiation should 
+     * not be allowed.
+     * @param allowRenegotiate true if re-negotiation is allowed (default false)
+     * @deprecated
+     */
+    @Deprecated
+    public void setAllowRenegotiate(boolean allowRenegotiate);
+}
diff --git a/src/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/src/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
new file mode 100644
index 0000000..833a68f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java
@@ -0,0 +1,653 @@
+//
+//  ========================================================================
+//  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.ssl;
+
+import java.io.IOException;
+import java.nio.channels.SocketChannel;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Buffers.Type;
+import org.eclipse.jetty.io.BuffersFactory;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RuntimeIOException;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SslConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+/* ------------------------------------------------------------ */
+/**
+ * SslSelectChannelConnector.
+ *
+ * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector"
+ */
+public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
+{
+    private final SslContextFactory _sslContextFactory;
+    private Buffers _sslBuffers;
+
+    /* ------------------------------------------------------------ */
+    public SslSelectChannelConnector()
+    {
+        this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
+        setSoLingerTime(30000);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Construct with explicit SslContextFactory.
+     * The SslContextFactory passed is added via {@link #addBean(Object)} so that 
+     * it's lifecycle may be managed with {@link AggregateLifeCycle}.
+     * @param sslContextFactory
+     */
+    public SslSelectChannelConnector(SslContextFactory sslContextFactory)
+    {
+        _sslContextFactory = sslContextFactory;
+        addBean(_sslContextFactory);
+        setUseDirectBuffers(false);
+        setSoLingerTime(30000);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Allow the Listener a chance to customise the request. before the server
+     * does its stuff. <br>
+     * This allows the required attributes to be set for SSL requests. <br>
+     * The requirements of the Servlet specs are:
+     * <ul>
+     * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
+     * String (since Servlet Spec 3.0).</li>
+     * <li> an attribute named "javax.servlet.request.cipher_suite" of type
+     * String.</li>
+     * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
+     * <li> an attribute named "javax.servlet.request.X509Certificate" of type
+     * java.security.cert.X509Certificate[]. This is an array of objects of type
+     * X509Certificate, the order of this array is defined as being in ascending
+     * order of trust. The first certificate in the chain is the one set by the
+     * client, the next is the one used to authenticate the first, and so on.
+     * </li>
+     * </ul>
+     *
+     * @param endpoint
+     *                The Socket the request arrived on. This should be a
+     *                {@link SocketEndPoint} wrapping a {@link SSLSocket}.
+     * @param request
+     *                HttpRequest to be customised.
+     */
+    @Override
+    public void customize(EndPoint endpoint, Request request) throws IOException
+    {
+        request.setScheme(HttpSchemes.HTTPS);
+        super.customize(endpoint,request);
+
+        SslConnection.SslEndPoint sslEndpoint=(SslConnection.SslEndPoint)endpoint;
+        SSLEngine sslEngine=sslEndpoint.getSslEngine();
+        SSLSession sslSession=sslEngine.getSession();
+
+        SslCertificates.customize(sslSession,endpoint,request);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL re-negotiation is allowed (default false)
+     * @deprecated
+     */
+    @Deprecated
+    public boolean isAllowRenegotiate()
+    {
+        return _sslContextFactory.isAllowRenegotiate();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
+     * does not have CVE-2009-3555 fixed, then re-negotiation should
+     * not be allowed.  CVE-2009-3555 was fixed in Sun java 1.6 with a ban
+     * of renegotiate in u19 and with RFC5746 in u22.
+     * @param allowRenegotiate true if re-negotiation is allowed (default false)
+     * @deprecated
+     */
+    @Deprecated
+    public void setAllowRenegotiate(boolean allowRenegotiate)
+    {
+        _sslContextFactory.setAllowRenegotiate(allowRenegotiate);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
+     * @deprecated
+     */
+    @Deprecated
+    public String[] getExcludeCipherSuites()
+    {
+        return _sslContextFactory.getExcludeCipherSuites();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
+     * @deprecated
+     */
+    @Deprecated
+    public void setExcludeCipherSuites(String[] cipherSuites)
+    {
+        _sslContextFactory.setExcludeCipherSuites(cipherSuites);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
+     * @deprecated
+     */
+    @Deprecated
+    public String[] getIncludeCipherSuites()
+    {
+        return _sslContextFactory.getIncludeCipherSuites();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
+     * @deprecated
+     */
+    @Deprecated
+    public void setIncludeCipherSuites(String[] cipherSuites)
+    {
+        _sslContextFactory.setIncludeCipherSuites(cipherSuites);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setPassword(String password)
+    {
+        _sslContextFactory.setKeyStorePassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTrustPassword(String password)
+    {
+        _sslContextFactory.setTrustStorePassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeyPassword(String password)
+    {
+        _sslContextFactory.setKeyManagerPassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unsupported.
+     *
+     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+     * @deprecated
+     */
+    @Deprecated
+    public String getAlgorithm()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unsupported.
+     *
+     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+     * @deprecated
+     */
+    @Deprecated
+    public void setAlgorithm(String algorithm)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
+     * @deprecated
+     */
+    @Deprecated
+    public String getProtocol()
+    {
+        return _sslContextFactory.getProtocol();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setProtocol(String protocol)
+    {
+        _sslContextFactory.setProtocol(protocol);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystore(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeystore(String keystore)
+    {
+        _sslContextFactory.setKeyStorePath(keystore);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
+     * @deprecated
+     */
+    @Deprecated
+    public String getKeystore()
+    {
+        return _sslContextFactory.getKeyStorePath();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
+     * @deprecated
+     */
+    @Deprecated
+    public String getKeystoreType()
+    {
+        return _sslContextFactory.getKeyStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public boolean getNeedClientAuth()
+    {
+        return _sslContextFactory.getNeedClientAuth();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public boolean getWantClientAuth()
+    {
+        return _sslContextFactory.getWantClientAuth();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setNeedClientAuth(boolean)
+     * @deprecated
+     */
+    @Deprecated
+    public void setNeedClientAuth(boolean needClientAuth)
+    {
+        _sslContextFactory.setNeedClientAuth(needClientAuth);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setWantClientAuth(boolean)
+     * @deprecated
+     */
+    @Deprecated
+    public void setWantClientAuth(boolean wantClientAuth)
+    {
+        _sslContextFactory.setWantClientAuth(wantClientAuth);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeystoreType(String keystoreType)
+    {
+        _sslContextFactory.setKeyStoreType(keystoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
+     * @deprecated
+     */
+    @Deprecated
+    public String getProvider()
+    {
+        return _sslContextFactory.getProvider();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSecureRandomAlgorithm()
+    {
+        return _sslContextFactory.getSecureRandomAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSslKeyManagerFactoryAlgorithm()
+    {
+        return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSslTrustManagerFactoryAlgorithm()
+    {
+        return _sslContextFactory.getTrustManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
+     * @deprecated
+     */
+    @Deprecated
+    public String getTruststore()
+    {
+        return _sslContextFactory.getTrustStore();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
+     * @deprecated
+     */
+    @Deprecated
+    public String getTruststoreType()
+    {
+        return _sslContextFactory.getTrustStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setProvider(String provider)
+    {
+        _sslContextFactory.setProvider(provider);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSecureRandomAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setSecureRandomAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslTrustManagerFactoryAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTruststore(String truststore)
+    {
+        _sslContextFactory.setTrustStore(truststore);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTruststoreType(String truststoreType)
+    {
+        _sslContextFactory.setTrustStoreType(truststoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslContext(SSLContext sslContext)
+    {
+        _sslContextFactory.setSslContext(sslContext);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+     * @deprecated
+     */
+    @Deprecated
+    public SSLContext getSslContext()
+    {
+        return _sslContextFactory.getSslContext();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory()
+     */
+    public SslContextFactory getSslContextFactory()
+    {
+        return _sslContextFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * By default, we're confidential, given we speak SSL. But, if we've been
+     * told about an confidential port, and said port is not our port, then
+     * we're not. This allows separation of listeners providing INTEGRAL versus
+     * CONFIDENTIAL constraints, such as one SSL listener configured to require
+     * client certs providing CONFIDENTIAL, whereas another SSL listener not
+     * requiring client certs providing mere INTEGRAL constraints.
+     */
+    @Override
+    public boolean isConfidential(Request request)
+    {
+        final int confidentialPort=getConfidentialPort();
+        return confidentialPort==0||confidentialPort==request.getServerPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * By default, we're integral, given we speak SSL. But, if we've been told
+     * about an integral port, and said port is not our port, then we're not.
+     * This allows separation of listeners providing INTEGRAL versus
+     * CONFIDENTIAL constraints, such as one SSL listener configured to require
+     * client certs providing CONFIDENTIAL, whereas another SSL listener not
+     * requiring client certs providing mere INTEGRAL constraints.
+     */
+    @Override
+    public boolean isIntegral(Request request)
+    {
+        final int integralPort=getIntegralPort();
+        return integralPort==0||integralPort==request.getServerPort();
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    protected AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint)
+    {
+        try
+        {
+            SSLEngine engine = createSSLEngine(channel);
+            SslConnection connection = newSslConnection(endpoint, engine);
+            AsyncConnection delegate = newPlainConnection(channel, connection.getSslEndPoint());
+            connection.getSslEndPoint().setConnection(delegate);
+            connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
+            return connection;
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeIOException(e);
+        }
+    }
+
+    protected AsyncConnection newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)
+    {
+        return super.newConnection(channel, endPoint);
+    }
+
+    protected SslConnection newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)
+    {
+        return new SslConnection(engine, endpoint);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param channel A channel which if passed is used as to extract remote
+     * host and port for the purposes of SSL session caching
+     * @return A SSLEngine for a new or cached SSL Session
+     * @throws IOException if the SSLEngine cannot be created
+     */
+    protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException
+    {
+        SSLEngine engine;
+        if (channel != null)
+        {
+            String peerHost = channel.socket().getInetAddress().getHostAddress();
+            int peerPort = channel.socket().getPort();
+            engine = _sslContextFactory.newSslEngine(peerHost, peerPort);
+        }
+        else
+        {
+            engine = _sslContextFactory.newSslEngine();
+        }
+
+        engine.setUseClientMode(false);
+        return engine;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _sslContextFactory.checkKeyStore();
+        _sslContextFactory.start();
+
+        SSLEngine sslEngine = _sslContextFactory.newSslEngine();
+
+        sslEngine.setUseClientMode(false);
+
+        SSLSession sslSession = sslEngine.getSession();
+
+        _sslBuffers = BuffersFactory.newBuffers(
+                getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
+                getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
+                getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,getMaxBuffers()
+        );
+
+        if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
+            setRequestHeaderSize(sslSession.getApplicationBufferSize());
+        if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
+            setRequestBufferSize(sslSession.getApplicationBufferSize());
+
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        _sslBuffers=null;
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return SSL buffers
+     */
+    public Buffers getSslBuffers()
+    {
+        return _sslBuffers;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java b/src/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
new file mode 100644
index 0000000..2b94467
--- /dev/null
+++ b/src/java/org/eclipse/jetty/server/ssl/SslSocketConnector.java
@@ -0,0 +1,712 @@
+//
+//  ========================================================================
+//  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.ssl;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RuntimeIOException;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+/* ------------------------------------------------------------ */
+/**
+ * SSL Socket Connector.
+ *
+ * This specialization of SocketConnector is an abstract listener that can be used as the basis for a
+ * specific JSSE listener.
+ *
+ * The original of this class was heavily based on the work from Court Demas, which in turn is
+ * based on the work from Forge Research. Since JSSE, this class has evolved significantly from
+ * that early work.
+ *
+ * @org.apache.xbean.XBean element="sslSocketConnector" description="Creates an ssl socket connector"
+ *
+ *
+ */
+public class SslSocketConnector extends SocketConnector  implements SslConnector
+{
+    private static final Logger LOG = Log.getLogger(SslSocketConnector.class);
+
+    private final SslContextFactory _sslContextFactory;
+    private int _handshakeTimeout = 0; //0 means use maxIdleTime
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructor.
+     */
+    public SslSocketConnector()
+    {
+        this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
+        setSoLingerTime(30000);
+    }
+
+    /* ------------------------------------------------------------ */
+    public SslSocketConnector(SslContextFactory sslContextFactory)
+    {
+        _sslContextFactory = sslContextFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL re-negotiation is allowed (default false)
+     */
+    public boolean isAllowRenegotiate()
+    {
+        return _sslContextFactory.isAllowRenegotiate();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
+     * does not have CVE-2009-3555 fixed, then re-negotiation should
+     * not be allowed.
+     * @param allowRenegotiate true if re-negotiation is allowed (default false)
+     */
+    public void setAllowRenegotiate(boolean allowRenegotiate)
+    {
+        _sslContextFactory.setAllowRenegotiate(allowRenegotiate);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void accept(int acceptorID)
+        throws IOException, InterruptedException
+    {
+        Socket socket = _serverSocket.accept();
+        configure(socket);
+
+        ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
+        connection.dispatch();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void configure(Socket socket)
+        throws IOException
+    {
+        super.configure(socket);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Allow the Listener a chance to customise the request. before the server does its stuff. <br>
+     * This allows the required attributes to be set for SSL requests. <br>
+     * The requirements of the Servlet specs are:
+     * <ul>
+     * <li> an attribute named "javax.servlet.request.ssl_id" of type String (since Spec 3.0).</li>
+     * <li> an attribute named "javax.servlet.request.cipher_suite" of type String.</li>
+     * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
+     * <li> an attribute named "javax.servlet.request.X509Certificate" of type
+     * java.security.cert.X509Certificate[]. This is an array of objects of type X509Certificate,
+     * the order of this array is defined as being in ascending order of trust. The first
+     * certificate in the chain is the one set by the client, the next is the one used to
+     * authenticate the first, and so on. </li>
+     * </ul>
+     *
+     * @param endpoint The Socket the request arrived on.
+     *        This should be a {@link SocketEndPoint} wrapping a {@link SSLSocket}.
+     * @param request HttpRequest to be customised.
+     */
+    @Override
+    public void customize(EndPoint endpoint, Request request)
+        throws IOException
+    {
+        super.customize(endpoint, request);
+        request.setScheme(HttpSchemes.HTTPS);
+
+        SocketEndPoint socket_end_point = (SocketEndPoint)endpoint;
+        SSLSocket sslSocket = (SSLSocket)socket_end_point.getTransport();
+        SSLSession sslSession = sslSocket.getSession();
+
+        SslCertificates.customize(sslSession,endpoint,request);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
+     * @deprecated
+     */
+    @Deprecated
+    public String[] getExcludeCipherSuites() {
+        return _sslContextFactory.getExcludeCipherSuites();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getIncludeCipherSuites()
+     * @deprecated
+     */
+    @Deprecated
+    public String[] getIncludeCipherSuites()
+    {
+        return _sslContextFactory.getIncludeCipherSuites();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
+     * @deprecated
+     */
+    @Deprecated
+    public String getKeystore()
+    {
+        return _sslContextFactory.getKeyStorePath();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
+     * @deprecated
+     */
+    @Deprecated
+    public String getKeystoreType()
+    {
+        return _sslContextFactory.getKeyStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public boolean getNeedClientAuth()
+    {
+        return _sslContextFactory.getNeedClientAuth();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
+     * @deprecated
+     */
+    @Deprecated
+    public String getProtocol()
+    {
+        return _sslContextFactory.getProtocol();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
+     * @deprecated
+     */
+    @Deprecated
+    public String getProvider() {
+	return _sslContextFactory.getProvider();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSecureRandomAlgorithm()
+    {
+        return _sslContextFactory.getSecureRandomAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSslKeyManagerFactoryAlgorithm()
+    {
+        return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
+     * @deprecated
+     */
+    @Deprecated
+    public String getSslTrustManagerFactoryAlgorithm()
+    {
+        return _sslContextFactory.getTrustManagerFactoryAlgorithm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
+     * @deprecated
+     */
+    @Deprecated
+    public String getTruststore()
+    {
+        return _sslContextFactory.getTrustStore();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory()
+     */
+//    @Override
+    public SslContextFactory getSslContextFactory()
+    {
+        return _sslContextFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
+     * @deprecated
+     */
+    @Deprecated
+    public String getTruststoreType()
+    {
+        return _sslContextFactory.getTrustStoreType();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
+     * @deprecated
+     */
+    @Deprecated
+    public boolean getWantClientAuth()
+    {
+        return _sslContextFactory.getWantClientAuth();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * By default, we're confidential, given we speak SSL. But, if we've been told about an
+     * confidential port, and said port is not our port, then we're not. This allows separation of
+     * listeners providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener
+     * configured to require client certs providing CONFIDENTIAL, whereas another SSL listener not
+     * requiring client certs providing mere INTEGRAL constraints.
+     */
+    @Override
+    public boolean isConfidential(Request request)
+    {
+        final int confidentialPort = getConfidentialPort();
+        return confidentialPort == 0 || confidentialPort == request.getServerPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * By default, we're integral, given we speak SSL. But, if we've been told about an integral
+     * port, and said port is not our port, then we're not. This allows separation of listeners
+     * providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener configured to
+     * require client certs providing CONFIDENTIAL, whereas another SSL listener not requiring
+     * client certs providing mere INTEGRAL constraints.
+     */
+    @Override
+    public boolean isIntegral(Request request)
+    {
+        final int integralPort = getIntegralPort();
+        return integralPort == 0 || integralPort == request.getServerPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void open() throws IOException
+    {
+        _sslContextFactory.checkKeyStore();
+        try
+        {
+            _sslContextFactory.start();
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeIOException(e);
+        }
+        super.open();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        _sslContextFactory.checkKeyStore();
+        _sslContextFactory.start();
+
+        super.doStart();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.bio.SocketConnector#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        _sslContextFactory.stop();
+
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param host The host name that this server should listen on
+     * @param port the port that this server should listen on
+     * @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
+     * @return A new {@link ServerSocket socket object} bound to the supplied address with all other
+     * settings as per the current configuration of this connector.
+     * @see #setWantClientAuth(boolean)
+     * @see #setNeedClientAuth(boolean)
+     * @exception IOException
+     */
+    @Override
+    protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
+    {
+       return _sslContextFactory.newSslServerSocket(host,port,backlog);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
+     * @deprecated
+     */
+    @Deprecated
+    public void setExcludeCipherSuites(String[] cipherSuites)
+    {
+        _sslContextFactory.setExcludeCipherSuites(cipherSuites);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setIncludeCipherSuites(java.lang.String[])
+     * @deprecated
+     */
+    @Deprecated
+    public void setIncludeCipherSuites(String[] cipherSuites)
+    {
+        _sslContextFactory.setIncludeCipherSuites(cipherSuites);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeyPassword(String password)
+    {
+        _sslContextFactory.setKeyManagerPassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keystore The resource path to the keystore, or null for built in keystores.
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeystore(String keystore)
+    {
+        _sslContextFactory.setKeyStorePath(keystore);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setKeystoreType(String keystoreType)
+    {
+        _sslContextFactory.setKeyStoreType(keystoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the value of the needClientAuth property
+     *
+     * @param needClientAuth true iff we require client certificate authentication.
+     * @deprecated
+     */
+    @Deprecated
+    public void setNeedClientAuth(boolean needClientAuth)
+    {
+        _sslContextFactory.setNeedClientAuth(needClientAuth);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setPassword(String password)
+    {
+        _sslContextFactory.setKeyStorePassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTrustPassword(String password)
+    {
+        _sslContextFactory.setTrustStorePassword(password);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setProtocol(String protocol)
+    {
+        _sslContextFactory.setProtocol(protocol);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setProvider(String provider) {
+        _sslContextFactory.setProvider(provider);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSecureRandomAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setSecureRandomAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslTrustManagerFactoryAlgorithm(String algorithm)
+    {
+        _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTruststore(String truststore)
+    {
+        _sslContextFactory.setTrustStore(truststore);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
+     * @deprecated
+     */
+    @Deprecated
+    public void setTruststoreType(String truststoreType)
+    {
+        _sslContextFactory.setTrustStoreType(truststoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+     * @deprecated
+     */
+    @Deprecated
+    public void setSslContext(SSLContext sslContext)
+    {
+        _sslContextFactory.setSslContext(sslContext);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+     * @deprecated
+     */
+    @Deprecated
+    public SSLContext getSslContext()
+    {
+        return _sslContextFactory.getSslContext();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the value of the _wantClientAuth property. This property is used
+     * internally when opening server sockets.
+     *
+     * @param wantClientAuth true if we want client certificate authentication.
+     * @see SSLServerSocket#setWantClientAuth
+     * @deprecated
+     */
+    @Deprecated
+    public void setWantClientAuth(boolean wantClientAuth)
+    {
+        _sslContextFactory.setWantClientAuth(wantClientAuth);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the time in milliseconds for so_timeout during ssl handshaking
+     * @param msec a non-zero value will be used to set so_timeout during
+     * ssl handshakes. A zero value means the maxIdleTime is used instead.
+     */
+    public void setHandshakeTimeout (int msec)
+    {
+        _handshakeTimeout = msec;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public int getHandshakeTimeout ()
+    {
+        return _handshakeTimeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    public class SslConnectorEndPoint extends ConnectorEndPoint
+    {
+        public SslConnectorEndPoint(Socket socket) throws IOException
+        {
+            super(socket);
+        }
+
+        @Override
+        public void shutdownOutput() throws IOException
+        {
+            close();
+        }
+
+        @Override
+        public void shutdownInput() throws IOException
+        {
+            close();
+        }
+
+        @Override
+        public void run()
+        {
+            try
+            {
+                int handshakeTimeout = getHandshakeTimeout();
+                int oldTimeout = _socket.getSoTimeout();
+                if (handshakeTimeout > 0)
+                    _socket.setSoTimeout(handshakeTimeout);
+
+                final SSLSocket ssl=(SSLSocket)_socket;
+                ssl.addHandshakeCompletedListener(new HandshakeCompletedListener()
+                {
+                    boolean handshook=false;
+                    public void handshakeCompleted(HandshakeCompletedEvent event)
+                    {
+                        if (handshook)
+                        {
+                            if (!_sslContextFactory.isAllowRenegotiate())
+                            {
+                                LOG.warn("SSL renegotiate denied: "+ssl);
+                                try{ssl.close();}catch(IOException e){LOG.warn(e);}
+                            }
+                        }
+                        else
+                            handshook=true;
+                    }
+                });
+                ssl.startHandshake();
+
+                if (handshakeTimeout>0)
+                    _socket.setSoTimeout(oldTimeout);
+
+                super.run();
+            }
+            catch (SSLException e)
+            {
+                LOG.debug(e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+            catch (IOException e)
+            {
+                LOG.debug(e);
+                try{close();}
+                catch(IOException e2){LOG.ignore(e2);}
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unsupported.
+     *
+     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+     * @deprecated
+     */
+    @Deprecated
+    public String getAlgorithm()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unsupported.
+     *
+     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+     * @deprecated
+     */
+    @Deprecated
+    public void setAlgorithm(String algorithm)
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/DefaultServlet.java b/src/java/org/eclipse/jetty/servlet/DefaultServlet.java
new file mode 100644
index 0000000..6707ab0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/DefaultServlet.java
@@ -0,0 +1,1134 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpContent;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeaderValues;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.WriterOutputStream;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.HttpOutput;
+import org.eclipse.jetty.server.InclusiveByteRange;
+import org.eclipse.jetty.server.ResourceCache;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.nio.NIOConnector;
+import org.eclipse.jetty.server.ssl.SslConnector;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.MultiPartOutputStream;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+import org.eclipse.jetty.util.resource.ResourceFactory;
+
+
+
+/* ------------------------------------------------------------ */
+/** The default servlet.
+ * This servlet, normally mapped to /, provides the handling for static
+ * content, OPTION and TRACE methods for the context.
+ * The following initParameters are supported, these can be set either
+ * on the servlet itself or as ServletContext initParameters with a prefix
+ * of org.eclipse.jetty.servlet.Default. :
+ * <PRE>
+ *  acceptRanges      If true, range requests and responses are
+ *                    supported
+ *
+ *  dirAllowed        If true, directory listings are returned if no
+ *                    welcome file is found. Else 403 Forbidden.
+ *
+ *  welcomeServlets   If true, attempt to dispatch to welcome files
+ *                    that are servlets, but only after no matching static
+ *                    resources could be found. If false, then a welcome
+ *                    file must exist on disk. If "exact", then exact
+ *                    servlet matches are supported without an existing file.
+ *                    Default is true.
+ *
+ *                    This must be false if you want directory listings,
+ *                    but have index.jsp in your welcome file list.
+ *
+ *  redirectWelcome   If true, welcome files are redirected rather than
+ *                    forwarded to.
+ *
+ *  gzip              If set to true, then static content will be served as
+ *                    gzip content encoded if a matching resource is
+ *                    found ending with ".gz"
+ *
+ *  resourceBase      Set to replace the context resource base
+ *
+ *  resourceCache     If set, this is a context attribute name, which the servlet 
+ *                    will use to look for a shared ResourceCache instance. 
+ *                        
+ *  relativeResourceBase
+ *                    Set with a pathname relative to the base of the
+ *                    servlet context root. Useful for only serving static content out
+ *                    of only specific subdirectories.
+ *
+ *  pathInfoOnly      If true, only the path info will be applied to the resourceBase 
+ *                        
+ *  stylesheet	      Set with the location of an optional stylesheet that will be used
+ *                    to decorate the directory listing html.
+ *
+ *  aliases           If True, aliases of resources are allowed (eg. symbolic
+ *                    links and caps variations). May bypass security constraints.
+ *                    
+ *  etags             If True, weak etags will be handled.
+ *
+ *  maxCacheSize      The maximum total size of the cache or 0 for no cache.
+ *  maxCachedFileSize The maximum size of a file to cache
+ *  maxCachedFiles    The maximum number of files to cache
+ *
+ *  useFileMappedBuffer
+ *                    If set to true, it will use mapped file buffer to serve static content
+ *                    when using NIO connector. Setting this value to false means that
+ *                    a direct buffer will be used instead of a mapped file buffer.
+ *                    By default, this is set to true.
+ *
+ *  cacheControl      If set, all static content will have this value set as the cache-control
+ *                    header.
+ *
+ *
+ * </PRE>
+ *
+ *
+ *
+ *
+ */
+public class DefaultServlet extends HttpServlet implements ResourceFactory
+{
+    private static final Logger LOG = Log.getLogger(DefaultServlet.class);
+
+    private static final long serialVersionUID = 4930458713846881193L;
+    private ServletContext _servletContext;
+    private ContextHandler _contextHandler;
+
+    private boolean _acceptRanges=true;
+    private boolean _dirAllowed=true;
+    private boolean _welcomeServlets=false;
+    private boolean _welcomeExactServlets=false;
+    private boolean _redirectWelcome=false;
+    private boolean _gzip=true;
+    private boolean _pathInfoOnly=false;
+    private boolean _etags=false;
+
+    private Resource _resourceBase;
+    private ResourceCache _cache;
+
+    private MimeTypes _mimeTypes;
+    private String[] _welcomes;
+    private Resource _stylesheet;
+    private boolean _useFileMappedBuffer=false;
+    private ByteArrayBuffer _cacheControl;
+    private String _relativeResourceBase;
+    private ServletHandler _servletHandler;
+    private ServletHolder _defaultHolder;
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void init()
+    throws UnavailableException
+    {
+        _servletContext=getServletContext();
+        _contextHandler = initContextHandler(_servletContext);
+
+        _mimeTypes = _contextHandler.getMimeTypes();
+
+        _welcomes = _contextHandler.getWelcomeFiles();
+        if (_welcomes==null)
+            _welcomes=new String[] {"index.html","index.jsp"};
+
+        _acceptRanges=getInitBoolean("acceptRanges",_acceptRanges);
+        _dirAllowed=getInitBoolean("dirAllowed",_dirAllowed);
+        _redirectWelcome=getInitBoolean("redirectWelcome",_redirectWelcome);
+        _gzip=getInitBoolean("gzip",_gzip);
+        _pathInfoOnly=getInitBoolean("pathInfoOnly",_pathInfoOnly);
+
+        if ("exact".equals(getInitParameter("welcomeServlets")))
+        {
+            _welcomeExactServlets=true;
+            _welcomeServlets=false;
+        }
+        else
+            _welcomeServlets=getInitBoolean("welcomeServlets", _welcomeServlets);
+
+        if (getInitParameter("aliases")!=null)
+            _contextHandler.setAliases(getInitBoolean("aliases",false));
+
+        boolean aliases=_contextHandler.isAliases();
+        if (!aliases && !FileResource.getCheckAliases())
+            throw new IllegalStateException("Alias checking disabled");
+        if (aliases)
+            _servletContext.log("Aliases are enabled! Security constraints may be bypassed!!!");
+
+        _useFileMappedBuffer=getInitBoolean("useFileMappedBuffer",_useFileMappedBuffer);
+
+        _relativeResourceBase = getInitParameter("relativeResourceBase");
+
+        String rb=getInitParameter("resourceBase");
+        if (rb!=null)
+        {
+            if (_relativeResourceBase!=null)
+                throw new  UnavailableException("resourceBase & relativeResourceBase");
+            try{_resourceBase=_contextHandler.newResource(rb);}
+            catch (Exception e)
+            {
+                LOG.warn(Log.EXCEPTION,e);
+                throw new UnavailableException(e.toString());
+            }
+        }
+
+        String css=getInitParameter("stylesheet");
+        try
+        {
+            if(css!=null)
+            {
+                _stylesheet = Resource.newResource(css);
+                if(!_stylesheet.exists())
+                {
+                    LOG.warn("!" + css);
+                    _stylesheet = null;
+                }
+            }
+            if(_stylesheet == null)
+            {
+                _stylesheet = Resource.newResource(this.getClass().getResource("/jetty-dir.css"));
+            }
+        }	
+        catch(Exception e)
+        {
+            LOG.warn(e.toString());
+            LOG.debug(e);
+        }
+
+        String t=getInitParameter("cacheControl");
+        if (t!=null)
+            _cacheControl=new ByteArrayBuffer(t);
+
+        String resourceCache = getInitParameter("resourceCache");
+        int max_cache_size=getInitInt("maxCacheSize", -2);
+        int max_cached_file_size=getInitInt("maxCachedFileSize", -2);
+        int max_cached_files=getInitInt("maxCachedFiles", -2);
+        if (resourceCache!=null)
+        {
+            if (max_cache_size!=-1 || max_cached_file_size!= -2 || max_cached_files!=-2)
+                LOG.debug("ignoring resource cache configuration, using resourceCache attribute");
+            if (_relativeResourceBase!=null || _resourceBase!=null)
+                throw new UnavailableException("resourceCache specified with resource bases");
+            _cache=(ResourceCache)_servletContext.getAttribute(resourceCache);
+
+            LOG.debug("Cache {}={}",resourceCache,_cache);
+        }
+
+        _etags = getInitBoolean("etags",_etags);
+        
+        try
+        {
+            if (_cache==null && max_cached_files>0)
+            {
+                _cache= new ResourceCache(null,this,_mimeTypes,_useFileMappedBuffer,_etags);
+
+                if (max_cache_size>0)
+                    _cache.setMaxCacheSize(max_cache_size);
+                if (max_cached_file_size>=-1)
+                    _cache.setMaxCachedFileSize(max_cached_file_size);
+                if (max_cached_files>=-1)
+                    _cache.setMaxCachedFiles(max_cached_files);
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.warn(Log.EXCEPTION,e);
+            throw new UnavailableException(e.toString());
+        }
+
+        _servletHandler= (ServletHandler) _contextHandler.getChildHandlerByClass(ServletHandler.class);
+        for (ServletHolder h :_servletHandler.getServlets())
+            if (h.getServletInstance()==this)
+                _defaultHolder=h;
+
+        
+        if (LOG.isDebugEnabled()) 
+            LOG.debug("resource base = "+_resourceBase);
+    }
+
+    /**
+     * Compute the field _contextHandler.<br/>
+     * In the case where the DefaultServlet is deployed on the HttpService it is likely that
+     * this method needs to be overwritten to unwrap the ServletContext facade until we reach
+     * the original jetty's ContextHandler.
+     * @param servletContext The servletContext of this servlet.
+     * @return the jetty's ContextHandler for this servletContext.
+     */
+    protected ContextHandler initContextHandler(ServletContext servletContext)
+    {
+        ContextHandler.Context scontext=ContextHandler.getCurrentContext();
+        if (scontext==null)
+        {
+            if (servletContext instanceof ContextHandler.Context)
+                return ((ContextHandler.Context)servletContext).getContextHandler();
+            else
+                throw new IllegalArgumentException("The servletContext " + servletContext + " " + 
+                    servletContext.getClass().getName() + " is not " + ContextHandler.Context.class.getName());
+        }
+        else
+            return ContextHandler.getCurrentContext().getContextHandler();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String getInitParameter(String name)
+    {
+        String value=getServletContext().getInitParameter("org.eclipse.jetty.servlet.Default."+name);
+        if (value==null)
+            value=super.getInitParameter(name);
+        return value;
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean getInitBoolean(String name, boolean dft)
+    {
+        String value=getInitParameter(name);
+        if (value==null || value.length()==0)
+            return dft;
+        return (value.startsWith("t")||
+                value.startsWith("T")||
+                value.startsWith("y")||
+                value.startsWith("Y")||
+                value.startsWith("1"));
+    }
+
+    /* ------------------------------------------------------------ */
+    private int getInitInt(String name, int dft)
+    {
+        String value=getInitParameter(name);
+        if (value==null)
+            value=getInitParameter(name);
+        if (value!=null && value.length()>0)
+            return Integer.parseInt(value);
+        return dft;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** get Resource to serve.
+     * Map a path to a resource. The default implementation calls
+     * HttpContext.getResource but derived servlets may provide
+     * their own mapping.
+     * @param pathInContext The path to find a resource for.
+     * @return The resource to serve.
+     */
+    public Resource getResource(String pathInContext)
+    {	
+        Resource r=null;
+        if (_relativeResourceBase!=null)
+            pathInContext=URIUtil.addPaths(_relativeResourceBase,pathInContext);
+
+        try
+        {
+            if (_resourceBase!=null)
+            {
+                r = _resourceBase.addPath(pathInContext);
+                if (!_contextHandler.checkAlias(pathInContext,r))
+                    r=null;
+            }
+            else if (_servletContext instanceof ContextHandler.Context)
+            {
+                r = _contextHandler.getResource(pathInContext);
+            }
+            else
+            {
+                URL u = _servletContext.getResource(pathInContext);
+                r = _contextHandler.newResource(u);
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("Resource "+pathInContext+"="+r);
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+
+        if((r==null || !r.exists()) && pathInContext.endsWith("/jetty-dir.css"))
+            r=_stylesheet;
+
+        return r;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response)
+    throws ServletException, IOException
+    {
+        String servletPath=null;
+        String pathInfo=null;
+        Enumeration<String> reqRanges = null;
+        Boolean included =request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI)!=null;
+        if (included!=null && included.booleanValue())
+        {
+            servletPath=(String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
+            pathInfo=(String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
+            if (servletPath==null)
+            {
+                servletPath=request.getServletPath();
+                pathInfo=request.getPathInfo();
+            }
+        }
+        else
+        {
+            included = Boolean.FALSE;
+            servletPath = _pathInfoOnly?"/":request.getServletPath();
+            pathInfo = request.getPathInfo();
+
+            // Is this a Range request?
+            reqRanges = request.getHeaders(HttpHeaders.RANGE);
+            if (!hasDefinedRange(reqRanges))
+                reqRanges = null;
+        }
+        
+        String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
+        boolean endsWithSlash=(pathInfo==null?request.getServletPath():pathInfo).endsWith(URIUtil.SLASH);
+        
+
+        // Find the resource and content
+        Resource resource=null;
+        HttpContent content=null;
+        try
+        {
+            // is gzip enabled?
+            String pathInContextGz=null;
+            boolean gzip=false;
+            if (!included.booleanValue() && _gzip && reqRanges==null && !endsWithSlash )
+            {
+                // Look for a gzip resource
+                pathInContextGz=pathInContext+".gz";
+                if (_cache==null)
+                    resource=getResource(pathInContextGz);
+                else
+                {
+                    content=_cache.lookup(pathInContextGz);
+                    resource=(content==null)?null:content.getResource();
+                }
+
+                // Does a gzip resource exist?
+                if (resource!=null && resource.exists() && !resource.isDirectory())
+                {
+                    // Tell caches that response may vary by accept-encoding
+                    response.addHeader(HttpHeaders.VARY,HttpHeaders.ACCEPT_ENCODING);
+                    
+                    // Does the client accept gzip?
+                    String accept=request.getHeader(HttpHeaders.ACCEPT_ENCODING);
+                    if (accept!=null && accept.indexOf("gzip")>=0)
+                        gzip=true;
+                }
+            }
+
+            // find resource
+            if (!gzip)
+            {
+                if (_cache==null)
+                    resource=getResource(pathInContext);
+                else
+                {
+                    content=_cache.lookup(pathInContext);
+                    resource=content==null?null:content.getResource();
+                }
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("uri="+request.getRequestURI()+" resource="+resource+(content!=null?" content":""));
+            
+            // Handle resource
+            if (resource==null || !resource.exists())
+            {
+                if (included) 
+                    throw new FileNotFoundException("!" + pathInContext);
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            }
+            else if (!resource.isDirectory())
+            {
+                if (endsWithSlash && _contextHandler.isAliases() && pathInContext.length()>1)
+                {
+                    String q=request.getQueryString();
+                    pathInContext=pathInContext.substring(0,pathInContext.length()-1);
+                    if (q!=null&&q.length()!=0)
+                        pathInContext+="?"+q;
+                    response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(_servletContext.getContextPath(),pathInContext)));
+                }
+                else
+                {
+                    // ensure we have content
+                    if (content==null)
+                        content=new HttpContent.ResourceAsHttpContent(resource,_mimeTypes.getMimeByExtension(resource.toString()),response.getBufferSize(),_etags);
+
+                    if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
+                    {
+                        if (gzip)
+                        {
+                            response.setHeader(HttpHeaders.CONTENT_ENCODING,"gzip");
+                            String mt=_servletContext.getMimeType(pathInContext);
+                            if (mt!=null)
+                                response.setContentType(mt);
+                        }
+                        sendData(request,response,included.booleanValue(),resource,content,reqRanges);
+                    }
+                }
+            }
+            else
+            {
+                String welcome=null;
+
+                if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.eclipse.jetty.server.nullPathInfo")!=null))
+                {
+                    StringBuffer buf=request.getRequestURL();
+                    synchronized(buf)
+                    {
+                        int param=buf.lastIndexOf(";");
+                        if (param<0)
+                            buf.append('/');
+                        else
+                            buf.insert(param,'/');
+                        String q=request.getQueryString();
+                        if (q!=null&&q.length()!=0)
+                        {
+                            buf.append('?');
+                            buf.append(q);
+                        }
+                        response.setContentLength(0);
+                        response.sendRedirect(response.encodeRedirectURL(buf.toString()));
+                    }
+                }
+                // else look for a welcome file
+                else if (null!=(welcome=getWelcomeFile(pathInContext)))
+                {
+                    LOG.debug("welcome={}",welcome);
+                    if (_redirectWelcome)
+                    {
+                        // Redirect to the index
+                        response.setContentLength(0);
+                        String q=request.getQueryString();
+                        if (q!=null&&q.length()!=0)
+                            response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths( _servletContext.getContextPath(),welcome)+"?"+q));
+                        else
+                            response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths( _servletContext.getContextPath(),welcome)));
+                    }
+                    else
+                    {
+                        // Forward to the index
+                        RequestDispatcher dispatcher=request.getRequestDispatcher(welcome);
+                        if (dispatcher!=null)
+                        {
+                            if (included.booleanValue())
+                                dispatcher.include(request,response);
+                            else
+                            {
+                                request.setAttribute("org.eclipse.jetty.server.welcome",welcome);
+                                dispatcher.forward(request,response);
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    content=new HttpContent.ResourceAsHttpContent(resource,_mimeTypes.getMimeByExtension(resource.toString()),_etags);
+                    if (included.booleanValue() || passConditionalHeaders(request,response, resource,content))
+                        sendDirectory(request,response,resource,pathInContext);
+                }
+            }
+        }
+        catch(IllegalArgumentException e)
+        {
+            LOG.warn(Log.EXCEPTION,e);
+            if(!response.isCommitted())
+                response.sendError(500, e.getMessage());
+        }
+        finally
+        {
+            if (content!=null)
+                content.release();
+            else if (resource!=null)
+                resource.release();
+        }
+
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean hasDefinedRange(Enumeration<String> reqRanges)
+    {
+        return (reqRanges!=null && reqRanges.hasMoreElements());
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doPost(HttpServletRequest request, HttpServletResponse response)
+    throws ServletException, IOException
+    {
+        doGet(request,response);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.http.HttpServlet#doTrace(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+    {
+        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+    throws ServletException, IOException
+    {
+        resp.setHeader("Allow", "GET,HEAD,POST,OPTIONS");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Finds a matching welcome file for the supplied {@link Resource}. This will be the first entry in the list of
+     * configured {@link #_welcomes welcome files} that existing within the directory referenced by the <code>Resource</code>.
+     * If the resource is not a directory, or no matching file is found, then it may look for a valid servlet mapping.
+     * If there is none, then <code>null</code> is returned.
+     * The list of welcome files is read from the {@link ContextHandler} for this servlet, or
+     * <code>"index.jsp" , "index.html"</code> if that is <code>null</code>.
+     * @param resource
+     * @return The path of the matching welcome file in context or null.
+     * @throws IOException
+     * @throws MalformedURLException
+     */
+    private String getWelcomeFile(String pathInContext) throws MalformedURLException, IOException
+    {
+        if (_welcomes==null)
+            return null;
+
+        String welcome_servlet=null;
+        for (int i=0;i<_welcomes.length;i++)
+        {
+            String welcome_in_context=URIUtil.addPaths(pathInContext,_welcomes[i]);
+            Resource welcome=getResource(welcome_in_context);
+            if (welcome!=null && welcome.exists())
+                return _welcomes[i];
+
+            if ((_welcomeServlets || _welcomeExactServlets) && welcome_servlet==null)
+            {
+                Map.Entry entry=_servletHandler.getHolderEntry(welcome_in_context);
+                if (entry!=null && entry.getValue()!=_defaultHolder &&
+                        (_welcomeServlets || (_welcomeExactServlets && entry.getKey().equals(welcome_in_context))))
+                    welcome_servlet=welcome_in_context;
+
+            }
+        }
+        return welcome_servlet;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* Check modification date headers.
+     */
+    protected boolean passConditionalHeaders(HttpServletRequest request,HttpServletResponse response, Resource resource, HttpContent content)
+    throws IOException
+    {
+        try
+        {
+            if (!request.getMethod().equals(HttpMethods.HEAD) )
+            {
+                if (_etags)
+                {
+                    String ifm=request.getHeader(HttpHeaders.IF_MATCH);
+                    if (ifm!=null)
+                    {
+                        boolean match=false;
+                        if (content!=null && content.getETag()!=null)
+                        {
+                            QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifm,", ",false,true);
+                            while (!match && quoted.hasMoreTokens())
+                            {
+                                String tag = quoted.nextToken();
+                                if (content.getETag().toString().equals(tag))
+                                    match=true;
+                            }
+                        }
+
+                        if (!match)
+                        {
+                            Response r = Response.getResponse(response);
+                            r.reset(true);
+                            r.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
+                            return false;
+                        }
+                    }
+                    
+                    String ifnm=request.getHeader(HttpHeaders.IF_NONE_MATCH);
+                    if (ifnm!=null && content!=null && content.getETag()!=null)
+                    {
+                        // Look for GzipFiltered version of etag
+                        if (content.getETag().toString().equals(request.getAttribute("o.e.j.s.GzipFilter.ETag")))
+                        {
+                            Response r = Response.getResponse(response);
+                            r.reset(true);
+                            r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                            r.getHttpFields().put(HttpHeaders.ETAG_BUFFER,ifnm);
+                            return false;
+                        }
+                        
+                        
+                        // Handle special case of exact match.
+                        if (content.getETag().toString().equals(ifnm))
+                        {
+                            Response r = Response.getResponse(response);
+                            r.reset(true);
+                            r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                            r.getHttpFields().put(HttpHeaders.ETAG_BUFFER,content.getETag());
+                            return false;
+                        }
+
+                        // Handle list of tags
+                        QuotedStringTokenizer quoted = new QuotedStringTokenizer(ifnm,", ",false,true);
+                        while (quoted.hasMoreTokens())
+                        {
+                            String tag = quoted.nextToken();
+                            if (content.getETag().toString().equals(tag))
+                            {
+                                Response r = Response.getResponse(response);
+                                r.reset(true);
+                                r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                                r.getHttpFields().put(HttpHeaders.ETAG_BUFFER,content.getETag());
+                                return false;
+                            }
+                        }
+                        
+                        return true;
+                    }
+                }
+                
+                String ifms=request.getHeader(HttpHeaders.IF_MODIFIED_SINCE);
+                if (ifms!=null)
+                {
+                    //Get jetty's Response impl
+                    Response r = Response.getResponse(response);
+                                       
+                    if (content!=null)
+                    {
+                        Buffer mdlm=content.getLastModified();
+                        if (mdlm!=null)
+                        {
+                            if (ifms.equals(mdlm.toString()))
+                            {
+                                r.reset(true);
+                                r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                                if (_etags)
+                                    r.getHttpFields().add(HttpHeaders.ETAG_BUFFER,content.getETag());
+                                r.flushBuffer();
+                                return false;
+                            }
+                        }
+                    }
+
+                    long ifmsl=request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
+                    if (ifmsl!=-1)
+                    {
+                        if (resource.lastModified()/1000 <= ifmsl/1000)
+                        { 
+                            r.reset(true);
+                            r.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                            if (_etags)
+                                r.getHttpFields().add(HttpHeaders.ETAG_BUFFER,content.getETag());
+                            r.flushBuffer();
+                            return false;
+                        }
+                    }
+                }
+
+                // Parse the if[un]modified dates and compare to resource
+                long date=request.getDateHeader(HttpHeaders.IF_UNMODIFIED_SINCE);
+
+                if (date!=-1)
+                {
+                    if (resource.lastModified()/1000 > date/1000)
+                    {
+                        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                        return false;
+                    }
+                }
+
+            }
+        }
+        catch(IllegalArgumentException iae)
+        {
+            if(!response.isCommitted())
+                response.sendError(400, iae.getMessage());
+            throw iae;
+        }
+        return true;
+    }
+
+
+    /* ------------------------------------------------------------------- */
+    protected void sendDirectory(HttpServletRequest request,
+            HttpServletResponse response,
+            Resource resource,
+            String pathInContext)
+    throws IOException
+    {
+        if (!_dirAllowed)
+        {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN);
+            return;
+        }
+
+        byte[] data=null;
+        String base = URIUtil.addPaths(request.getRequestURI(),URIUtil.SLASH);
+
+        //If the DefaultServlet has a resource base set, use it
+        if (_resourceBase != null)
+        {
+            // handle ResourceCollection
+            if (_resourceBase instanceof ResourceCollection)
+                resource=_resourceBase.addPath(pathInContext);
+        }
+        //Otherwise, try using the resource base of its enclosing context handler
+        else if (_contextHandler.getBaseResource() instanceof ResourceCollection)
+            resource=_contextHandler.getBaseResource().addPath(pathInContext);
+
+        String dir = resource.getListHTML(base,pathInContext.length()>1);
+        if (dir==null)
+        {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN,
+            "No directory");
+            return;
+        }
+
+        data=dir.getBytes("UTF-8");
+        response.setContentType("text/html; charset=UTF-8");
+        response.setContentLength(data.length);
+        response.getOutputStream().write(data);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void sendData(HttpServletRequest request,
+            HttpServletResponse response,
+            boolean include,
+            Resource resource,
+            HttpContent content,
+            Enumeration reqRanges)
+    throws IOException
+    {
+        boolean direct;
+        long content_length;
+        if (content==null)
+        {
+            direct=false;
+            content_length=resource.length();
+        }
+        else
+        {
+            Connector connector = AbstractHttpConnection.getCurrentConnection().getConnector();
+            direct=connector instanceof NIOConnector && ((NIOConnector)connector).getUseDirectBuffers() && !(connector instanceof SslConnector);
+            content_length=content.getContentLength();
+        }
+
+
+        // Get the output stream (or writer)
+        OutputStream out =null;
+        boolean written;
+        try
+        {
+            out = response.getOutputStream();
+
+            // has a filter already written to the response?
+            written = out instanceof HttpOutput 
+                ? ((HttpOutput)out).isWritten() 
+                : AbstractHttpConnection.getCurrentConnection().getGenerator().isWritten();
+        }
+        catch(IllegalStateException e) 
+        {
+            out = new WriterOutputStream(response.getWriter());
+            written=true; // there may be data in writer buffer, so assume written
+        }
+        
+        if ( reqRanges == null || !reqRanges.hasMoreElements() || content_length<0)
+        {
+            //  if there were no ranges, send entire entity
+            if (include)
+            {
+                resource.writeTo(out,0,content_length);
+            }
+            else
+            {
+                // See if a direct methods can be used?
+                if (content!=null && !written && out instanceof HttpOutput)
+                {
+                    if (response instanceof Response)
+                    {
+                        writeOptionHeaders(((Response)response).getHttpFields());
+                        ((AbstractHttpConnection.Output)out).sendContent(content);
+                    }
+                    else 
+                    {
+                        Buffer buffer = direct?content.getDirectBuffer():content.getIndirectBuffer();
+                        if (buffer!=null)
+                        {
+                            writeHeaders(response,content,content_length);
+                            ((AbstractHttpConnection.Output)out).sendContent(buffer);
+                        }
+                        else
+                        {
+                            writeHeaders(response,content,content_length);
+                            resource.writeTo(out,0,content_length);
+                        }
+                    }
+                }
+                else 
+                {
+                    // Write headers normally
+                    writeHeaders(response,content,written?-1:content_length);
+
+                    // Write content normally
+                    Buffer buffer = (content==null)?null:content.getIndirectBuffer();
+                    if (buffer!=null)
+                        buffer.writeTo(out);
+                    else
+                        resource.writeTo(out,0,content_length);
+                }
+            }
+        }
+        else
+        {
+            // Parse the satisfiable ranges
+            List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,content_length);
+
+            //  if there are no satisfiable ranges, send 416 response
+            if (ranges==null || ranges.size()==0)
+            {
+                writeHeaders(response, content, content_length);
+                response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
+                response.setHeader(HttpHeaders.CONTENT_RANGE,
+                        InclusiveByteRange.to416HeaderRangeString(content_length));
+                resource.writeTo(out,0,content_length);
+                return;
+            }
+
+            //  if there is only a single valid range (must be satisfiable
+            //  since were here now), send that range with a 216 response
+            if ( ranges.size()== 1)
+            {
+                InclusiveByteRange singleSatisfiableRange =
+                    (InclusiveByteRange)ranges.get(0);
+                long singleLength = singleSatisfiableRange.getSize(content_length);
+                writeHeaders(response,content,singleLength                     );
+                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+                response.setHeader(HttpHeaders.CONTENT_RANGE,
+                        singleSatisfiableRange.toHeaderRangeString(content_length));
+                resource.writeTo(out,singleSatisfiableRange.getFirst(content_length),singleLength);
+                return;
+            }
+
+            //  multiple non-overlapping valid ranges cause a multipart
+            //  216 response which does not require an overall
+            //  content-length header
+            //
+            writeHeaders(response,content,-1);
+            String mimetype=(content.getContentType()==null?null:content.getContentType().toString());
+            if (mimetype==null)
+                LOG.warn("Unknown mimetype for "+request.getRequestURI());
+            MultiPartOutputStream multi = new MultiPartOutputStream(out);
+            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+
+            // If the request has a "Request-Range" header then we need to
+            // send an old style multipart/x-byteranges Content-Type. This
+            // keeps Netscape and acrobat happy. This is what Apache does.
+            String ctp;
+            if (request.getHeader(HttpHeaders.REQUEST_RANGE)!=null)
+                ctp = "multipart/x-byteranges; boundary=";
+            else
+                ctp = "multipart/byteranges; boundary=";
+            response.setContentType(ctp+multi.getBoundary());
+
+            InputStream in=resource.getInputStream();
+            long pos=0;
+
+            // calculate the content-length
+            int length=0;
+            String[] header = new String[ranges.size()];
+            for (int i=0;i<ranges.size();i++)
+            {
+                InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
+                header[i]=ibr.toHeaderRangeString(content_length);
+                length+=
+                    ((i>0)?2:0)+
+                    2+multi.getBoundary().length()+2+
+                    (mimetype==null?0:HttpHeaders.CONTENT_TYPE.length()+2+mimetype.length())+2+
+                    HttpHeaders.CONTENT_RANGE.length()+2+header[i].length()+2+
+                    2+
+                    (ibr.getLast(content_length)-ibr.getFirst(content_length))+1;
+            }
+            length+=2+2+multi.getBoundary().length()+2+2;
+            response.setContentLength(length);
+
+            for (int i=0;i<ranges.size();i++)
+            {
+                InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
+                multi.startPart(mimetype,new String[]{HttpHeaders.CONTENT_RANGE+": "+header[i]});
+
+                long start=ibr.getFirst(content_length);
+                long size=ibr.getSize(content_length);
+                if (in!=null)
+                {
+                    // Handle non cached resource
+                    if (start<pos)
+                    {
+                        in.close();
+                        in=resource.getInputStream();
+                        pos=0;
+                    }
+                    if (pos<start)
+                    {
+                        in.skip(start-pos);
+                        pos=start;
+                    }
+                    IO.copy(in,multi,size);
+                    pos+=size;
+                }
+                else
+                    // Handle cached resource
+                    (resource).writeTo(multi,start,size);
+
+            }
+            if (in!=null)
+                in.close();
+            multi.close();
+        }
+        return;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeHeaders(HttpServletResponse response,HttpContent content,long count)
+    throws IOException
+    {        
+        if (content.getContentType()!=null && response.getContentType()==null)
+            response.setContentType(content.getContentType().toString());
+
+        if (response instanceof Response)
+        {
+            Response r=(Response)response;
+            HttpFields fields = r.getHttpFields();
+
+            if (content.getLastModified()!=null)
+                fields.put(HttpHeaders.LAST_MODIFIED_BUFFER,content.getLastModified());
+            else if (content.getResource()!=null)
+            {
+                long lml=content.getResource().lastModified();
+                if (lml!=-1)
+                    fields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER,lml);
+            }
+
+            if (count != -1)
+                r.setLongContentLength(count);
+
+            writeOptionHeaders(fields);
+            
+            if (_etags)
+                fields.put(HttpHeaders.ETAG_BUFFER,content.getETag());
+        }
+        else
+        {
+            long lml=content.getResource().lastModified();
+            if (lml>=0)
+                response.setDateHeader(HttpHeaders.LAST_MODIFIED,lml);
+
+            if (count != -1)
+            {
+                if (count<Integer.MAX_VALUE)
+                    response.setContentLength((int)count);
+                else
+                    response.setHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(count));
+            }
+
+            writeOptionHeaders(response);
+
+            if (_etags)
+                response.setHeader(HttpHeaders.ETAG,content.getETag().toString());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeOptionHeaders(HttpFields fields) throws IOException
+    {
+        if (_acceptRanges)
+            fields.put(HttpHeaders.ACCEPT_RANGES_BUFFER,HttpHeaderValues.BYTES_BUFFER);
+
+        if (_cacheControl!=null)
+            fields.put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void writeOptionHeaders(HttpServletResponse response) throws IOException
+    {
+        if (_acceptRanges)
+            response.setHeader(HttpHeaders.ACCEPT_RANGES,"bytes");
+
+        if (_cacheControl!=null)
+            response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
+    }
+    
+  
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see javax.servlet.Servlet#destroy()
+     */
+    @Override
+    public void destroy()
+    {
+        if (_cache!=null)
+            _cache.flushCache();
+        super.destroy();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/src/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
new file mode 100644
index 0000000..a89073c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
@@ -0,0 +1,229 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+
+/* ------------------------------------------------------------ */
+/** Error Page Error Handler
+ *
+ * An ErrorHandler that maps exceptions and status codes to URIs for dispatch using
+ * the internal ERROR style of dispatch.
+ *
+ */
+public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler.ErrorPageMapper
+{
+    public final static String GLOBAL_ERROR_PAGE = "org.eclipse.jetty.server.error_page.global";
+
+    protected ServletContext _servletContext;
+    private final Map<String,String> _errorPages= new HashMap<String,String>(); // code or exception to URL
+    private final List<ErrorCodeRange> _errorPageList=new ArrayList<ErrorCodeRange>(); // list of ErrorCode by range
+
+    /* ------------------------------------------------------------ */
+    public ErrorPageErrorHandler()
+    {}
+
+    @Override
+    public String getErrorPage(HttpServletRequest request)
+    {
+        String error_page= null;
+        Class<?> exClass= (Class<?>)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE);
+
+        if (ServletException.class.equals(exClass))
+        {
+            error_page= (String)_errorPages.get(exClass.getName());
+            if (error_page == null)
+            {
+                Throwable th= (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+                while (th instanceof ServletException)
+                    th= ((ServletException)th).getRootCause();
+                if (th != null)
+                    exClass= th.getClass();
+            }
+        }
+
+        while (error_page == null && exClass != null )
+        {
+            error_page= (String)_errorPages.get(exClass.getName());
+            exClass= exClass.getSuperclass();
+        }
+
+        if (error_page == null)
+        {
+            // look for an exact code match
+            Integer code=(Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
+            if (code!=null)
+            {
+                error_page= (String)_errorPages.get(Integer.toString(code));
+
+                // if still not found
+                if ((error_page == null) && (_errorPageList != null))
+                {
+                    // look for an error code range match.
+                    for (int i = 0; i < _errorPageList.size(); i++)
+                    {
+                        ErrorCodeRange errCode = (ErrorCodeRange) _errorPageList.get(i);
+                        if (errCode.isInRange(code))
+                        {
+                            error_page = errCode.getUri();
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        //try new servlet 3.0 global error page
+        if (error_page == null)
+        {
+            error_page = _errorPages.get(GLOBAL_ERROR_PAGE);
+        }
+
+        return error_page;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the errorPages.
+     */
+    public Map<String,String> getErrorPages()
+    {
+        return _errorPages;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param errorPages The errorPages to set. A map of Exception class name  or error code as a string to URI string
+     */
+    public void setErrorPages(Map<String,String> errorPages)
+    {
+        _errorPages.clear();
+        if (errorPages!=null)
+            _errorPages.putAll(errorPages);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add Error Page mapping for an exception class
+     * This method is called as a result of an exception-type element in a web.xml file
+     * or may be called directly
+     * @param exception The exception
+     * @param uri The URI of the error page.
+     */
+    public void addErrorPage(Class<? extends Throwable> exception,String uri)
+    {
+        _errorPages.put(exception.getName(),uri);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add Error Page mapping for an exception class
+     * This method is called as a result of an exception-type element in a web.xml file
+     * or may be called directly
+     * @param exceptionClassName The exception
+     * @param uri The URI of the error page.
+     */
+    public void addErrorPage(String exceptionClassName,String uri)
+    {
+        _errorPages.put(exceptionClassName,uri);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add Error Page mapping for a status code.
+     * This method is called as a result of an error-code element in a web.xml file
+     * or may be called directly
+     * @param code The HTTP status code to match
+     * @param uri The URI of the error page.
+     */
+    public void addErrorPage(int code,String uri)
+    {
+        _errorPages.put(Integer.toString(code),uri);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add Error Page mapping for a status code range.
+     * This method is not available from web.xml and must be called
+     * directly.
+     * @param from The lowest matching status code
+     * @param to The highest matching status code
+     * @param uri The URI of the error page.
+     */
+    public void addErrorPage(int from, int to, String uri)
+    {
+        _errorPageList.add(new ErrorCodeRange(from, to, uri));
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+        _servletContext=ContextHandler.getCurrentContext();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class ErrorCodeRange
+    {
+        private int _from;
+        private int _to;
+        private String _uri;
+
+        ErrorCodeRange(int from, int to, String uri)
+            throws IllegalArgumentException
+        {
+            if (from > to)
+                throw new IllegalArgumentException("from>to");
+
+            _from = from;
+            _to = to;
+            _uri = uri;
+        }
+
+        boolean isInRange(int value)
+        {
+            if ((value >= _from) && (value <= _to))
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        String getUri()
+        {
+            return _uri;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "from: " + _from + ",to: " + _to + ",uri: " + _uri;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/FilterHolder.java b/src/java/org/eclipse/jetty/servlet/FilterHolder.java
new file mode 100644
index 0000000..3b85f60
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/FilterHolder.java
@@ -0,0 +1,259 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletException;
+
+import org.eclipse.jetty.servlet.Holder.Source;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* --------------------------------------------------------------------- */
+/** 
+ * 
+ */
+public class FilterHolder extends Holder<Filter>
+{
+    private static final Logger LOG = Log.getLogger(FilterHolder.class);
+    
+    /* ------------------------------------------------------------ */
+    private transient Filter _filter;
+    private transient Config _config;
+    private transient FilterRegistration.Dynamic _registration;
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor 
+     */
+    public FilterHolder()
+    {
+        this(Source.EMBEDDED);
+    }   
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor 
+     */
+    public FilterHolder(Holder.Source source)
+    {
+        super(source);
+    }   
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor 
+     */
+    public FilterHolder(Class<? extends Filter> filter)
+    {
+        this(Source.EMBEDDED);
+        setHeldClass(filter);
+    }
+
+    /* ---------------------------------------------------------------- */
+    /** Constructor for existing filter.
+     */
+    public FilterHolder(Filter filter)
+    {
+        this(Source.EMBEDDED);
+        setFilter(filter);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void doStart()
+        throws Exception
+    {
+        super.doStart();
+        
+        if (!javax.servlet.Filter.class
+            .isAssignableFrom(_class))
+        {
+            String msg = _class+" is not a javax.servlet.Filter";
+            super.stop();
+            throw new IllegalStateException(msg);
+        }
+
+        if (_filter==null)
+        {
+            try
+            {
+                _filter=((ServletContextHandler.Context)_servletHandler.getServletContext()).createFilter(getHeldClass());
+            }
+            catch (ServletException se)
+            {
+                Throwable cause = se.getRootCause();
+                if (cause instanceof InstantiationException)
+                    throw (InstantiationException)cause;
+                if (cause instanceof IllegalAccessException)
+                    throw (IllegalAccessException)cause;
+                throw se;
+            }
+        }
+        
+        _config=new Config();
+        _filter.init(_config);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void doStop()
+        throws Exception
+    {      
+        if (_filter!=null)
+        {
+            try
+            {
+                destroyInstance(_filter);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+            }
+        }
+        if (!_extInstance)
+            _filter=null;
+        
+        _config=null;
+        super.doStop();   
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroyInstance (Object o)
+        throws Exception
+    {
+        if (o==null)
+            return;
+        Filter f = (Filter)o;
+        f.destroy();
+        getServletHandler().destroyFilter(f);
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized void setFilter(Filter filter)
+    {
+        _filter=filter;
+        _extInstance=true;
+        setHeldClass(filter.getClass());
+        if (getName()==null)
+            setName(filter.getClass().getName());
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Filter getFilter()
+    {
+        return _filter;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return getName();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public FilterRegistration.Dynamic getRegistration()
+    {
+        if (_registration == null)
+            _registration = new Registration();
+        return _registration;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected class Registration extends HolderRegistration implements FilterRegistration.Dynamic
+    {
+        public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... servletNames)
+        {
+            illegalStateIfContextStarted();
+            FilterMapping mapping = new FilterMapping();
+            mapping.setFilterHolder(FilterHolder.this);
+            mapping.setServletNames(servletNames);
+            mapping.setDispatcherTypes(dispatcherTypes);
+            if (isMatchAfter)
+                _servletHandler.addFilterMapping(mapping);
+            else
+                _servletHandler.prependFilterMapping(mapping);
+        }
+
+        public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns)
+        {
+            illegalStateIfContextStarted();
+            FilterMapping mapping = new FilterMapping();
+            mapping.setFilterHolder(FilterHolder.this);
+            mapping.setPathSpecs(urlPatterns);
+            mapping.setDispatcherTypes(dispatcherTypes);
+            if (isMatchAfter)
+                _servletHandler.addFilterMapping(mapping);
+            else
+                _servletHandler.prependFilterMapping(mapping);
+        }
+
+        public Collection<String> getServletNameMappings()
+        {
+            FilterMapping[] mappings =_servletHandler.getFilterMappings();
+            List<String> names=new ArrayList<String>();
+            for (FilterMapping mapping : mappings)
+            {
+                if (mapping.getFilterHolder()!=FilterHolder.this)
+                    continue;
+                String[] servlets=mapping.getServletNames();
+                if (servlets!=null && servlets.length>0)
+                    names.addAll(Arrays.asList(servlets));
+            }
+            return names;
+        }
+
+        public Collection<String> getUrlPatternMappings()
+        {
+            FilterMapping[] mappings =_servletHandler.getFilterMappings();
+            List<String> patterns=new ArrayList<String>();
+            for (FilterMapping mapping : mappings)
+            {
+                if (mapping.getFilterHolder()!=FilterHolder.this)
+                    continue;
+                String[] specs=mapping.getPathSpecs();
+                patterns.addAll(TypeUtil.asList(specs));
+            }
+            return patterns;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    class Config extends HolderConfig implements FilterConfig
+    {
+        /* ------------------------------------------------------------ */
+        public String getFilterName()
+        {
+            return _name;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/FilterMapping.java b/src/java/org/eclipse/jetty/servlet/FilterMapping.java
new file mode 100644
index 0000000..2047451
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/FilterMapping.java
@@ -0,0 +1,276 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import javax.servlet.DispatcherType;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+
+
+public class FilterMapping implements Dumpable
+{
+    /** Dispatch types */
+    public static final int DEFAULT=0;
+    public static final int REQUEST=1;
+    public static final int FORWARD=2;
+    public static final int INCLUDE=4;
+    public static final int ERROR=8;
+    public static final int ASYNC=16;
+    public static final int ALL=31;
+    
+
+    /* ------------------------------------------------------------ */
+    /** Dispatch type from name
+     */
+    public static DispatcherType dispatch(String type)
+    {
+        if ("request".equalsIgnoreCase(type))
+            return DispatcherType.REQUEST;
+        if ("forward".equalsIgnoreCase(type))
+            return DispatcherType.FORWARD;
+        if ("include".equalsIgnoreCase(type))
+            return DispatcherType.INCLUDE;
+        if ("error".equalsIgnoreCase(type))
+            return DispatcherType.ERROR;
+        if ("async".equalsIgnoreCase(type))
+            return DispatcherType.ASYNC;
+        throw new IllegalArgumentException(type);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Dispatch type from name
+     */
+    public static int dispatch(DispatcherType type)
+    {
+    	switch(type)
+    	{
+    	  case REQUEST:
+    		  return REQUEST;
+    	  case ASYNC:
+    		  return ASYNC;
+    	  case FORWARD:
+    		  return FORWARD;
+    	  case INCLUDE:
+    		  return INCLUDE;
+    	  case ERROR:
+    		  return ERROR;
+    	}
+        throw new IllegalArgumentException(type.toString());
+    }
+	
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    
+	
+    private int _dispatches=DEFAULT;
+    private String _filterName;
+    private transient FilterHolder _holder;
+    private String[] _pathSpecs;
+    private String[] _servletNames;
+
+    /* ------------------------------------------------------------ */
+    public FilterMapping()
+    {}
+    
+    /* ------------------------------------------------------------ */
+    /** Check if this filter applies to a path.
+     * @param path The path to check or null to just check type
+     * @param type The type of request: __REQUEST,__FORWARD,__INCLUDE, __ASYNC or __ERROR.
+     * @return True if this filter applies
+     */
+    boolean appliesTo(String path, int type)
+    {
+        if (appliesTo(type))
+        {
+            for (int i=0;i<_pathSpecs.length;i++)
+                if (_pathSpecs[i]!=null &&  PathMap.match(_pathSpecs[i], path,true))
+                    return true;
+        }
+
+        return false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Check if this filter applies to a particular dispatch type.
+     * @param type The type of request:
+     *      {@link Handler#REQUEST}, {@link Handler#FORWARD}, {@link Handler#INCLUDE} or {@link Handler#ERROR}.
+     * @return <code>true</code> if this filter applies
+     */
+    boolean appliesTo(int type)
+    {
+    	if (_dispatches==0)
+    		return type==REQUEST || type==ASYNC && _holder.isAsyncSupported();
+        return (_dispatches&type)!=0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the filterName.
+     */
+    public String getFilterName()
+    {
+        return _filterName;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the holder.
+     */
+    FilterHolder getFilterHolder()
+    {
+        return _holder;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the pathSpec.
+     */
+    public String[] getPathSpecs()
+    {
+        return _pathSpecs;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) 
+    {
+        _dispatches=DEFAULT;
+        if (dispatcherTypes!=null)
+        {
+            if (dispatcherTypes.contains(DispatcherType.ERROR)) 
+                _dispatches|=ERROR;
+            if (dispatcherTypes.contains(DispatcherType.FORWARD)) 
+                _dispatches|=FORWARD;
+            if (dispatcherTypes.contains(DispatcherType.INCLUDE)) 
+                _dispatches|=INCLUDE;
+            if (dispatcherTypes.contains(DispatcherType.REQUEST)) 
+                _dispatches|=REQUEST;
+            if (dispatcherTypes.contains(DispatcherType.ASYNC)) 
+                _dispatches|=ASYNC;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param dispatches The dispatches to set.
+     * @see #DEFAULT
+     * @see #REQUEST
+     * @see #ERROR
+     * @see #FORWARD
+     * @see #INCLUDE
+     */
+    public void setDispatches(int dispatches)
+    {
+        _dispatches = dispatches;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filterName The filterName to set.
+     */
+    public void setFilterName(String filterName)
+    {
+        _filterName = filterName;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param holder The holder to set.
+     */
+    void setFilterHolder(FilterHolder holder)
+    {
+        _holder = holder;
+        setFilterName(holder.getName());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpecs The Path specifications to which this filter should be mapped. 
+     */
+    public void setPathSpecs(String[] pathSpecs)
+    {
+        _pathSpecs = pathSpecs;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpec The pathSpec to set.
+     */
+    public void setPathSpec(String pathSpec)
+    {
+        _pathSpecs = new String[]{pathSpec};
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletName.
+     */
+    public String[] getServletNames()
+    {
+        return _servletNames;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletNames Maps the {@link #setFilterName(String) named filter} to multiple servlets
+     * @see #setServletName
+     */
+    public void setServletNames(String[] servletNames)
+    {
+        _servletNames = servletNames;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletName Maps the {@link #setFilterName(String) named filter} to a single servlet
+     * @see #setServletNames
+     */
+    public void setServletName(String servletName)
+    {
+        _servletNames = new String[]{servletName};
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return 
+        TypeUtil.asList(_pathSpecs)+"/"+
+        TypeUtil.asList(_servletNames)+"=="+
+        _dispatches+"=>"+
+        _filterName; 
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        out.append(String.valueOf(this)).append("\n");
+    }
+
+    /* ------------------------------------------------------------ */
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }    
+}
diff --git a/src/java/org/eclipse/jetty/servlet/Holder.java b/src/java/org/eclipse/jetty/servlet/Holder.java
new file mode 100644
index 0000000..f46211a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/Holder.java
@@ -0,0 +1,408 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Registration;
+import javax.servlet.ServletContext;
+import javax.servlet.UnavailableException;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* --------------------------------------------------------------------- */
+/** 
+ * 
+ */
+public class Holder<T> extends AbstractLifeCycle implements Dumpable
+{
+    public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
+    final private Source _source;
+    private static final Logger LOG = Log.getLogger(Holder.class);
+
+    protected transient Class<? extends T> _class;
+    protected final Map<String,String> _initParams=new HashMap<String,String>(3);
+    protected String _className;
+    protected String _displayName;
+    protected boolean _extInstance;
+    protected boolean _asyncSupported;
+
+    /* ---------------------------------------------------------------- */
+    protected String _name;
+    protected ServletHandler _servletHandler;
+
+    /* ---------------------------------------------------------------- */
+    protected Holder(Source source)
+    {
+        _source=source;
+        switch(_source)
+        {
+            case JAVAX_API:
+            case DESCRIPTOR:
+            case ANNOTATION:
+                _asyncSupported=false;
+                break;
+            default:
+                _asyncSupported=true;
+        }
+    }
+    
+    public Source getSource()
+    {
+        return _source;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if this holder was created for a specific instance.
+     */
+    public boolean isInstance()
+    {
+        return _extInstance;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    public void doStart()
+        throws Exception
+    {
+        //if no class already loaded and no classname, make servlet permanently unavailable
+        if (_class==null && (_className==null || _className.equals("")))
+            throw new UnavailableException("No class for Servlet or Filter for "+_name);
+        
+        //try to load class
+        if (_class==null)
+        {
+            try
+            {
+                _class=Loader.loadClass(Holder.class, _className);
+                if(LOG.isDebugEnabled())
+                    LOG.debug("Holding {}",_class);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+                throw new UnavailableException(e.getMessage());
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void doStop()
+        throws Exception
+    {
+        if (!_extInstance)
+            _class=null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getClassName()
+    {
+        return _className;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Class<? extends T> getHeldClass()
+    {
+        return _class;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getDisplayName()
+    {
+        return _displayName;
+    }
+
+    /* ---------------------------------------------------------------- */
+    public String getInitParameter(String param)
+    {
+        if (_initParams==null)
+            return null;
+        return (String)_initParams.get(param);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Enumeration getInitParameterNames()
+    {
+        if (_initParams==null)
+            return Collections.enumeration(Collections.EMPTY_LIST);
+        return Collections.enumeration(_initParams.keySet());
+    }
+
+    /* ---------------------------------------------------------------- */
+    public Map<String,String> getInitParameters()
+    {
+        return _initParams;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getName()
+    {
+        return _name;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletHandler.
+     */
+    public ServletHandler getServletHandler()
+    {
+        return _servletHandler;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void destroyInstance(Object instance)
+    throws Exception
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param className The className to set.
+     */
+    public void setClassName(String className)
+    {
+        _className = className;
+        _class=null;
+        if (_name==null)
+            _name=className+"-"+Integer.toHexString(this.hashCode());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param held The class to hold
+     */
+    public void setHeldClass(Class<? extends T> held)
+    {
+        _class=held;
+        if (held!=null)
+        {
+            _className=held.getName();
+            if (_name==null)
+                _name=held.getName()+"-"+Integer.toHexString(this.hashCode());
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setDisplayName(String name)
+    {
+        _displayName=name;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setInitParameter(String param,String value)
+    {
+        _initParams.put(param,value);
+    }
+    
+    /* ---------------------------------------------------------------- */
+    public void setInitParameters(Map<String,String> map)
+    {
+        _initParams.clear();
+        _initParams.putAll(map);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * The name is a primary key for the held object.
+     * Ensure that the name is set BEFORE adding a Holder
+     * (eg ServletHolder or FilterHolder) to a ServletHandler.
+     * @param name The name to set.
+     */
+    public void setName(String name)
+    {
+        _name = name;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletHandler The {@link ServletHandler} that will handle requests dispatched to this servlet.
+     */
+    public void setServletHandler(ServletHandler servletHandler)
+    {
+        _servletHandler = servletHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setAsyncSupported(boolean suspendable)
+    {
+        _asyncSupported=suspendable;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isAsyncSupported()
+    {
+        return _asyncSupported;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return _name;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void illegalStateIfContextStarted()
+    {
+        if (_servletHandler!=null)
+        {
+            ContextHandler.Context context=(ContextHandler.Context)_servletHandler.getServletContext();
+            if (context!=null && context.getContextHandler().isStarted())
+                throw new IllegalStateException("Started");
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        out.append(_name).append("==").append(_className)
+        .append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
+        AggregateLifeCycle.dump(out,indent,_initParams.entrySet());
+    }
+
+    /* ------------------------------------------------------------ */
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }    
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected class HolderConfig 
+    {   
+        
+        /* -------------------------------------------------------- */
+        public ServletContext getServletContext()
+        {
+            return _servletHandler.getServletContext();
+        }
+
+        /* -------------------------------------------------------- */
+        public String getInitParameter(String param)
+        {
+            return Holder.this.getInitParameter(param);
+        }
+    
+        /* -------------------------------------------------------- */
+        public Enumeration getInitParameterNames()
+        {
+            return Holder.this.getInitParameterNames();
+        }
+    }
+
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    protected class HolderRegistration implements Registration.Dynamic
+    {
+        public void setAsyncSupported(boolean isAsyncSupported)
+        {
+            illegalStateIfContextStarted();
+            Holder.this.setAsyncSupported(isAsyncSupported);
+        }
+
+        public void setDescription(String description)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug(this+" is "+description);
+        }
+
+        public String getClassName()
+        {
+            return Holder.this.getClassName();
+        }
+
+        public String getInitParameter(String name)
+        {
+            return Holder.this.getInitParameter(name);
+        }
+
+        public Map<String, String> getInitParameters()
+        {
+            return Holder.this.getInitParameters();
+        }
+
+        public String getName()
+        {
+            return Holder.this.getName();
+        }
+
+        public boolean setInitParameter(String name, String value)
+        {
+            illegalStateIfContextStarted();
+            if (name == null) {
+                throw new IllegalArgumentException("init parameter name required");
+            }
+            if (value == null) {
+                throw new IllegalArgumentException("non-null value required for init parameter " + name);
+            }
+            if (Holder.this.getInitParameter(name)!=null)
+                return false;
+            Holder.this.setInitParameter(name,value);
+            return true;
+        }
+
+        public Set<String> setInitParameters(Map<String, String> initParameters)
+        {
+            illegalStateIfContextStarted();
+            Set<String> clash=null;
+            for (Map.Entry<String, String> entry : initParameters.entrySet())
+            {
+                if (entry.getKey() == null) {
+                    throw new IllegalArgumentException("init parameter name required");
+                }
+                if (entry.getValue() == null) {
+                    throw new IllegalArgumentException("non-null value required for init parameter " + entry.getKey());
+                }
+                if (Holder.this.getInitParameter(entry.getKey())!=null)
+                {
+                    if (clash==null)
+                        clash=new HashSet<String>();
+                    clash.add(entry.getKey());
+                }
+            }
+            if (clash!=null)
+                return clash;
+            Holder.this.getInitParameters().putAll(initParameters);
+            return Collections.emptySet();
+        }
+        
+        
+    }
+}
+
+
+
+
+
diff --git a/src/java/org/eclipse/jetty/servlet/Invoker.java b/src/java/org/eclipse/jetty/servlet/Invoker.java
new file mode 100644
index 0000000..c3e55f6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/Invoker.java
@@ -0,0 +1,314 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**  Dynamic Servlet Invoker.  
+ * This servlet invokes anonymous servlets that have not been defined   
+ * in the web.xml or by other means. The first element of the pathInfo  
+ * of a request passed to the envoker is treated as a servlet name for  
+ * an existing servlet, or as a class name of a new servlet.            
+ * This servlet is normally mapped to /servlet/*                        
+ * This servlet support the following initParams:                       
+ * <PRE>                                                                     
+ *  nonContextServlets       If false, the invoker can only load        
+ *                           servlets from the contexts classloader.    
+ *                           This is false by default and setting this  
+ *                           to true may have security implications.    
+ *                                                                      
+ *  verbose                  If true, log dynamic loads                 
+ *                                                                      
+ *  *                        All other parameters are copied to the     
+ *                           each dynamic servlet as init parameters    
+ * </PRE>
+ * @version $Id: Invoker.java 4780 2009-03-17 15:36:08Z jesse $
+ * 
+ */
+public class Invoker extends HttpServlet
+{
+    private static final Logger LOG = Log.getLogger(Invoker.class);
+
+
+    private ContextHandler _contextHandler;
+    private ServletHandler _servletHandler;
+    private Map.Entry _invokerEntry;
+    private Map _parameters;
+    private boolean _nonContextServlets;
+    private boolean _verbose;
+        
+    /* ------------------------------------------------------------ */
+    public void init()
+    {
+        ServletContext config=getServletContext();
+        _contextHandler=((ContextHandler.Context)config).getContextHandler();
+
+        Handler handler=_contextHandler.getHandler();
+        while (handler!=null && !(handler instanceof ServletHandler) && (handler instanceof HandlerWrapper))
+            handler=((HandlerWrapper)handler).getHandler();
+        _servletHandler = (ServletHandler)handler;
+        Enumeration e = getInitParameterNames();
+        while(e.hasMoreElements())
+        {
+            String param=(String)e.nextElement();
+            String value=getInitParameter(param);
+            String lvalue=value.toLowerCase(Locale.ENGLISH);
+            if ("nonContextServlets".equals(param))
+            {
+                _nonContextServlets=value.length()>0 && lvalue.startsWith("t");
+            }
+            if ("verbose".equals(param))
+            {
+                _verbose=value.length()>0 && lvalue.startsWith("t");
+            }
+            else
+            {
+                if (_parameters==null)
+                    _parameters=new HashMap();
+                _parameters.put(param,value);
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void service(HttpServletRequest request, HttpServletResponse response)
+	throws ServletException, IOException
+    {
+        // Get the requested path and info
+        boolean included=false;
+        String servlet_path=(String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
+        if (servlet_path==null)
+            servlet_path=request.getServletPath();
+        else
+            included=true;
+        String path_info = (String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
+        if (path_info==null)
+            path_info=request.getPathInfo();
+        
+        // Get the servlet class
+        String servlet = path_info;
+        if (servlet==null || servlet.length()<=1 )
+        {
+            response.sendError(404);
+            return;
+        }
+        
+        
+        int i0=servlet.charAt(0)=='/'?1:0;
+        int i1=servlet.indexOf('/',i0);
+        servlet=i1<0?servlet.substring(i0):servlet.substring(i0,i1);
+
+        // look for a named holder
+        ServletHolder[] holders = _servletHandler.getServlets();
+        ServletHolder holder = getHolder (holders, servlet);
+       
+        if (holder!=null)
+        {
+            // Found a named servlet (from a user's web.xml file) so
+            // now we add a mapping for it
+            if (LOG.isDebugEnabled())
+                LOG.debug("Adding servlet mapping for named servlet:"+servlet+":"+URIUtil.addPaths(servlet_path,servlet)+"/*");
+            ServletMapping mapping = new ServletMapping();
+            mapping.setServletName(servlet);
+            mapping.setPathSpec(URIUtil.addPaths(servlet_path,servlet)+"/*");
+            _servletHandler.setServletMappings((ServletMapping[])LazyList.addToArray(_servletHandler.getServletMappings(), mapping, ServletMapping.class));
+        }
+        else
+        {
+            // look for a class mapping
+            if (servlet.endsWith(".class"))
+                servlet=servlet.substring(0,servlet.length()-6);
+            if (servlet==null || servlet.length()==0)
+            {
+                response.sendError(404);
+                return;
+            }   
+        
+            synchronized(_servletHandler)
+            {
+                // find the entry for the invoker (me)
+                 _invokerEntry=_servletHandler.getHolderEntry(servlet_path);
+            
+                // Check for existing mapping (avoid threaded race).
+                String path=URIUtil.addPaths(servlet_path,servlet);
+                Map.Entry entry = _servletHandler.getHolderEntry(path);
+               
+                if (entry!=null && !entry.equals(_invokerEntry))
+                {
+                    // Use the holder
+                    holder=(ServletHolder)entry.getValue();
+                }
+                else
+                {
+                    // Make a holder
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("Making new servlet="+servlet+" with path="+path+"/*");
+                    holder=_servletHandler.addServletWithMapping(servlet, path+"/*");
+                    
+                    if (_parameters!=null)
+                        holder.setInitParameters(_parameters);
+                    
+                    try {holder.start();}
+                    catch (Exception e)
+                    {
+                        LOG.debug(e);
+                        throw new UnavailableException(e.toString());
+                    }
+                    
+                    // Check it is from an allowable classloader
+                    if (!_nonContextServlets)
+                    {
+                        Object s=holder.getServlet();
+                        
+                        if (_contextHandler.getClassLoader()!=
+                            s.getClass().getClassLoader())
+                        {
+                            try 
+                            {
+                                holder.stop();
+                            } 
+                            catch (Exception e) 
+                            {
+                                LOG.ignore(e);
+                            }
+                            
+                            LOG.warn("Dynamic servlet "+s+
+                                         " not loaded from context "+
+                                         request.getContextPath());
+                            throw new UnavailableException("Not in context");
+                        }
+                    }
+
+                    if (_verbose && LOG.isDebugEnabled())
+                        LOG.debug("Dynamic load '"+servlet+"' at "+path);
+                }
+            }
+        }
+        
+        if (holder!=null)
+        {
+            final Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+            holder.handle(baseRequest,
+                    new InvokedRequest(request,included,servlet,servlet_path,path_info),
+                          response);
+        }
+        else
+        {
+            LOG.info("Can't find holder for servlet: "+servlet);
+            response.sendError(404);
+        }
+            
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    class InvokedRequest extends HttpServletRequestWrapper
+    {
+        String _servletPath;
+        String _pathInfo;
+        boolean _included;
+        
+        /* ------------------------------------------------------------ */
+        InvokedRequest(HttpServletRequest request,
+                boolean included,
+                String name,
+                String servletPath,
+                String pathInfo)
+        {
+            super(request);
+            _included=included;
+            _servletPath=URIUtil.addPaths(servletPath,name);
+            _pathInfo=pathInfo.substring(name.length()+1);
+            if (_pathInfo.length()==0)
+                _pathInfo=null;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public String getServletPath()
+        {
+            if (_included)
+                return super.getServletPath();
+            return _servletPath;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public String getPathInfo()
+        {
+            if (_included)
+                return super.getPathInfo();
+            return _pathInfo;
+        }
+        
+        /* ------------------------------------------------------------ */
+        public Object getAttribute(String name)
+        {
+            if (_included)
+            {
+                if (name.equals(Dispatcher.INCLUDE_REQUEST_URI))
+                    return URIUtil.addPaths(URIUtil.addPaths(getContextPath(),_servletPath),_pathInfo);
+                if (name.equals(Dispatcher.INCLUDE_PATH_INFO))
+                    return _pathInfo;
+                if (name.equals(Dispatcher.INCLUDE_SERVLET_PATH))
+                    return _servletPath;
+            }
+            return super.getAttribute(name);
+        }
+    }
+    
+    
+    private ServletHolder getHolder(ServletHolder[] holders, String servlet)
+    {
+        if (holders == null)
+            return null;
+       
+        ServletHolder holder = null;
+        for (int i=0; holder==null && i<holders.length; i++)
+        {
+            if (holders[i].getName().equals(servlet))
+            {
+                holder = holders[i];
+            }
+        }
+        return holder;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/JspPropertyGroupServlet.java b/src/java/org/eclipse/jetty/servlet/JspPropertyGroupServlet.java
new file mode 100644
index 0000000..f2ec2f3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/JspPropertyGroupServlet.java
@@ -0,0 +1,146 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.resource.Resource;
+
+
+/* ------------------------------------------------------------ */
+/** Servlet handling JSP Property Group mappings
+ * <p>
+ * This servlet is mapped to by any URL pattern for a JSP property group. 
+ * Resources handled by this servlet that are not directories will be passed
+ * directly to the JSP servlet.    Resources that are directories will be 
+ * passed directly to the default servlet.
+ */
+public class JspPropertyGroupServlet extends GenericServlet
+{
+    private static final long serialVersionUID = 3681783214726776945L;
+    
+    public final static String NAME = "__org.eclipse.jetty.servlet.JspPropertyGroupServlet__";
+    private final ServletHandler _servletHandler;
+    private final ContextHandler _contextHandler;
+    private ServletHolder _dftServlet;
+    private ServletHolder _jspServlet;
+    private boolean _starJspMapped;
+    
+    public JspPropertyGroupServlet(ContextHandler context, ServletHandler servletHandler)
+    {
+        _contextHandler=context;
+        _servletHandler=servletHandler;        
+    }
+    
+    @Override
+    public void init() throws ServletException
+    {            
+        String jsp_name = "jsp";
+        ServletMapping servlet_mapping =_servletHandler.getServletMapping("*.jsp");
+        if (servlet_mapping!=null)
+        {
+            _starJspMapped=true;
+           
+            //now find the jsp servlet, ignoring the mapping that is for ourself
+            ServletMapping[] mappings = _servletHandler.getServletMappings();
+            for (ServletMapping m:mappings)
+            {
+                String[] paths = m.getPathSpecs();
+                if (paths!=null)
+                {
+                    for (String path:paths)
+                    {
+                        if ("*.jsp".equals(path) && !NAME.equals(m.getServletName()))
+                            servlet_mapping = m;
+                    }
+                }
+            }
+            
+            jsp_name=servlet_mapping.getServletName();
+        }
+        _jspServlet=_servletHandler.getServlet(jsp_name);
+        
+        String dft_name="default";
+        ServletMapping default_mapping=_servletHandler.getServletMapping("/");
+        if (default_mapping!=null)
+            dft_name=default_mapping.getServletName();
+        _dftServlet=_servletHandler.getServlet(dft_name);
+    }
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
+    {           
+        HttpServletRequest request = null;
+        if (req instanceof HttpServletRequest)
+            request = (HttpServletRequest)req;
+        else
+            throw new ServletException("Request not HttpServletRequest");
+
+        String servletPath=null;
+        String pathInfo=null;
+        if (request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI)!=null)
+        {
+            servletPath=(String)request.getAttribute(Dispatcher.INCLUDE_SERVLET_PATH);
+            pathInfo=(String)request.getAttribute(Dispatcher.INCLUDE_PATH_INFO);
+            if (servletPath==null)
+            {
+                servletPath=request.getServletPath();
+                pathInfo=request.getPathInfo();
+            }
+        }
+        else
+        {
+            servletPath = request.getServletPath();
+            pathInfo = request.getPathInfo();
+        }
+        
+        String pathInContext=URIUtil.addPaths(servletPath,pathInfo);
+        
+        if (pathInContext.endsWith("/"))
+        {
+            _dftServlet.getServlet().service(req,res);
+        }
+        else if (_starJspMapped && pathInContext.toLowerCase().endsWith(".jsp"))
+        {
+            _jspServlet.getServlet().service(req,res);
+        }
+        else
+        {
+         
+            Resource resource = _contextHandler.getResource(pathInContext);
+            if (resource!=null && resource.isDirectory())
+                _dftServlet.getServlet().service(req,res);
+            else
+                _jspServlet.getServlet().service(req,res);
+        }
+        
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlet/NoJspServlet.java b/src/java/org/eclipse/jetty/servlet/NoJspServlet.java
new file mode 100644
index 0000000..8a9ff5b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/NoJspServlet.java
@@ -0,0 +1,45 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class NoJspServlet extends HttpServlet
+{
+    private boolean _warned;
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
+    {
+        if (!_warned)
+            getServletContext().log("No JSP support.  Check that JSP jars are in lib/jsp and that the JSP option has been specified to start.jar");
+        _warned=true;
+
+        response.sendError(500,"JSP support not configured");
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/src/java/org/eclipse/jetty/servlet/ServletContextHandler.java
new file mode 100644
index 0000000..314b321
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/ServletContextHandler.java
@@ -0,0 +1,1292 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+import javax.servlet.descriptor.JspPropertyGroupDescriptor;
+import javax.servlet.descriptor.TaglibDescriptor;
+
+import org.eclipse.jetty.security.ConstraintAware;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.security.Constraint;
+
+
+/* ------------------------------------------------------------ */
+/** Servlet Context.
+ * This extension to the ContextHandler allows for
+ * simple construction of a context with ServletHandler and optionally
+ * session and security handlers, et.<pre>
+ *   new ServletContext("/context",Context.SESSIONS|Context.NO_SECURITY);
+ * </pre>
+ * <p/>
+ * This class should have been called ServletContext, but this would have
+ * cause confusion with {@link ServletContext}.
+ */
+public class ServletContextHandler extends ContextHandler
+{   
+    public final static int SESSIONS=1;
+    public final static int SECURITY=2;
+    public final static int NO_SESSIONS=0;
+    public final static int NO_SECURITY=0;
+
+    protected final List<Decorator> _decorators= new ArrayList<Decorator>();
+    protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass=org.eclipse.jetty.security.ConstraintSecurityHandler.class;
+    protected SessionHandler _sessionHandler;
+    protected SecurityHandler _securityHandler;
+    protected ServletHandler _servletHandler;
+    protected HandlerWrapper _wrapper;
+    protected int _options;
+    protected JspConfigDescriptor _jspConfig;
+    protected Object _restrictedContextListeners;
+    private boolean _restrictListeners = true;
+
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler()
+    {
+        this(null,null,null,null,null);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(int options)
+    {
+        this(null,null,options);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(HandlerContainer parent, String contextPath)
+    {
+        this(parent,contextPath,null,null,null,null);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(HandlerContainer parent, String contextPath, int options)
+    {
+        this(parent,contextPath,null,null,null,null);
+        _options=options;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(HandlerContainer parent, String contextPath, boolean sessions, boolean security)
+    {
+        this(parent,contextPath,(sessions?SESSIONS:0)|(security?SECURITY:0));
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(HandlerContainer parent, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
+    {   
+        this(parent,null,sessionHandler,securityHandler,servletHandler,errorHandler);
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
+    {   
+        super((ContextHandler.Context)null);
+        _scontext = new Context();
+        _sessionHandler = sessionHandler;
+        _securityHandler = securityHandler;
+        _servletHandler = servletHandler;
+            
+        if (errorHandler!=null)
+            setErrorHandler(errorHandler);
+
+        if (contextPath!=null)
+            setContextPath(contextPath);
+
+        if (parent instanceof HandlerWrapper)
+            ((HandlerWrapper)parent).setHandler(this);
+        else if (parent instanceof HandlerCollection)
+            ((HandlerCollection)parent).addHandler(this);
+    }    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.handler.ContextHandler#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        if (_decorators != null)
+            _decorators.clear();
+        if (_wrapper != null)
+            _wrapper.setHandler(null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the defaultSecurityHandlerClass.
+     * @return the defaultSecurityHandlerClass
+     */
+    public Class<? extends SecurityHandler> getDefaultSecurityHandlerClass()
+    {
+        return _defaultSecurityHandlerClass;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the defaultSecurityHandlerClass.
+     * @param defaultSecurityHandlerClass the defaultSecurityHandlerClass to set
+     */
+    public void setDefaultSecurityHandlerClass(Class<? extends SecurityHandler> defaultSecurityHandlerClass)
+    {
+        _defaultSecurityHandlerClass = defaultSecurityHandlerClass;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected SessionHandler newSessionHandler()
+    {
+        return new SessionHandler();
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected SecurityHandler newSecurityHandler()
+    {
+        try
+        {
+            return (SecurityHandler)_defaultSecurityHandlerClass.newInstance();
+        }
+        catch(Exception e)
+        {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected ServletHandler newServletHandler()
+    {
+        return new ServletHandler();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Finish constructing handlers and link them together.
+     * 
+     * @see org.eclipse.jetty.server.handler.ContextHandler#startContext()
+     */
+    protected void startContext() throws Exception
+    {
+        // force creation of missing handlers.
+        getSessionHandler();
+        getSecurityHandler();
+        getServletHandler();
+        
+        Handler handler = _servletHandler;
+        if (_securityHandler!=null)
+        {
+            _securityHandler.setHandler(handler);
+            handler=_securityHandler;
+        }
+        
+        if (_sessionHandler!=null)
+        {
+            _sessionHandler.setHandler(handler);
+            handler=_sessionHandler;
+        }
+        
+        // skip any wrapped handlers 
+        _wrapper=this;
+        while (_wrapper!=handler && _wrapper.getHandler() instanceof HandlerWrapper)
+            _wrapper=(HandlerWrapper)_wrapper.getHandler();
+        
+        // if we are not already linked
+        if (_wrapper!=handler)
+        {
+            if (_wrapper.getHandler()!=null )
+                throw new IllegalStateException("!ScopedHandler");
+            _wrapper.setHandler(handler);
+        }
+        
+    	super.startContext();
+
+    	// OK to Initialize servlet handler now
+    	if (_servletHandler != null && _servletHandler.isStarted())
+    	{
+    	    for (int i=_decorators.size()-1;i>=0; i--)
+    	    {
+    	        Decorator decorator = _decorators.get(i);
+                if (_servletHandler.getFilters()!=null)
+                    for (FilterHolder holder:_servletHandler.getFilters())
+                        decorator.decorateFilterHolder(holder);
+    	        if(_servletHandler.getServlets()!=null)
+    	            for (ServletHolder holder:_servletHandler.getServlets())
+    	                decorator.decorateServletHolder(holder);
+    	    }   
+    	        
+    	    _servletHandler.initialize();
+    	}
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the securityHandler.
+     */
+    public SecurityHandler getSecurityHandler()
+    {
+        if (_securityHandler==null && (_options&SECURITY)!=0 && !isStarted()) 
+            _securityHandler=newSecurityHandler();
+        
+        return _securityHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletHandler.
+     */
+    public ServletHandler getServletHandler()
+    {
+        if (_servletHandler==null && !isStarted()) 
+            _servletHandler=newServletHandler();
+        return _servletHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the sessionHandler.
+     */
+    public SessionHandler getSessionHandler()
+    {
+        if (_sessionHandler==null && (_options&SESSIONS)!=0 && !isStarted()) 
+            _sessionHandler=newSessionHandler();
+        return _sessionHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a servlet.
+     */
+    public ServletHolder addServlet(String className,String pathSpec)
+    {
+        return getServletHandler().addServletWithMapping(className, pathSpec);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a servlet.
+     */
+    public ServletHolder addServlet(Class<? extends Servlet> servlet,String pathSpec)
+    {
+        return getServletHandler().addServletWithMapping(servlet.getName(), pathSpec);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a servlet.
+     */
+    public void addServlet(ServletHolder servlet,String pathSpec)
+    {
+        getServletHandler().addServletWithMapping(servlet, pathSpec);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a filter
+     */
+    public void addFilter(FilterHolder holder,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        getServletHandler().addFilterWithMapping(holder,pathSpec,dispatches);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** convenience method to add a filter
+     */
+    public FilterHolder addFilter(Class<? extends Filter> filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** convenience method to add a filter
+     */
+    public FilterHolder addFilter(String filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
+    }
+
+    /**
+     * notification that a ServletRegistration has been created so we can track the annotations
+     * @param holder new holder created through the api.
+     * @return the ServletRegistration.Dynamic
+     */
+    protected ServletRegistration.Dynamic dynamicHolderAdded(ServletHolder holder) {
+        return holder.getRegistration();
+    }
+
+    /**
+     * delegate for ServletContext.declareRole method
+     * @param roleNames role names to add
+     */
+    protected void addRoles(String... roleNames) {
+        //Get a reference to the SecurityHandler, which must be ConstraintAware
+        if (_securityHandler != null && _securityHandler instanceof ConstraintAware)
+        {
+            HashSet<String> union = new HashSet<String>();
+            Set<String> existing = ((ConstraintAware)_securityHandler).getRoles();
+            if (existing != null)
+                union.addAll(existing);
+            union.addAll(Arrays.asList(roleNames));
+            ((ConstraintSecurityHandler)_securityHandler).setRoles(union);
+        }
+    }
+
+    /**
+     * Delegate for ServletRegistration.Dynamic.setServletSecurity method
+     * @param registration ServletRegistration.Dynamic instance that setServletSecurity was called on
+     * @param servletSecurityElement new security info
+     * @return the set of exact URL mappings currently associated with the registration that are also present in the web.xml
+     * security constraints and thus will be unaffected by this call.
+     */
+    public Set<String> setServletSecurity(ServletRegistration.Dynamic registration, ServletSecurityElement servletSecurityElement)
+    {
+        //Default implementation is to just accept them all. If using a webapp, then this behaviour is overridden in WebAppContext.setServletSecurity       
+        Collection<String> pathSpecs = registration.getMappings();
+        if (pathSpecs != null)
+        {
+            for (String pathSpec:pathSpecs)
+            {
+                List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
+                for (ConstraintMapping m:mappings)
+                    ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
+            }
+        }
+        return Collections.emptySet();
+    }
+
+
+    
+    public void restrictEventListener (EventListener e)
+    {
+        if (_restrictListeners && e instanceof ServletContextListener)
+            _restrictedContextListeners = LazyList.add(_restrictedContextListeners, e);
+    }
+
+    public boolean isRestrictListeners() {
+        return _restrictListeners;
+    }
+
+    public void setRestrictListeners(boolean restrictListeners) {
+        this._restrictListeners = restrictListeners;
+    }
+
+    public void callContextInitialized(ServletContextListener l, ServletContextEvent e)
+    {
+        try
+        {
+            //toggle state of the dynamic API so that the listener cannot use it
+            if (LazyList.contains(_restrictedContextListeners, l))
+                this.getServletContext().setEnabled(false);
+            
+            super.callContextInitialized(l, e);
+        }
+        finally
+        {
+            //untoggle the state of the dynamic API
+            this.getServletContext().setEnabled(true);
+        }
+    }
+
+    
+    public void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
+    {
+        super.callContextDestroyed(l, e);
+    }
+
+  
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param sessionHandler The sessionHandler to set.
+     */
+    public void setSessionHandler(SessionHandler sessionHandler)
+    {
+        if (isStarted())
+            throw new IllegalStateException("STARTED");
+
+        _sessionHandler = sessionHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param securityHandler The {@link SecurityHandler} to set on this context.
+     */
+    public void setSecurityHandler(SecurityHandler securityHandler)
+    {
+        if (isStarted())
+            throw new IllegalStateException("STARTED");
+
+        _securityHandler = securityHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletHandler The servletHandler to set.
+     */
+    public void setServletHandler(ServletHandler servletHandler)
+    {
+        if (isStarted())
+            throw new IllegalStateException("STARTED");
+
+        _servletHandler = servletHandler;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The decorator list used to resource inject new Filters, Servlets and EventListeners
+     */
+    public List<Decorator> getDecorators()
+    {
+        return Collections.unmodifiableList(_decorators);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param decorators The lis of {@link Decorator}s
+     */
+    public void setDecorators(List<Decorator> decorators)
+    {
+        _decorators.clear();
+        _decorators.addAll(decorators);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param decorator The decorator to add
+     */
+    public void addDecorator(Decorator decorator)
+    {
+        _decorators.add(decorator);
+    }
+
+    /* ------------------------------------------------------------ */
+    void destroyServlet(Servlet servlet)
+    {
+        for (Decorator decorator : _decorators)
+            decorator.destroyServletInstance(servlet);
+    }
+
+    /* ------------------------------------------------------------ */
+    void destroyFilter(Filter filter)
+    {
+        for (Decorator decorator : _decorators)
+            decorator.destroyFilterInstance(filter);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static class JspPropertyGroup implements JspPropertyGroupDescriptor
+    {
+        private List<String> _urlPatterns = new ArrayList<String>();
+        private String _elIgnored;
+        private String _pageEncoding;
+        private String _scriptingInvalid;
+        private String _isXml;
+        private List<String> _includePreludes = new ArrayList<String>();
+        private List<String> _includeCodas = new ArrayList<String>();
+        private String _deferredSyntaxAllowedAsLiteral;
+        private String _trimDirectiveWhitespaces;
+        private String _defaultContentType;
+        private String _buffer;
+        private String _errorOnUndeclaredNamespace;
+        
+        
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getUrlPatterns()
+         */
+        public Collection<String> getUrlPatterns()
+        {
+            return new ArrayList<String>(_urlPatterns); // spec says must be a copy
+        }
+        
+        public void addUrlPattern (String s)
+        {
+            if (!_urlPatterns.contains(s))
+                _urlPatterns.add(s);
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getElIgnored()
+         */
+        public String getElIgnored()
+        {
+            return _elIgnored;
+        }
+        
+        public void setElIgnored (String s)
+        {
+            _elIgnored = s;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getPageEncoding()
+         */
+        public String getPageEncoding()
+        {
+            return _pageEncoding;
+        }
+        
+        public void setPageEncoding(String pageEncoding)
+        {
+            _pageEncoding = pageEncoding;
+        }
+
+        public void setScriptingInvalid(String scriptingInvalid)
+        {
+            _scriptingInvalid = scriptingInvalid;
+        }
+
+        public void setIsXml(String isXml)
+        {
+            _isXml = isXml;
+        }
+
+        public void setDeferredSyntaxAllowedAsLiteral(String deferredSyntaxAllowedAsLiteral)
+        {
+            _deferredSyntaxAllowedAsLiteral = deferredSyntaxAllowedAsLiteral;
+        }
+
+        public void setTrimDirectiveWhitespaces(String trimDirectiveWhitespaces)
+        {
+            _trimDirectiveWhitespaces = trimDirectiveWhitespaces;
+        }
+
+        public void setDefaultContentType(String defaultContentType)
+        {
+            _defaultContentType = defaultContentType;
+        }
+
+        public void setBuffer(String buffer)
+        {
+            _buffer = buffer;
+        }
+
+        public void setErrorOnUndeclaredNamespace(String errorOnUndeclaredNamespace)
+        {
+            _errorOnUndeclaredNamespace = errorOnUndeclaredNamespace;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getScriptingInvalid()
+         */
+        public String getScriptingInvalid()
+        {
+            return _scriptingInvalid;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIsXml()
+         */
+        public String getIsXml()
+        {
+            return _isXml;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIncludePreludes()
+         */
+        public Collection<String> getIncludePreludes()
+        {
+            return new ArrayList<String>(_includePreludes); //must be a copy
+        }
+        
+        public void addIncludePrelude(String prelude)
+        {
+            if (!_includePreludes.contains(prelude))
+                _includePreludes.add(prelude);
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIncludeCodas()
+         */
+        public Collection<String> getIncludeCodas()
+        {
+            return new ArrayList<String>(_includeCodas); //must be a copy
+        }
+
+        public void addIncludeCoda (String coda)
+        {
+            if (!_includeCodas.contains(coda))
+                _includeCodas.add(coda);
+        }
+        
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getDeferredSyntaxAllowedAsLiteral()
+         */
+        public String getDeferredSyntaxAllowedAsLiteral()
+        {
+            return _deferredSyntaxAllowedAsLiteral;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getTrimDirectiveWhitespaces()
+         */
+        public String getTrimDirectiveWhitespaces()
+        {
+            return _trimDirectiveWhitespaces;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getDefaultContentType()
+         */
+        public String getDefaultContentType()
+        {
+            return _defaultContentType;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getBuffer()
+         */
+        public String getBuffer()
+        {
+            return _buffer;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getErrorOnUndeclaredNamespace()
+         */
+        public String getErrorOnUndeclaredNamespace()
+        {
+            return _errorOnUndeclaredNamespace;
+        }
+        
+        public String toString ()
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append("JspPropertyGroupDescriptor:");
+            sb.append(" el-ignored="+_elIgnored);
+            sb.append(" is-xml="+_isXml);
+            sb.append(" page-encoding="+_pageEncoding);
+            sb.append(" scripting-invalid="+_scriptingInvalid);
+            sb.append(" deferred-syntax-allowed-as-literal="+_deferredSyntaxAllowedAsLiteral);
+            sb.append(" trim-directive-whitespaces"+_trimDirectiveWhitespaces);
+            sb.append(" default-content-type="+_defaultContentType);
+            sb.append(" buffer="+_buffer);
+            sb.append(" error-on-undeclared-namespace="+_errorOnUndeclaredNamespace);
+            for (String prelude:_includePreludes)
+                sb.append(" include-prelude="+prelude);
+            for (String coda:_includeCodas)
+                sb.append(" include-coda="+coda);
+            return sb.toString();
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static class TagLib implements TaglibDescriptor
+    {
+        private String _uri;
+        private String _location;
+
+        /** 
+         * @see javax.servlet.descriptor.TaglibDescriptor#getTaglibURI()
+         */
+        public String getTaglibURI()
+        {
+           return _uri;
+        }
+        
+        public void setTaglibURI(String uri)
+        {
+            _uri = uri;
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.TaglibDescriptor#getTaglibLocation()
+         */
+        public String getTaglibLocation()
+        {
+            return _location;
+        }
+        
+        public void setTaglibLocation(String location)
+        {
+            _location = location;
+        }
+    
+        public String toString()
+        {
+            return ("TagLibDescriptor: taglib-uri="+_uri+" location="+_location);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public static class JspConfig implements JspConfigDescriptor
+    {
+        private List<TaglibDescriptor> _taglibs = new ArrayList<TaglibDescriptor>();
+        private List<JspPropertyGroupDescriptor> _jspPropertyGroups = new ArrayList<JspPropertyGroupDescriptor>();
+        
+        public JspConfig() {}
+
+        /** 
+         * @see javax.servlet.descriptor.JspConfigDescriptor#getTaglibs()
+         */
+        public Collection<TaglibDescriptor> getTaglibs()
+        {
+            return new ArrayList<TaglibDescriptor>(_taglibs);
+        }
+        
+        public void addTaglibDescriptor (TaglibDescriptor d)
+        {
+            _taglibs.add(d);
+        }
+
+        /** 
+         * @see javax.servlet.descriptor.JspConfigDescriptor#getJspPropertyGroups()
+         */
+        public Collection<JspPropertyGroupDescriptor> getJspPropertyGroups()
+        {
+           return new ArrayList<JspPropertyGroupDescriptor>(_jspPropertyGroups);
+        }
+        
+        public void addJspPropertyGroup(JspPropertyGroupDescriptor g)
+        {
+            _jspPropertyGroups.add(g);
+        }
+        
+        public String toString()
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append("JspConfigDescriptor: \n");
+            for (TaglibDescriptor taglib:_taglibs)
+                sb.append(taglib+"\n");
+            for (JspPropertyGroupDescriptor jpg:_jspPropertyGroups)
+                sb.append(jpg+"\n");
+            return sb.toString();
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public class Context extends ContextHandler.Context
+    {
+        /* ------------------------------------------------------------ */
+        /* 
+         * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+         */
+        @Override
+        public RequestDispatcher getNamedDispatcher(String name)
+        {
+            ContextHandler context=org.eclipse.jetty.servlet.ServletContextHandler.this;
+            if (_servletHandler==null)
+                return null;
+            ServletHolder holder = _servletHandler.getServlet(name);
+            if (holder==null || !holder.isEnabled())
+                return null;
+            return new Dispatcher(context, name);
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)
+        {
+            if (isStarted())
+                throw new IllegalStateException();
+            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();
+            FilterHolder holder = handler.getFilter(filterName);
+            if (holder == null)
+            {
+                //new filter
+                holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
+                holder.setName(filterName);
+                holder.setHeldClass(filterClass);
+                handler.addFilter(holder);
+                return holder.getRegistration();
+            }
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                //preliminary filter registration completion
+                holder.setHeldClass(filterClass);
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing filter
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public FilterRegistration.Dynamic addFilter(String filterName, String className)
+        {
+            if (isStarted())
+                throw new IllegalStateException();
+            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();
+            FilterHolder holder = handler.getFilter(filterName);
+            if (holder == null)
+            {
+                //new filter
+                holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
+                holder.setName(filterName);
+                holder.setClassName(className);
+                handler.addFilter(holder);
+                return holder.getRegistration();
+            }
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                //preliminary filter registration completion
+                holder.setClassName(className);
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing filter
+        }
+
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public FilterRegistration.Dynamic addFilter(String filterName, Filter filter)
+        {
+            if (isStarted())
+                throw new IllegalStateException();
+
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();
+            FilterHolder holder = handler.getFilter(filterName);
+            if (holder == null)
+            {
+                //new filter
+                holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
+                holder.setName(filterName);
+                holder.setFilter(filter);
+                handler.addFilter(holder);
+                return holder.getRegistration();
+            }
+            
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                //preliminary filter registration completion
+                holder.setFilter(filter);
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing filter
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
+        {
+            if (!isStarting())
+                throw new IllegalStateException();
+            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();
+            ServletHolder holder = handler.getServlet(servletName);
+            if (holder == null)
+            {
+                //new servlet
+                holder = handler.newServletHolder(Holder.Source.JAVAX_API);
+                holder.setName(servletName);
+                holder.setHeldClass(servletClass);
+                handler.addServlet(holder);
+                return dynamicHolderAdded(holder);
+            }
+
+            //complete a partial registration
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                holder.setHeldClass(servletClass);
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing completed registration for servlet name      
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public ServletRegistration.Dynamic addServlet(String servletName, String className)
+        {
+            if (!isStarting())
+                throw new IllegalStateException();
+            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+
+
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();            
+            ServletHolder holder = handler.getServlet(servletName);
+            if (holder == null)
+            {
+                //new servlet
+                holder = handler.newServletHolder(Holder.Source.JAVAX_API);
+                holder.setName(servletName);
+                holder.setClassName(className);
+                handler.addServlet(holder);
+                return dynamicHolderAdded(holder);
+            }
+
+            //complete a partial registration
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                holder.setClassName(className); 
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing completed registration for servlet name
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @since servlet-api-3.0
+         */
+        @Override
+        public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
+        {
+            if (!isStarting())
+                throw new IllegalStateException();
+
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+
+            final ServletHandler handler = ServletContextHandler.this.getServletHandler();
+            ServletHolder holder = handler.getServlet(servletName);
+            if (holder == null)
+            {
+                holder = handler.newServletHolder(Holder.Source.JAVAX_API);
+                holder.setName(servletName);
+                holder.setServlet(servlet);
+                handler.addServlet(holder);
+                return dynamicHolderAdded(holder);
+            }
+            
+            //complete a partial registration
+            if (holder.getClassName()==null && holder.getHeldClass()==null)
+            {
+                holder.setServlet(servlet);
+                return holder.getRegistration();
+            }
+            else
+                return null; //existing completed registration for servlet name
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public boolean setInitParameter(String name, String value)
+        {
+            // TODO other started conditions
+            if (!isStarting())
+                throw new IllegalStateException();
+            
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            return super.setInitParameter(name,value);
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public <T extends Filter> T createFilter(Class<T> c) throws ServletException
+        {
+            try
+            {
+                T f = c.newInstance();
+                for (int i=_decorators.size()-1; i>=0; i--)
+                {
+                    Decorator decorator = _decorators.get(i);
+                    f=decorator.decorateFilterInstance(f);
+                }
+                return f;
+            }
+            catch (InstantiationException e)
+            {
+                throw new ServletException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new ServletException(e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public <T extends Servlet> T createServlet(Class<T> c) throws ServletException
+        {
+            try
+            {
+                T s = c.newInstance();
+                for (int i=_decorators.size()-1; i>=0; i--)
+                {
+                    Decorator decorator = _decorators.get(i);
+                    s=decorator.decorateServletInstance(s);
+                }
+                return s;
+            }
+            catch (InstantiationException e)
+            {
+                throw new ServletException(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new ServletException(e);
+            }
+        }
+
+        @Override
+        public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
+        {
+            if (_sessionHandler!=null)
+                return _sessionHandler.getSessionManager().getDefaultSessionTrackingModes();
+            return null;
+        }
+
+        @Override
+        public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
+        {
+            if (_sessionHandler!=null)
+                return _sessionHandler.getSessionManager().getEffectiveSessionTrackingModes();
+            return null;
+        }
+
+        @Override
+        public FilterRegistration getFilterRegistration(String filterName)
+        {
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            final FilterHolder holder=ServletContextHandler.this.getServletHandler().getFilter(filterName);
+            return (holder==null)?null:holder.getRegistration();
+        }
+
+        @Override
+        public Map<String, ? extends FilterRegistration> getFilterRegistrations()
+        {
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            HashMap<String, FilterRegistration> registrations = new HashMap<String, FilterRegistration>();
+            ServletHandler handler=ServletContextHandler.this.getServletHandler();
+            FilterHolder[] holders=handler.getFilters();
+            if (holders!=null)
+            {
+                for (FilterHolder holder : holders)
+                    registrations.put(holder.getName(),holder.getRegistration());
+            }
+            return registrations;
+        }
+
+        @Override
+        public ServletRegistration getServletRegistration(String servletName)
+        {
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            final ServletHolder holder=ServletContextHandler.this.getServletHandler().getServlet(servletName);
+            return (holder==null)?null:holder.getRegistration();
+        }
+
+        @Override
+        public Map<String, ? extends ServletRegistration> getServletRegistrations()
+        {
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            HashMap<String, ServletRegistration> registrations = new HashMap<String, ServletRegistration>();
+            ServletHandler handler=ServletContextHandler.this.getServletHandler();
+            ServletHolder[] holders=handler.getServlets();
+            if (holders!=null)
+            {
+                for (ServletHolder holder : holders)
+                    registrations.put(holder.getName(),holder.getRegistration());
+            }
+            return registrations;
+        }
+
+        @Override
+        public SessionCookieConfig getSessionCookieConfig()
+        {
+            // TODO other started conditions
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            if (_sessionHandler!=null)
+                return _sessionHandler.getSessionManager().getSessionCookieConfig();
+            return null;
+        }
+
+        @Override
+        public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
+        {
+            // TODO other started conditions
+            if (!isStarting())
+                throw new IllegalStateException();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            
+            
+            if (_sessionHandler!=null)
+                _sessionHandler.getSessionManager().setSessionTrackingModes(sessionTrackingModes);
+        }
+
+        @Override
+        public void addListener(String className)
+        {
+            // TODO other started conditions
+            if (!isStarting())
+                throw new IllegalStateException();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            super.addListener(className);
+        }
+
+        @Override
+        public <T extends EventListener> void addListener(T t)
+        {
+            // TODO other started conditions
+            if (!isStarting())
+                throw new IllegalStateException();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            super.addListener(t);
+        }
+
+        @Override
+        public void addListener(Class<? extends EventListener> listenerClass)
+        {
+            // TODO other started conditions
+            if (!isStarting())
+                throw new IllegalStateException();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            super.addListener(listenerClass);
+        }
+
+        @Override
+        public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
+        {
+            try
+            {
+                T l = super.createListener(clazz);
+
+                for (int i=_decorators.size()-1; i>=0; i--)
+                {
+                    Decorator decorator = _decorators.get(i);
+                    l=decorator.decorateListenerInstance(l);
+                }
+                return l;
+            }
+            catch(ServletException e)
+            {
+                throw e;
+            }
+            catch(Exception e)
+            {
+                throw new ServletException(e);
+            }
+        }
+
+
+        @Override
+        public JspConfigDescriptor getJspConfigDescriptor()
+        {
+            return _jspConfig;
+        }
+        
+        @Override
+        public void setJspConfigDescriptor(JspConfigDescriptor d)
+        {
+            _jspConfig = d;
+        }
+        
+        
+        @Override
+        public void declareRoles(String... roleNames)
+        {
+            if (!isStarting())
+                throw new IllegalStateException();
+            if (!_enabled)
+                throw new UnsupportedOperationException();
+            addRoles(roleNames);
+
+
+        }
+
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    /** Interface to decorate loaded classes.
+     */
+    public interface Decorator
+    {
+        <T extends Filter> T decorateFilterInstance(T filter) throws ServletException;
+        <T extends Servlet> T decorateServletInstance(T servlet) throws ServletException;
+        <T extends EventListener> T decorateListenerInstance(T listener) throws ServletException;
+
+        void decorateFilterHolder(FilterHolder filter) throws ServletException;
+        void decorateServletHolder(ServletHolder servlet) throws ServletException;
+        
+        void destroyServletInstance(Servlet s);
+        void destroyFilterInstance(Filter f);
+        void destroyListenerInstance(EventListener f);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/ServletHandler.java b/src/java/org/eclipse/jetty/servlet/ServletHandler.java
new file mode 100644
index 0000000..53da17a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -0,0 +1,1649 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.continuation.ContinuationThrowable;
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.RuntimeIOException;
+import org.eclipse.jetty.security.IdentityService;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.AsyncContinuation;
+import org.eclipse.jetty.server.Dispatcher;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServletRequestHttpWrapper;
+import org.eclipse.jetty.server.ServletResponseHttpWrapper;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ScopedHandler;
+import org.eclipse.jetty.servlet.Holder.Source;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiException;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* --------------------------------------------------------------------- */
+/** Servlet HttpHandler.
+ * This handler maps requests to servlets that implement the
+ * javax.servlet.http.HttpServlet API.
+ * <P>
+ * This handler does not implement the full J2EE features and is intended to
+ * be used directly when a full web application is not required.  If a Web application is required,
+ * then this handler should be used as part of a <code>org.eclipse.jetty.webapp.WebAppContext</code>.
+ * <p>
+ * Unless run as part of a {@link ServletContextHandler} or derivative, the {@link #initialize()}
+ * method must be called manually after start().
+ */
+public class ServletHandler extends ScopedHandler
+{
+    private static final Logger LOG = Log.getLogger(ServletHandler.class);
+
+    /* ------------------------------------------------------------ */
+    public static final String __DEFAULT_SERVLET="default";
+        
+    /* ------------------------------------------------------------ */
+    private ServletContextHandler _contextHandler;
+    private ContextHandler.Context _servletContext;
+    private FilterHolder[] _filters=new FilterHolder[0];
+    private FilterMapping[] _filterMappings;
+    private int _matchBeforeIndex = -1; //index of last programmatic FilterMapping with isMatchAfter=false
+    private int _matchAfterIndex = -1;  //index of 1st programmatic FilterMapping with isMatchAfter=true
+    private boolean _filterChainsCached=true;
+    private int _maxFilterChainsCacheSize=512;
+    private boolean _startWithUnavailable=false;
+    private IdentityService _identityService;
+    
+    private ServletHolder[] _servlets=new ServletHolder[0];
+    private ServletMapping[] _servletMappings;
+    
+    private final Map<String,FilterHolder> _filterNameMap= new HashMap<String,FilterHolder>();
+    private List<FilterMapping> _filterPathMappings;
+    private MultiMap<String> _filterNameMappings;
+    
+    private final Map<String,ServletHolder> _servletNameMap=new HashMap<String,ServletHolder>();
+    private PathMap _servletPathMap;
+    
+    protected final ConcurrentMap<String,FilterChain> _chainCache[] = new ConcurrentMap[FilterMapping.ALL];
+    protected final Queue<String>[] _chainLRU = new Queue[FilterMapping.ALL];
+
+
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     */
+    public ServletHandler()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.server.handler.AbstractHandler#setServer(org.eclipse.jetty.server.Server)
+     */
+    public void setServer(Server server)
+    {
+        Server old=getServer();
+        if (old!=null && old!=server)
+        {
+            getServer().getContainer().update(this, _filters, null, "filter",true);
+            getServer().getContainer().update(this, _filterMappings, null, "filterMapping",true);
+            getServer().getContainer().update(this, _servlets, null, "servlet",true);
+            getServer().getContainer().update(this, _servletMappings, null, "servletMapping",true);
+        }
+
+        super.setServer(server);
+        
+        if (server!=null && old!=server)
+        {
+            server.getContainer().update(this, null, _filters, "filter",true);
+            server.getContainer().update(this, null, _filterMappings, "filterMapping",true);
+            server.getContainer().update(this, null, _servlets, "servlet",true);
+            server.getContainer().update(this, null, _servletMappings, "servletMapping",true);
+        }
+    }
+
+    /* ----------------------------------------------------------------- */
+    @Override
+    protected synchronized void doStart()
+        throws Exception
+    {
+        _servletContext=ContextHandler.getCurrentContext();
+        _contextHandler=(ServletContextHandler)(_servletContext==null?null:_servletContext.getContextHandler());
+
+        if (_contextHandler!=null)
+        {
+            SecurityHandler security_handler = (SecurityHandler)_contextHandler.getChildHandlerByClass(SecurityHandler.class);
+            if (security_handler!=null)
+                _identityService=security_handler.getIdentityService();
+        }
+        
+        updateNameMappings();
+        updateMappings();
+        
+        if(_filterChainsCached)
+        {
+            _chainCache[FilterMapping.REQUEST]=new ConcurrentHashMap<String,FilterChain>();
+            _chainCache[FilterMapping.FORWARD]=new ConcurrentHashMap<String,FilterChain>();
+            _chainCache[FilterMapping.INCLUDE]=new ConcurrentHashMap<String,FilterChain>();
+            _chainCache[FilterMapping.ERROR]=new ConcurrentHashMap<String,FilterChain>();
+            _chainCache[FilterMapping.ASYNC]=new ConcurrentHashMap<String,FilterChain>();
+            
+            _chainLRU[FilterMapping.REQUEST]=new ConcurrentLinkedQueue<String>();
+            _chainLRU[FilterMapping.FORWARD]=new ConcurrentLinkedQueue<String>();
+            _chainLRU[FilterMapping.INCLUDE]=new ConcurrentLinkedQueue<String>();
+            _chainLRU[FilterMapping.ERROR]=new ConcurrentLinkedQueue<String>();
+            _chainLRU[FilterMapping.ASYNC]=new ConcurrentLinkedQueue<String>();
+        }
+
+        super.doStart();
+        
+        if (_contextHandler==null || !(_contextHandler instanceof ServletContextHandler))
+            initialize();
+    }   
+    
+    /* ----------------------------------------------------------------- */
+    @Override
+    protected synchronized void doStop()
+        throws Exception
+    {
+        super.doStop();
+
+        // Stop filters
+        List<FilterHolder> filterHolders = new ArrayList<FilterHolder>();
+        List<FilterMapping> filterMappings = LazyList.array2List(_filterMappings);
+        if (_filters!=null)
+        {
+            for (int i=_filters.length; i-->0;)
+            {
+                try { _filters[i].stop(); }catch(Exception e){LOG.warn(Log.EXCEPTION,e);}
+                if (_filters[i].getSource() != Source.EMBEDDED)
+                {
+                    //remove all of the mappings that were for non-embedded filters
+                    _filterNameMap.remove(_filters[i].getName());
+                    //remove any mappings associated with this filter
+                    ListIterator<FilterMapping> fmitor = filterMappings.listIterator();
+                    while (fmitor.hasNext())
+                    {
+                        FilterMapping fm = fmitor.next();
+                        if (fm.getFilterName().equals(_filters[i].getName()))
+                            fmitor.remove();
+                    }
+                }
+                else
+                    filterHolders.add(_filters[i]); //only retain embedded
+            }
+        }
+        _filters = (FilterHolder[]) LazyList.toArray(filterHolders, FilterHolder.class);
+        _filterMappings = (FilterMapping[]) LazyList.toArray(filterMappings, FilterMapping.class);
+        _matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length-1);
+        _matchBeforeIndex = -1;
+
+
+        // Stop servlets
+        List<ServletHolder> servletHolders = new ArrayList<ServletHolder>();  //will be remaining servlets
+        List<ServletMapping> servletMappings = LazyList.array2List(_servletMappings); //will be remaining mappings
+        if (_servlets!=null)
+        {
+            for (int i=_servlets.length; i-->0;)
+            {
+                try { _servlets[i].stop(); }catch(Exception e){LOG.warn(Log.EXCEPTION,e);}
+                if (_servlets[i].getSource() != Source.EMBEDDED)
+                {
+                    //remove from servlet name map
+                    _servletNameMap.remove(_servlets[i].getName());
+                    //remove any mappings associated with this servlet
+                    ListIterator<ServletMapping> smitor = servletMappings.listIterator();
+                    while (smitor.hasNext())
+                    {
+                        ServletMapping sm = smitor.next();
+                        if (sm.getServletName().equals(_servlets[i].getName()))
+                            smitor.remove();
+                    }
+                }
+                else
+                    servletHolders.add(_servlets[i]); //only retain embedded 
+            }
+        }
+        _servlets = (ServletHolder[]) LazyList.toArray(servletHolders, ServletHolder.class);
+        _servletMappings = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
+
+
+        //will be regenerated on next start
+        _filterPathMappings=null;
+        _filterNameMappings=null;       
+        _servletPathMap=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected IdentityService getIdentityService()
+    {
+        return _identityService;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the contextLog.
+     */
+    public Object getContextLog()
+    {
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the filterMappings.
+     */
+    public FilterMapping[] getFilterMappings()
+    {
+        return _filterMappings;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get Filters.
+     * @return Array of defined servlets
+     */
+    public FilterHolder[] getFilters()
+    {
+        return _filters;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** ServletHolder matching path.
+     * @param pathInContext Path within _context.
+     * @return PathMap Entries pathspec to ServletHolder
+     */
+    public PathMap.Entry getHolderEntry(String pathInContext)
+    {
+        if (_servletPathMap==null)
+            return null;
+        return _servletPathMap.getMatch(pathInContext);
+    }
+ 
+    /* ------------------------------------------------------------ */
+    public ServletContext getServletContext()
+    {
+        return _servletContext;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletMappings.
+     */
+    public ServletMapping[] getServletMappings()
+    {
+        return _servletMappings;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletMappings.
+     */
+    public ServletMapping getServletMapping(String pattern)
+    {
+        ServletMapping theMapping = null;
+        if (_servletMappings!=null)
+        {
+            for (ServletMapping m:_servletMappings)
+            {
+                String[] paths=m.getPathSpecs();
+                if (paths!=null)
+                {
+                    for (String path:paths)
+                    {
+                        if (pattern.equals(path))
+                            theMapping = m;
+                    }
+                }
+            }
+        }
+        return theMapping;
+    }
+        
+    /* ------------------------------------------------------------ */
+    /** Get Servlets.
+     * @return Array of defined servlets
+     */
+    public ServletHolder[] getServlets()
+    {
+        return _servlets;
+    }
+
+    /* ------------------------------------------------------------ */
+    public ServletHolder getServlet(String name)
+    {
+        return (ServletHolder)_servletNameMap.get(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        // Get the base requests
+        final String old_servlet_path=baseRequest.getServletPath();
+        final String old_path_info=baseRequest.getPathInfo();
+
+        DispatcherType type = baseRequest.getDispatcherType();
+       
+        ServletHolder servlet_holder=null;
+        UserIdentity.Scope old_scope=null;
+
+        // find the servlet
+        if (target.startsWith("/"))
+        {
+            // Look for the servlet by path
+            PathMap.Entry entry=getHolderEntry(target);
+            if (entry!=null)
+            {
+                servlet_holder=(ServletHolder)entry.getValue();
+
+                String servlet_path_spec=(String)entry.getKey(); 
+                String servlet_path=entry.getMapped()!=null?entry.getMapped():PathMap.pathMatch(servlet_path_spec,target);
+                String path_info=PathMap.pathInfo(servlet_path_spec,target); 
+                
+                if (DispatcherType.INCLUDE.equals(type))
+                {
+                    baseRequest.setAttribute(Dispatcher.INCLUDE_SERVLET_PATH,servlet_path);
+                    baseRequest.setAttribute(Dispatcher.INCLUDE_PATH_INFO, path_info);
+                }
+                else
+                {
+                    baseRequest.setServletPath(servlet_path);
+                    baseRequest.setPathInfo(path_info);
+                }
+            }      
+        }
+        else
+        {
+            // look for a servlet by name!
+            servlet_holder=(ServletHolder)_servletNameMap.get(target);
+        }
+       
+        if (LOG.isDebugEnabled())
+            LOG.debug("servlet {}|{}|{} -> {}",baseRequest.getContextPath(),baseRequest.getServletPath(),baseRequest.getPathInfo(),servlet_holder);
+
+        try
+        {
+            // Do the filter/handling thang
+            old_scope=baseRequest.getUserIdentityScope();
+            baseRequest.setUserIdentityScope(servlet_holder);
+
+            // start manual inline of nextScope(target,baseRequest,request,response);
+            if (never())
+                nextScope(target,baseRequest,request,response);
+            else 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 (old_scope!=null)
+                baseRequest.setUserIdentityScope(old_scope);
+
+            if (!(DispatcherType.INCLUDE.equals(type)))
+            {
+                baseRequest.setServletPath(old_servlet_path);
+                baseRequest.setPathInfo(old_path_info); 
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @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
+    {
+        DispatcherType type = baseRequest.getDispatcherType();
+        
+        ServletHolder servlet_holder=(ServletHolder) baseRequest.getUserIdentityScope();
+        FilterChain chain=null;
+
+        // find the servlet
+        if (target.startsWith("/"))
+        {
+            if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0)
+                chain=getFilterChain(baseRequest, target, servlet_holder);
+        }
+        else
+        {
+            if (servlet_holder!=null)
+            {
+                if (_filterMappings!=null && _filterMappings.length>0)
+                {
+                    chain=getFilterChain(baseRequest, null,servlet_holder);
+                }
+            }
+        }
+
+        LOG.debug("chain={}",chain);
+
+        Throwable th=null;
+        try
+        {
+            if (servlet_holder==null)
+            {
+                if (getHandler()==null)
+                    notFound(request, response);
+                else
+                    nextHandle(target,baseRequest,request,response);
+            }
+            else
+            {
+                // unwrap any tunnelling of base Servlet request/responses
+                ServletRequest req = request;
+                if (req instanceof ServletRequestHttpWrapper)
+                    req = ((ServletRequestHttpWrapper)req).getRequest();
+                ServletResponse res = response;
+                if (res instanceof ServletResponseHttpWrapper)
+                    res = ((ServletResponseHttpWrapper)res).getResponse();
+
+                // Do the filter/handling thang
+                if (chain!=null)
+                    chain.doFilter(req, res);
+                else 
+                    servlet_holder.handle(baseRequest,req,res);
+            }
+        }
+        catch(EofException e)
+        {
+            throw e;
+        }
+        catch(RuntimeIOException e)
+        {
+            throw e;
+        }
+        catch(ContinuationThrowable e)
+        {   
+            throw e;
+        }
+        catch(Exception e)
+        {
+            if (!(DispatcherType.REQUEST.equals(type) || DispatcherType.ASYNC.equals(type)))
+            {
+                if (e instanceof IOException)
+                    throw (IOException)e;
+                if (e instanceof RuntimeException)
+                    throw (RuntimeException)e;
+                if (e instanceof ServletException)
+                    throw (ServletException)e;
+            }
+
+            // unwrap cause
+            th=e;
+            if (th instanceof UnavailableException)
+            {
+                LOG.debug(th); 
+            }
+            else if (th instanceof ServletException)
+            {
+                LOG.warn(th);
+                Throwable cause=((ServletException)th).getRootCause();
+                if (cause!=null)
+                    th=cause;
+            }
+
+            // handle or log exception
+            if (th instanceof HttpException)
+                throw (HttpException)th;
+            else if (th instanceof RuntimeIOException)
+                throw (RuntimeIOException)th;
+            else if (th instanceof EofException)
+                throw (EofException)th;
+
+            else if (LOG.isDebugEnabled())
+            {
+                LOG.warn(request.getRequestURI(), th); 
+                LOG.debug(request.toString()); 
+            }
+            else if (th instanceof IOException || th instanceof UnavailableException)
+            {
+                LOG.debug(request.getRequestURI(),th);
+            }
+            else
+            {
+                LOG.warn(request.getRequestURI(),th);
+            }
+
+            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,th.getClass());
+            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION,th);
+            if (!response.isCommitted())
+            {
+                if (th instanceof UnavailableException)
+                {
+                    UnavailableException ue = (UnavailableException)th;
+                    if (ue.isPermanent())
+                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                    else
+                        response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                }
+                else
+                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+            else
+                LOG.debug("Response already committed for handling "+th);
+            
+        }
+        catch(Error e)
+        {   
+            if (!(DispatcherType.REQUEST.equals(type) || DispatcherType.ASYNC.equals(type)))
+                throw e;
+            th=e;
+            LOG.warn("Error for "+request.getRequestURI(),e);
+            if(LOG.isDebugEnabled())LOG.debug(request.toString());
+
+            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE,e.getClass());
+            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
+            if (!response.isCommitted())
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            else
+                LOG.debug("Response already committed for handling ",e);
+        }
+        finally
+        {
+            if (servlet_holder!=null)
+                baseRequest.setHandled(true);
+
+            // Complete async requests 
+            if (th!=null && request.isAsyncStarted())
+                ((AsyncContinuation)request.getAsyncContext()).errorComplete();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected FilterChain getFilterChain(Request baseRequest, String pathInContext, ServletHolder servletHolder) 
+    {
+        String key=pathInContext==null?servletHolder.getName():pathInContext;
+        int dispatch = FilterMapping.dispatch(baseRequest.getDispatcherType());
+        
+        if (_filterChainsCached && _chainCache!=null)
+        {
+            FilterChain chain = (FilterChain)_chainCache[dispatch].get(key);
+            if (chain!=null)
+                return chain;
+        }
+        
+        // Build list of filters
+        Object filters= null;
+        // Path filters
+        if (pathInContext!=null && _filterPathMappings!=null)
+        {
+            for (int i= 0; i < _filterPathMappings.size(); i++)
+            {
+                FilterMapping mapping = (FilterMapping)_filterPathMappings.get(i);
+                if (mapping.appliesTo(pathInContext, dispatch))
+                    filters= LazyList.add(filters, mapping.getFilterHolder());
+            }
+        }
+
+        // Servlet name filters
+        if (servletHolder != null && _filterNameMappings!=null && _filterNameMappings.size() > 0)
+        {
+            // Servlet name filters
+            if (_filterNameMappings.size() > 0)
+            {
+                Object o= _filterNameMappings.get(servletHolder.getName());
+                for (int i=0; i<LazyList.size(o);i++)
+                {
+                    FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
+                    if (mapping.appliesTo(dispatch))
+                        filters=LazyList.add(filters,mapping.getFilterHolder());
+                }
+                
+                o= _filterNameMappings.get("*");
+                for (int i=0; i<LazyList.size(o);i++)
+                {
+                    FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
+                    if (mapping.appliesTo(dispatch))
+                        filters=LazyList.add(filters,mapping.getFilterHolder());
+                }
+            }
+        }
+        
+        if (filters==null)
+            return null;
+        
+        
+        FilterChain chain = null;
+        if (_filterChainsCached)
+        {
+            if (LazyList.size(filters) > 0)
+                chain= new CachedChain(filters, servletHolder);
+
+            final Map<String,FilterChain> cache=_chainCache[dispatch];
+            final Queue<String> lru=_chainLRU[dispatch];
+
+        	// Do we have too many cached chains?
+        	while (_maxFilterChainsCacheSize>0 && cache.size()>=_maxFilterChainsCacheSize)
+        	{
+        	    // The LRU list is not atomic with the cache map, so be prepared to invalidate if 
+        	    // a key is not found to delete.
+        	    // Delete by LRU (where U==created)
+        	    String k=lru.poll();
+        	    if (k==null)
+        	    {
+        	        cache.clear();
+        	        break;
+        	    }
+        	    cache.remove(k);
+        	}
+        	
+        	cache.put(key,chain);
+        	lru.add(key);
+        }
+        else if (LazyList.size(filters) > 0)
+            chain = new Chain(baseRequest,filters, servletHolder);
+    
+        return chain;
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void invalidateChainsCache()
+    {
+        if (_chainLRU[FilterMapping.REQUEST]!=null)
+        {
+            _chainLRU[FilterMapping.REQUEST].clear();
+            _chainLRU[FilterMapping.FORWARD].clear();
+            _chainLRU[FilterMapping.INCLUDE].clear();
+            _chainLRU[FilterMapping.ERROR].clear();
+            _chainLRU[FilterMapping.ASYNC].clear();
+
+            _chainCache[FilterMapping.REQUEST].clear();
+            _chainCache[FilterMapping.FORWARD].clear();
+            _chainCache[FilterMapping.INCLUDE].clear();
+            _chainCache[FilterMapping.ERROR].clear();
+            _chainCache[FilterMapping.ASYNC].clear();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the handler is started and there are no unavailable servlets 
+     */
+    public boolean isAvailable()
+    {
+        if (!isStarted())
+            return false;
+        ServletHolder[] holders = getServlets();
+        for (int i=0;i<holders.length;i++)
+        {
+            ServletHolder holder = holders[i];
+            if (holder!=null && !holder.isAvailable())
+                return false;
+        }
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param start True if this handler will start with unavailable servlets
+     */
+    public void setStartWithUnavailable(boolean start)
+    {
+        _startWithUnavailable=start;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if this handler will start with unavailable servlets
+     */
+    public boolean isStartWithUnavailable()
+    {
+        return _startWithUnavailable;
+    }
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Initialize filters and load-on-startup servlets.
+     * Called automatically from start if autoInitializeServlet is true.
+     */
+    public void initialize()
+        throws Exception
+    {
+        MultiException mx = new MultiException();
+
+        // Start filters
+        if (_filters!=null)
+        {
+            for (int i=0;i<_filters.length; i++)
+                _filters[i].start();
+        }
+        
+        if (_servlets!=null)
+        {
+            // Sort and Initialize servlets
+            ServletHolder[] servlets = (ServletHolder[])_servlets.clone();
+            Arrays.sort(servlets);
+            for (int i=0; i<servlets.length; i++)
+            {
+                try
+                {
+                    if (servlets[i].getClassName()==null && servlets[i].getForcedPath()!=null)
+                    {
+                        ServletHolder forced_holder = (ServletHolder)_servletPathMap.match(servlets[i].getForcedPath());
+                        if (forced_holder==null || forced_holder.getClassName()==null)
+                        {    
+                            mx.add(new IllegalStateException("No forced path servlet for "+servlets[i].getForcedPath()));
+                            continue;
+                        }
+                        servlets[i].setClassName(forced_holder.getClassName());
+                    }
+                    
+                    servlets[i].start();
+                }
+                catch(Throwable e)
+                {
+                    LOG.debug(Log.EXCEPTION,e);
+                    mx.add(e);
+                }
+            } 
+            mx.ifExceptionThrow();  
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the filterChainsCached.
+     */
+    public boolean isFilterChainsCached()
+    {
+        return _filterChainsCached;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * see also newServletHolder(Class)
+     */
+    public ServletHolder newServletHolder(Holder.Source source)
+    {
+        return new ServletHolder(source);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a servlet Holder.
+    public ServletHolder newServletHolder(Class<? extends Servlet> servlet)
+    {
+        return new ServletHolder(servlet);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a servlet.
+     * @return The servlet holder.
+     */
+    public ServletHolder addServletWithMapping (String className,String pathSpec)
+    {
+        ServletHolder holder = newServletHolder(Holder.Source.EMBEDDED);
+        holder.setClassName(className);
+        addServletWithMapping(holder,pathSpec);
+        return holder;
+    }   
+    
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a servlet.
+     * @return The servlet holder.
+     */
+    public ServletHolder addServletWithMapping (Class<? extends Servlet> servlet,String pathSpec)
+    {
+        ServletHolder holder = newServletHolder(Holder.Source.EMBEDDED);
+        holder.setHeldClass(servlet);
+        //DUPLICATES adding servlet from addServletWithMapping(holder, pathSpec)?
+        //setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
+        addServletWithMapping(holder,pathSpec);
+        
+        return holder;
+    }   
+    
+    /* ------------------------------------------------------------ */
+    /** conveniance method to add a servlet.
+     * @param servlet servlet holder to add
+     * @param pathSpec servlet mappings for the servletHolder
+     */
+    public void addServletWithMapping (ServletHolder servlet,String pathSpec)
+    {
+        ServletHolder[] holders=getServlets();
+        if (holders!=null)
+            holders = holders.clone();
+        
+        try
+        {
+            setServlets((ServletHolder[])LazyList.addToArray(holders, servlet, ServletHolder.class));
+            
+            ServletMapping mapping = new ServletMapping();
+            mapping.setServletName(servlet.getName());
+            mapping.setPathSpec(pathSpec);
+            setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
+        }
+        catch (Exception e)
+        {
+            setServlets(holders);
+            if (e instanceof RuntimeException)
+                throw (RuntimeException)e;
+            throw new RuntimeException(e);
+        }
+    }
+
+    
+    /* ------------------------------------------------------------ */    
+    /**Convenience method to add a pre-constructed ServletHolder.
+     * @param holder
+     */
+    public void addServlet(ServletHolder holder)
+    {
+        setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
+    }
+    
+    /* ------------------------------------------------------------ */    
+    /** Convenience method to add a pre-constructed ServletMapping.
+     * @param mapping
+     */
+    public void addServletMapping (ServletMapping mapping)
+    {
+        setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
+    }
+
+    public Set<String>  setServletSecurity(ServletRegistration.Dynamic registration, ServletSecurityElement servletSecurityElement) {
+        if (_contextHandler != null) {
+            return _contextHandler.setServletSecurity(registration, servletSecurityElement);
+        }
+        return Collections.emptySet();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see #newFilterHolder(Class)
+     */
+    public FilterHolder newFilterHolder(Holder.Source source)
+    {
+        return new FilterHolder(source);
+    }
+
+    /* ------------------------------------------------------------ */
+    public FilterHolder getFilter(String name)
+    {
+        return (FilterHolder)_filterNameMap.get(name);
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param filter  class of filter to create
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     * @return The filter holder.
+     */
+    public FilterHolder addFilterWithMapping (Class<? extends Filter> filter,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
+        holder.setHeldClass(filter);
+        addFilterWithMapping(holder,pathSpec,dispatches);
+        
+        return holder;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param className of filter
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     * @return The filter holder.
+     */
+    public FilterHolder addFilterWithMapping (String className,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
+        holder.setClassName(className);
+        
+        addFilterWithMapping(holder,pathSpec,dispatches);
+        return holder;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param holder filter holder to add
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     */
+    public void addFilterWithMapping (FilterHolder holder,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        FilterHolder[] holders = getFilters();
+        if (holders!=null)
+            holders = (FilterHolder[])holders.clone();
+        
+        try
+        {
+            setFilters((FilterHolder[])LazyList.addToArray(holders, holder, FilterHolder.class));
+            
+            FilterMapping mapping = new FilterMapping();
+            mapping.setFilterName(holder.getName());
+            mapping.setPathSpec(pathSpec);
+            mapping.setDispatcherTypes(dispatches);
+            //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
+            addFilterMapping(mapping);
+            
+        }
+        catch (RuntimeException e)
+        {
+            setFilters(holders);
+            throw e;
+        }
+        catch (Error e)
+        {
+            setFilters(holders);
+            throw e;
+        }
+            
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param filter  class of filter to create
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     * @return The filter holder.
+     */
+    public FilterHolder addFilterWithMapping (Class<? extends Filter> filter,String pathSpec,int dispatches)
+    {
+        FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
+        holder.setHeldClass(filter);
+        addFilterWithMapping(holder,pathSpec,dispatches);
+        
+        return holder;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param className of filter
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     * @return The filter holder.
+     */
+    public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
+    {
+        FilterHolder holder = newFilterHolder(Holder.Source.EMBEDDED);
+        holder.setClassName(className);
+        
+        addFilterWithMapping(holder,pathSpec,dispatches);
+        return holder;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter.
+     * @param holder filter holder to add
+     * @param pathSpec filter mappings for filter
+     * @param dispatches see {@link FilterMapping#setDispatches(int)}
+     */
+    public void addFilterWithMapping (FilterHolder holder,String pathSpec,int dispatches)
+    {
+        FilterHolder[] holders = getFilters();
+        if (holders!=null)
+            holders = (FilterHolder[])holders.clone();
+        
+        try
+        {
+            setFilters((FilterHolder[])LazyList.addToArray(holders, holder, FilterHolder.class));
+            
+            FilterMapping mapping = new FilterMapping();
+            mapping.setFilterName(holder.getName());
+            mapping.setPathSpec(pathSpec);
+            mapping.setDispatches(dispatches);
+            //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
+            addFilterMapping(mapping);
+        }
+        catch (RuntimeException e)
+        {
+            setFilters(holders);
+            throw e;
+        }
+        catch (Error e)
+        {
+            setFilters(holders);
+            throw e;
+        }
+            
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a filter with a mapping
+     * @param className
+     * @param pathSpec
+     * @param dispatches
+     * @return the filter holder created
+     * @deprecated use {@link #addFilterWithMapping(Class, String, EnumSet<DispatcherType>)} instead
+     */
+    public FilterHolder addFilter (String className,String pathSpec,EnumSet<DispatcherType> dispatches)
+    {
+        return addFilterWithMapping(className, pathSpec, dispatches);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * convenience method to add a filter and mapping
+     * @param filter
+     * @param filterMapping
+     */
+    public void addFilter (FilterHolder filter, FilterMapping filterMapping)
+    {
+        if (filter != null)
+            setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
+        if (filterMapping != null)
+            //setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), filterMapping, FilterMapping.class));
+            addFilterMapping(filterMapping);
+    }
+    
+    /* ------------------------------------------------------------ */  
+    /** Convenience method to add a preconstructed FilterHolder
+     * @param filter
+     */
+    public void addFilter (FilterHolder filter)
+    {
+        if (filter != null)
+            setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a preconstructed FilterMapping
+     * @param mapping
+     */
+    public void addFilterMapping (FilterMapping mapping)
+    {
+        if (mapping != null)
+        { 
+            Source source = (mapping.getFilterHolder()==null?null:mapping.getFilterHolder().getSource());
+            FilterMapping[] mappings =getFilterMappings();
+            if (mappings==null || mappings.length==0)
+            {
+                setFilterMappings(insertFilterMapping(mapping,0,false));
+                if (source != null && source == Source.JAVAX_API)
+                    _matchAfterIndex = 0;
+            }
+            else
+            {
+                //there are existing entries. If this is a programmatic filtermapping, it is added at the end of the list.
+                //If this is a normal filtermapping, it is inserted after all the other filtermappings (matchBefores and normals), 
+                //but before the first matchAfter filtermapping.
+                if (source != null && Source.JAVAX_API == source)
+                {
+                    setFilterMappings(insertFilterMapping(mapping,mappings.length-1, false));
+                    if (_matchAfterIndex < 0)
+                        _matchAfterIndex = getFilterMappings().length-1;
+                }
+                else
+                {
+                    //insert non-programmatic filter mappings before any matchAfters, if any
+                    if (_matchAfterIndex < 0)
+                        setFilterMappings(insertFilterMapping(mapping,mappings.length-1, false));
+                    else
+                    {
+                        FilterMapping[] new_mappings = insertFilterMapping(mapping, _matchAfterIndex, true);
+                        ++_matchAfterIndex;
+                        setFilterMappings(new_mappings);
+                    }
+                }
+            }
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Convenience method to add a preconstructed FilterMapping
+     * @param mapping
+     */
+    public void prependFilterMapping (FilterMapping mapping)
+    {
+        if (mapping != null)
+        {
+            Source source = mapping.getFilterHolder().getSource();
+            
+            FilterMapping[] mappings = getFilterMappings();
+            if (mappings==null || mappings.length==0)
+            {
+                setFilterMappings(insertFilterMapping(mapping, 0, false));
+                if (source != null && Source.JAVAX_API == source)
+                    _matchBeforeIndex = 0;
+            }
+            else
+            {
+                if (source != null && Source.JAVAX_API == source)
+                {
+                    //programmatically defined filter mappings are prepended to mapping list in the order
+                    //in which they were defined. In other words, insert this mapping at the tail of the 
+                    //programmatically prepended filter mappings, BEFORE the first web.xml defined filter mapping.
+
+                    if (_matchBeforeIndex < 0)
+                    { 
+                        //no programmatically defined prepended filter mappings yet, prepend this one
+                        _matchBeforeIndex = 0;
+                        FilterMapping[] new_mappings = insertFilterMapping(mapping, 0, true);
+                        setFilterMappings(new_mappings);
+                    }
+                    else
+                    {
+                        FilterMapping[] new_mappings = insertFilterMapping(mapping,_matchBeforeIndex, false);
+                        ++_matchBeforeIndex;
+                        setFilterMappings(new_mappings);
+                    }
+                }
+                else
+                {
+                    //non programmatically defined, just prepend to list
+                    FilterMapping[] new_mappings = insertFilterMapping(mapping, 0, true);
+                    setFilterMappings(new_mappings);
+                }
+                
+                //adjust matchAfterIndex ptr to take account of the mapping we just prepended
+                if (_matchAfterIndex >= 0)
+                    ++_matchAfterIndex;
+            }
+        }
+    }
+    
+    
+    
+    /**
+     * Insert a filtermapping in the list
+     * @param mapping the FilterMapping to add
+     * @param pos the position in the existing arry at which to add it
+     * @param before if true, insert before  pos, if false insert after it
+     * @return
+     */
+    protected FilterMapping[] insertFilterMapping (FilterMapping mapping, int pos, boolean before)
+    {
+        if (pos < 0)
+            throw new IllegalArgumentException("FilterMapping insertion pos < 0");
+        FilterMapping[] mappings = getFilterMappings();
+        
+        if (mappings==null || mappings.length==0)
+        {
+            return new FilterMapping[] {mapping};
+        }
+        FilterMapping[] new_mappings = new FilterMapping[mappings.length+1];
+
+    
+        if (before)
+        {
+            //copy existing filter mappings up to but not including the pos
+            System.arraycopy(mappings,0,new_mappings,0,pos);
+
+            //add in the new mapping
+            new_mappings[pos] = mapping; 
+
+            //copy the old pos mapping and any remaining existing mappings
+            System.arraycopy(mappings,pos,new_mappings,pos+1, mappings.length-pos);
+
+        }
+        else
+        {
+            //copy existing filter mappings up to and including the pos
+            System.arraycopy(mappings,0,new_mappings,0,pos+1);
+            //add in the new mapping after the pos
+            new_mappings[pos+1] = mapping;   
+
+            //copy the remaining existing mappings
+            if (mappings.length > pos+1)
+                System.arraycopy(mappings,pos+1,new_mappings,pos+2, mappings.length-(pos+1));
+        }
+        return new_mappings;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    protected synchronized void updateNameMappings()
+    {   
+        // update filter name map
+        _filterNameMap.clear();
+        if (_filters!=null)
+        {   
+            for (int i=0;i<_filters.length;i++)
+            {
+                _filterNameMap.put(_filters[i].getName(),_filters[i]);
+                _filters[i].setServletHandler(this);
+            }
+        }
+
+        // Map servlet names to holders
+        _servletNameMap.clear();
+        if (_servlets!=null)
+        {   
+            // update the maps
+            for (int i=0;i<_servlets.length;i++)
+            {
+                _servletNameMap.put(_servlets[i].getName(),_servlets[i]);
+                _servlets[i].setServletHandler(this);
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected synchronized void updateMappings()
+    {   
+        // update filter mappings
+        if (_filterMappings==null)
+        {
+            _filterPathMappings=null;
+            _filterNameMappings=null;
+        }
+        else 
+        {
+            _filterPathMappings=new ArrayList();
+            _filterNameMappings=new MultiMap();
+            for (int i=0;i<_filterMappings.length;i++)
+            {
+                FilterHolder filter_holder = (FilterHolder)_filterNameMap.get(_filterMappings[i].getFilterName());
+                if (filter_holder==null)
+                    throw new IllegalStateException("No filter named "+_filterMappings[i].getFilterName());
+                _filterMappings[i].setFilterHolder(filter_holder);    
+                if (_filterMappings[i].getPathSpecs()!=null)
+                    _filterPathMappings.add(_filterMappings[i]);
+                
+                if (_filterMappings[i].getServletNames()!=null)
+                {
+                    String[] names=_filterMappings[i].getServletNames();
+                    for (int j=0;j<names.length;j++)
+                    {
+                        if (names[j]!=null)
+                            _filterNameMappings.add(names[j], _filterMappings[i]);  
+                    }
+                }
+            }
+        }
+
+        // Map servlet paths to holders
+        if (_servletMappings==null || _servletNameMap==null)
+        {
+            _servletPathMap=null;
+        }
+        else
+        {
+            PathMap pm = new PathMap();
+            
+            // update the maps
+            for (int i=0;i<_servletMappings.length;i++)
+            {
+                ServletHolder servlet_holder = (ServletHolder)_servletNameMap.get(_servletMappings[i].getServletName());
+                if (servlet_holder==null)
+                    throw new IllegalStateException("No such servlet: "+_servletMappings[i].getServletName());
+                else if (servlet_holder.isEnabled() && _servletMappings[i].getPathSpecs()!=null)
+                {
+                    String[] pathSpecs = _servletMappings[i].getPathSpecs();
+                    for (int j=0;j<pathSpecs.length;j++)
+                        if (pathSpecs[j]!=null)
+                            pm.put(pathSpecs[j],servlet_holder);
+                }
+            }
+            
+            _servletPathMap=pm;
+        }
+        
+        // flush filter chain cache
+        if (_chainCache!=null)
+        {
+            for (int i=_chainCache.length;i-->0;)
+            {
+                if (_chainCache[i]!=null)
+                    _chainCache[i].clear();
+            }
+        }
+
+        if (LOG.isDebugEnabled()) 
+        {
+            LOG.debug("filterNameMap="+_filterNameMap);
+            LOG.debug("pathFilters="+_filterPathMappings);
+            LOG.debug("servletFilterMap="+_filterNameMappings);
+            LOG.debug("servletPathMap="+_servletPathMap);
+            LOG.debug("servletNameMap="+_servletNameMap);
+        }
+        
+        try
+        {
+            if (_contextHandler!=null && _contextHandler.isStarted() || _contextHandler==null && isStarted())
+                initialize();
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void notFound(HttpServletRequest request,
+                  HttpServletResponse response)
+        throws IOException
+    {
+        if(LOG.isDebugEnabled())
+            LOG.debug("Not Found "+request.getRequestURI());
+        //Override to send an error back, eg with: response.sendError(HttpServletResponse.SC_NOT_FOUND);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filterChainsCached The filterChainsCached to set.
+     */
+    public void setFilterChainsCached(boolean filterChainsCached)
+    {
+        _filterChainsCached = filterChainsCached;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filterMappings The filterMappings to set.
+     */
+    public void setFilterMappings(FilterMapping[] filterMappings)
+    {
+        if (getServer()!=null)
+            getServer().getContainer().update(this,_filterMappings,filterMappings,"filterMapping",true);
+        _filterMappings = filterMappings;
+        updateMappings();
+        invalidateChainsCache();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public synchronized void setFilters(FilterHolder[] holders)
+    {
+        if (getServer()!=null)
+            getServer().getContainer().update(this,_filters,holders,"filter",true);
+        _filters=holders;
+        updateNameMappings();
+        invalidateChainsCache();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletMappings The servletMappings to set.
+     */
+    public void setServletMappings(ServletMapping[] servletMappings)
+    {
+        if (getServer()!=null)
+            getServer().getContainer().update(this,_servletMappings,servletMappings,"servletMapping",true);
+        _servletMappings = servletMappings;
+        updateMappings();
+        invalidateChainsCache();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set Servlets.
+     * @param holders Array of servletsto define
+     */
+    public synchronized void setServlets(ServletHolder[] holders)
+    {
+        if (getServer()!=null)
+            getServer().getContainer().update(this,_servlets,holders,"servlet",true);
+        _servlets=holders;
+        updateNameMappings();
+        invalidateChainsCache();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class CachedChain implements FilterChain
+    {
+        FilterHolder _filterHolder;
+        CachedChain _next;
+        ServletHolder _servletHolder;
+
+        /* ------------------------------------------------------------ */
+        CachedChain(Object filters, ServletHolder servletHolder)
+        {
+            if (LazyList.size(filters)>0)
+            {
+                _filterHolder=(FilterHolder)LazyList.get(filters, 0);
+                filters=LazyList.remove(filters,0);
+                _next=new CachedChain(filters,servletHolder);
+            }
+            else
+                _servletHolder=servletHolder;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void doFilter(ServletRequest request, ServletResponse response) 
+            throws IOException, ServletException
+        {                   
+            final Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+
+            // pass to next filter
+            if (_filterHolder!=null)
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("call filter " + _filterHolder);
+                Filter filter= _filterHolder.getFilter();
+                if (_filterHolder.isAsyncSupported())
+                    filter.doFilter(request, response, _next);
+                else
+                {
+                    final boolean suspendable=baseRequest.isAsyncSupported();
+                    if (suspendable)
+                    {
+                        try
+                        {
+                            baseRequest.setAsyncSupported(false);
+                            filter.doFilter(request, response, _next);
+                        }
+                        finally
+                        {
+                            baseRequest.setAsyncSupported(true);
+                        }
+                    }
+                    else
+                        filter.doFilter(request, response, _next);
+                }
+                return;
+            }
+
+            // Call servlet
+            
+            HttpServletRequest srequest = (HttpServletRequest)request;
+            if (_servletHolder != null)
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("call servlet " + _servletHolder);
+                _servletHolder.handle(baseRequest,request, response);
+            }
+            else if (getHandler()==null)
+                notFound(srequest, (HttpServletResponse)response);
+            else
+                nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
+                           baseRequest,srequest,(HttpServletResponse)response);
+            
+        }
+        
+        public String toString()
+        {
+            if (_filterHolder!=null)
+                return _filterHolder+"->"+_next.toString();
+            if (_servletHolder!=null)
+                return _servletHolder.toString();
+            return "null";
+        }
+    }  
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class Chain implements FilterChain
+    {
+        final Request _baseRequest;
+        final Object _chain;
+        final ServletHolder _servletHolder;
+        int _filter= 0;
+
+        /* ------------------------------------------------------------ */
+        Chain(Request baseRequest, Object filters, ServletHolder servletHolder)
+        {
+            _baseRequest=baseRequest;
+            _chain= filters;
+            _servletHolder= servletHolder;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void doFilter(ServletRequest request, ServletResponse response)
+            throws IOException, ServletException
+        {
+            if (LOG.isDebugEnabled()) 
+                LOG.debug("doFilter " + _filter);
+
+            // pass to next filter
+            if (_filter < LazyList.size(_chain))
+            {
+                FilterHolder holder= (FilterHolder)LazyList.get(_chain, _filter++);
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("call filter " + holder);
+                Filter filter= holder.getFilter();
+                
+                if (holder.isAsyncSupported() || !_baseRequest.isAsyncSupported())
+                {
+                    filter.doFilter(request, response, this);
+                }
+                else
+                {
+                    try
+                    {
+                        _baseRequest.setAsyncSupported(false);
+                        filter.doFilter(request, response, this);
+                    }
+                    finally
+                    {
+                        _baseRequest.setAsyncSupported(true);
+                    }
+                }
+                    
+                return;
+            }
+
+            // Call servlet
+            HttpServletRequest srequest = (HttpServletRequest)request;
+            if (_servletHolder != null)
+            {
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("call servlet " + _servletHolder);
+                _servletHolder.handle(_baseRequest,request, response);
+            }
+            else if (getHandler()==null)
+                notFound(srequest, (HttpServletResponse)response);
+            else
+            {            
+                Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest();
+                nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
+                           baseRequest,srequest,(HttpServletResponse)response);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public String toString()
+        {
+            StringBuilder b = new StringBuilder();
+            for (int i=0; i<LazyList.size(_chain);i++)
+            {
+                Object o=LazyList.get(_chain, i);
+                b.append(o.toString());
+                b.append("->");
+            }
+            b.append(_servletHolder);
+            return b.toString();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The maximum entries in a filter chain cache.
+     */
+    public int getMaxFilterChainsCacheSize()
+    {
+        return _maxFilterChainsCacheSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the maximum filter chain cache size.
+     * Filter chains are cached if {@link #isFilterChainsCached()} is true. If the max cache size
+     * is greater than zero, then the cache is flushed whenever it grows to be this size.
+     * 
+     * @param maxFilterChainsCacheSize  the maximum number of entries in a filter chain cache.
+     */
+    public void setMaxFilterChainsCacheSize(int maxFilterChainsCacheSize)
+    {
+        _maxFilterChainsCacheSize = maxFilterChainsCacheSize;
+    }
+    
+    /* ------------------------------------------------------------ */
+    void destroyServlet(Servlet servlet)
+    {
+        if (_contextHandler!=null)
+            _contextHandler.destroyServlet(servlet);
+    }
+
+    /* ------------------------------------------------------------ */
+    void destroyFilter(Filter filter)
+    {
+        if (_contextHandler!=null)
+            _contextHandler.destroyFilter(filter);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void dump(Appendable out,String indent) throws IOException
+    {
+        super.dumpThis(out);
+        dump(out,indent,
+                TypeUtil.asList(getHandlers()),
+                getBeans(),
+                TypeUtil.asList(getFilterMappings()),
+                TypeUtil.asList(getFilters()),
+                TypeUtil.asList(getServletMappings()),
+                TypeUtil.asList(getServlets()));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/ServletHolder.java b/src/java/org/eclipse/jetty/servlet/ServletHolder.java
new file mode 100644
index 0000000..30542b1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/ServletHolder.java
@@ -0,0 +1,969 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.SingleThreadModel;
+import javax.servlet.UnavailableException;
+
+import org.eclipse.jetty.security.IdentityService;
+import org.eclipse.jetty.security.RunAsToken;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+
+/* --------------------------------------------------------------------- */
+/** Servlet Instance and Context Holder.
+ * Holds the name, params and some state of a javax.servlet.Servlet
+ * instance. It implements the ServletConfig interface.
+ * This class will organise the loading of the servlet when needed or
+ * requested.
+ *
+ * 
+ */
+public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable
+{
+    private static final Logger LOG = Log.getLogger(ServletHolder.class);
+
+    /* ---------------------------------------------------------------- */
+    private int _initOrder;
+    private boolean _initOnStartup=false;
+    private Map<String, String> _roleMap;
+    private String _forcedPath;
+    private String _runAsRole;
+    private RunAsToken _runAsToken;
+    private IdentityService _identityService;
+    private ServletRegistration.Dynamic _registration;
+    
+    
+    private transient Servlet _servlet;
+    private transient Config _config;
+    private transient long _unavailable;
+    private transient boolean _enabled = true;
+    private transient UnavailableException _unavailableEx;
+    public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
+
+    /* ---------------------------------------------------------------- */
+    /** Constructor .
+     */
+    public ServletHolder()
+    {
+        this(Source.EMBEDDED);
+    }
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor .
+     */
+    public ServletHolder(Holder.Source creator)
+    {
+        super(creator);
+    }
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor for existing servlet.
+     */
+    public ServletHolder(Servlet servlet)
+    {
+        this(Source.EMBEDDED);
+        setServlet(servlet);
+    }
+
+    /* ---------------------------------------------------------------- */
+    /** Constructor for servlet class.
+     */
+    public ServletHolder(String name, Class<? extends Servlet> servlet)
+    {
+        this(Source.EMBEDDED);
+        setName(name);
+        setHeldClass(servlet);
+    }
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor for servlet class.
+     */
+    public ServletHolder(String name, Servlet servlet)
+    {
+        this(Source.EMBEDDED);
+        setName(name);
+        setServlet(servlet);
+    }
+    
+    /* ---------------------------------------------------------------- */
+    /** Constructor for servlet class.
+     */
+    public ServletHolder(Class<? extends Servlet> servlet)
+    {
+        this(Source.EMBEDDED);
+        setHeldClass(servlet);
+    }
+
+    /* ---------------------------------------------------------------- */
+    /**
+     * @return The unavailable exception or null if not unavailable
+     */
+    public UnavailableException getUnavailableException()
+    {
+        return _unavailableEx;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public synchronized void setServlet(Servlet servlet)
+    {
+        if (servlet==null || servlet instanceof SingleThreadModel)
+            throw new IllegalArgumentException();
+
+        _extInstance=true;
+        _servlet=servlet;
+        setHeldClass(servlet.getClass());
+        if (getName()==null)
+            setName(servlet.getClass().getName()+"-"+super.hashCode());
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int getInitOrder()
+    {
+        return _initOrder;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the initialize order.
+     * Holders with order<0, are initialized on use. Those with
+     * order>=0 are initialized in increasing order when the handler
+     * is started.
+     */
+    public void setInitOrder(int order)
+    {
+        _initOnStartup=true;
+        _initOrder = order;
+    }
+    
+    public boolean isSetInitOrder()
+    {
+        return _initOnStartup;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Comparitor by init order.
+     */
+    public int compareTo(Object o)
+    {
+        if (o instanceof ServletHolder)
+        {
+            ServletHolder sh= (ServletHolder)o;
+            if (sh==this)
+                return 0;
+            if (sh._initOrder<_initOrder)
+                return 1;
+            if (sh._initOrder>_initOrder)
+                return -1;
+            
+            int c=(_className!=null && sh._className!=null)?_className.compareTo(sh._className):0;
+            if (c==0)
+                c=_name.compareTo(sh._name);
+            return c;
+        }
+        return 1;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean equals(Object o)
+    {
+        return compareTo(o)==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int hashCode()
+    {
+        return _name==null?System.identityHashCode(this):_name.hashCode();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Link a user role.
+     * Translate the role name used by a servlet, to the link name
+     * used by the container.
+     * @param name The role name as used by the servlet
+     * @param link The role name as used by the container.
+     */
+    public synchronized void setUserRoleLink(String name,String link)
+    {
+        if (_roleMap==null)
+            _roleMap=new HashMap<String, String>();
+        _roleMap.put(name,link);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** get a user role link.
+     * @param name The name of the role
+     * @return The name as translated by the link. If no link exists,
+     * the name is returned.
+     */
+    public String getUserRoleLink(String name)
+    {
+        if (_roleMap==null)
+            return name;
+        String link= _roleMap.get(name);
+        return (link==null)?name:link;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Map<String, String> getRoleMap()
+    {
+        return _roleMap == null? NO_MAPPED_ROLES : _roleMap;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the forcedPath.
+     */
+    public String getForcedPath()
+    {
+        return _forcedPath;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param forcedPath The forcedPath to set.
+     */
+    public void setForcedPath(String forcedPath)
+    {
+        _forcedPath = forcedPath;
+    }
+    
+    public boolean isEnabled()
+    {
+        return _enabled;
+    }
+
+
+    public void setEnabled(boolean enabled)
+    {
+        _enabled = enabled;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void doStart()
+        throws Exception
+    {
+        _unavailable=0;
+        if (!_enabled)
+            return;
+        
+        
+        //check servlet has a class (ie is not a preliminary registration). If preliminary, fail startup.
+        try
+        {
+            super.doStart();
+        } 
+        catch (UnavailableException ue)
+        {
+            makeUnavailable(ue);
+            if (_servletHandler.isStartWithUnavailable())
+            {
+                LOG.ignore(ue);
+                return;
+            }
+            else
+                throw ue;
+        }
+
+
+        //servlet is not an instance of javax.servlet.Servlet
+        try
+        {
+            checkServletType();
+        }
+        catch (UnavailableException ue)
+        {
+            makeUnavailable(ue);
+            if (_servletHandler.isStartWithUnavailable())
+            {
+                LOG.ignore(ue);
+                return;
+            }
+            else
+                throw ue;
+        }
+        
+
+        _identityService = _servletHandler.getIdentityService();
+        if (_identityService!=null && _runAsRole!=null)
+            _runAsToken=_identityService.newRunAsToken(_runAsRole);
+        
+        _config=new Config();
+
+        if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
+            _servlet = new SingleThreadedWrapper();
+
+        if (_extInstance || _initOnStartup)
+        {
+            try
+            {
+                initServlet();
+            }
+            catch(Exception e)
+            {
+                if (_servletHandler.isStartWithUnavailable())
+                    LOG.ignore(e);
+                else
+                    throw e;
+            }
+        }  
+    }
+
+    /* ------------------------------------------------------------ */
+    public void doStop()
+        throws Exception
+    {
+        Object old_run_as = null;
+        if (_servlet!=null)
+        {       
+            try
+            {
+                if (_identityService!=null)
+                    old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
+
+                destroyInstance(_servlet);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+            }
+            finally
+            {
+                if (_identityService!=null)
+                    _identityService.unsetRunAs(old_run_as);
+            }
+        }
+
+        if (!_extInstance)
+            _servlet=null;
+
+        _config=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void destroyInstance (Object o)
+    throws Exception
+    {
+        if (o==null)
+            return;
+        Servlet servlet =  ((Servlet)o);
+        getServletHandler().destroyServlet(servlet);
+        servlet.destroy();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the servlet.
+     * @return The servlet
+     */
+    public synchronized Servlet getServlet()
+        throws ServletException
+    {
+        // Handle previous unavailability
+        if (_unavailable!=0)
+        {
+            if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
+                throw _unavailableEx;
+            _unavailable=0;
+            _unavailableEx=null;
+        }
+
+        if (_servlet==null)
+            initServlet();
+        return _servlet;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the servlet instance (no initialization done).
+     * @return The servlet or null
+     */
+    public Servlet getServletInstance()
+    {
+        return _servlet;
+    }
+        
+    /* ------------------------------------------------------------ */
+    /**
+     * Check to ensure class of servlet is acceptable.
+     * @throws UnavailableException
+     */
+    public void checkServletType ()
+        throws UnavailableException
+    {
+        if (_class==null || !javax.servlet.Servlet.class.isAssignableFrom(_class))
+        {
+            throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return true if the holder is started and is not unavailable
+     */
+    public boolean isAvailable()
+    {
+        if (isStarted()&& _unavailable==0)
+            return true;
+        try 
+        {
+            getServlet();
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+        }
+
+        return isStarted()&& _unavailable==0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    private void makeUnavailable(UnavailableException e)
+    {
+        if (_unavailableEx==e && _unavailable!=0)
+            return;
+
+        _servletHandler.getServletContext().log("unavailable",e);
+
+        _unavailableEx=e;
+        _unavailable=-1;
+        if (e.isPermanent())   
+            _unavailable=-1;
+        else
+        {
+            if (_unavailableEx.getUnavailableSeconds()>0)
+                _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
+            else
+                _unavailable=System.currentTimeMillis()+5000; // TODO configure
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+
+    private void makeUnavailable(final Throwable e)
+    {
+        if (e instanceof UnavailableException)
+            makeUnavailable((UnavailableException)e);
+        else
+        {
+            ServletContext ctx = _servletHandler.getServletContext();
+            if (ctx==null)
+                LOG.info("unavailable",e);
+            else
+                ctx.log("unavailable",e);
+            _unavailableEx=new UnavailableException(String.valueOf(e),-1)
+            {
+                {
+                    initCause(e);
+                }
+            };
+            _unavailable=-1;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void initServlet()
+    	throws ServletException
+    {
+        Object old_run_as = null;
+        try
+        {
+            if (_servlet==null)
+                _servlet=newInstance();
+            if (_config==null)
+                _config=new Config();
+            
+            // Handle run as
+            if (_identityService!=null)
+            {
+                old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
+            }
+            
+            // Handle configuring servlets that implement org.apache.jasper.servlet.JspServlet
+            if (isJspServlet())
+            {
+                initJspServlet();
+            }
+
+            initMultiPart();
+            
+            _servlet.init(_config);
+        }
+        catch (UnavailableException e)
+        {
+            makeUnavailable(e);
+            _servlet=null;
+            _config=null;
+            throw e;
+        }
+        catch (ServletException e)
+        {
+            makeUnavailable(e.getCause()==null?e:e.getCause());
+            _servlet=null;
+            _config=null;
+            throw e;
+        }
+        catch (Exception e)
+        {
+            makeUnavailable(e);
+            _servlet=null;
+            _config=null;
+            throw new ServletException(this.toString(),e);
+        }
+        finally
+        {
+            // pop run-as role
+            if (_identityService!=null)
+                _identityService.unsetRunAs(old_run_as);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @throws Exception
+     */
+    protected void initJspServlet () throws Exception
+    {
+        ContextHandler ch = ((ContextHandler.Context)getServletHandler().getServletContext()).getContextHandler();
+        
+        /* Set the webapp's classpath for Jasper */
+        ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
+
+        /* Set the system classpath for Jasper */
+        setInitParameter("com.sun.appserv.jsp.classpath", Loader.getClassPath(ch.getClassLoader().getParent())); 
+        
+        /* Set up other classpath attribute */
+        if ("?".equals(getInitParameter("classpath")))
+        {
+            String classpath = ch.getClassPath();
+            LOG.debug("classpath=" + classpath);
+            if (classpath != null) 
+                setInitParameter("classpath", classpath);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Register a ServletRequestListener that will ensure tmp multipart
+     * files are deleted when the request goes out of scope.
+     * 
+     * @throws Exception
+     */
+    protected void initMultiPart () throws Exception
+    {
+        //if this servlet can handle multipart requests, ensure tmp files will be
+        //cleaned up correctly
+        if (((Registration)getRegistration()).getMultipartConfig() != null)
+        {
+            //Register a listener to delete tmp files that are created as a result of this
+            //servlet calling Request.getPart() or Request.getParts()
+            ContextHandler ch = ((ContextHandler.Context)getServletHandler().getServletContext()).getContextHandler();
+            ch.addEventListener(new Request.MultiPartCleanerListener());
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.UserIdentity.Scope#getContextPath()
+     */
+    public String getContextPath()
+    {
+        return _config.getServletContext().getContextPath();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.server.UserIdentity.Scope#getRoleRefMap()
+     */
+    public Map<String, String> getRoleRefMap()
+    {
+        return _roleMap;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getRunAsRole() 
+    {
+        return _runAsRole;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setRunAsRole(String role) 
+    {
+        _runAsRole = role;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Service a request with this servlet.
+     */
+    public void handle(Request baseRequest,
+                       ServletRequest request,
+                       ServletResponse response)
+        throws ServletException,
+               UnavailableException,
+               IOException
+    {
+        if (_class==null)
+            throw new UnavailableException("Servlet Not Initialized");
+        
+        Servlet servlet=_servlet;
+        synchronized(this)
+        {
+            if (!isStarted())
+                throw new UnavailableException("Servlet not initialized", -1);
+            if (_unavailable!=0 || !_initOnStartup)
+                servlet=getServlet();
+            if (servlet==null)
+                throw new UnavailableException("Could not instantiate "+_class);
+        }
+        
+        // Service the request
+        boolean servlet_error=true;
+        Object old_run_as = null;
+        boolean suspendable = baseRequest.isAsyncSupported();
+        try
+        {
+            // Handle aliased path
+            if (_forcedPath!=null)
+                // TODO complain about poor naming to the Jasper folks
+                request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
+
+            // Handle run as
+            if (_identityService!=null)
+                old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
+
+            if (!isAsyncSupported())
+                baseRequest.setAsyncSupported(false);
+
+            MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
+            if (mpce != null)
+                request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
+
+            servlet.service(request,response);
+            servlet_error=false;
+        }
+        catch(UnavailableException e)
+        {
+            makeUnavailable(e);
+            throw _unavailableEx;
+        }
+        finally
+        {
+            baseRequest.setAsyncSupported(suspendable);
+            
+            // pop run-as role
+            if (_identityService!=null)
+                _identityService.unsetRunAs(old_run_as);
+
+            // Handle error params.
+            if (servlet_error)
+                request.setAttribute("javax.servlet.error.servlet_name",getName());
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private boolean isJspServlet ()
+    {
+        if (_servlet == null)
+            return false;
+        
+        Class c = _servlet.getClass();
+        
+        boolean result = false;
+        while (c != null && !result)
+        {
+            result = isJspServlet(c.getName());
+            c = c.getSuperclass();
+        }
+        
+        return result;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private boolean isJspServlet (String classname)
+    {
+        if (classname == null)
+            return false;
+        return ("org.apache.jasper.servlet.JspServlet".equals(classname));
+    }
+
+ 
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    protected class Config extends HolderConfig implements ServletConfig
+    {   
+        /* -------------------------------------------------------- */
+        public String getServletName()
+        {
+            return getName();
+        }
+        
+    }
+
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    public class Registration extends HolderRegistration implements ServletRegistration.Dynamic
+    {
+        protected MultipartConfigElement _multipartConfig;       
+        
+        public Set<String> addMapping(String... urlPatterns)
+        {
+            illegalStateIfContextStarted();
+            Set<String> clash=null;
+            for (String pattern : urlPatterns)
+            {
+                ServletMapping mapping = _servletHandler.getServletMapping(pattern);
+                if (mapping!=null)
+                {
+                    //if the servlet mapping was from a default descriptor, then allow it to be overridden
+                    if (!mapping.isDefault())
+                    {
+                        if (clash==null)
+                            clash=new HashSet<String>();
+                        clash.add(pattern);
+                    }
+                }
+            }
+            
+            //if there were any clashes amongst the urls, return them
+            if (clash!=null)
+                return clash;
+            
+            //otherwise apply all of them
+            ServletMapping mapping = new ServletMapping();
+            mapping.setServletName(ServletHolder.this.getName());
+            mapping.setPathSpecs(urlPatterns);
+            _servletHandler.addServletMapping(mapping);
+            
+            return Collections.emptySet();
+        }
+
+        public Collection<String> getMappings()
+        {
+            ServletMapping[] mappings =_servletHandler.getServletMappings();
+            List<String> patterns=new ArrayList<String>();
+            if (mappings!=null)
+            {
+                for (ServletMapping mapping : mappings)
+                {
+                    if (!mapping.getServletName().equals(getName()))
+                        continue;
+                    String[] specs=mapping.getPathSpecs();
+                    if (specs!=null && specs.length>0)
+                        patterns.addAll(Arrays.asList(specs));
+                }
+            }
+            return patterns;
+        }
+
+        @Override
+        public String getRunAsRole() 
+        {
+            return _runAsRole;
+        }
+
+        @Override
+        public void setLoadOnStartup(int loadOnStartup)
+        {
+            illegalStateIfContextStarted();
+            ServletHolder.this.setInitOrder(loadOnStartup);
+        }
+        
+        public int getInitOrder()
+        {
+            return ServletHolder.this.getInitOrder();
+        }
+
+        @Override
+        public void setMultipartConfig(MultipartConfigElement element) 
+        {
+            _multipartConfig = element;
+        }
+        
+        public MultipartConfigElement getMultipartConfig()
+        {
+            return _multipartConfig;
+        }
+
+        @Override
+        public void setRunAsRole(String role) 
+        {
+            _runAsRole = role;
+        }
+
+        @Override
+        public Set<String> setServletSecurity(ServletSecurityElement securityElement) 
+        {
+            return _servletHandler.setServletSecurity(this, securityElement);
+        }
+    }
+    
+    public ServletRegistration.Dynamic getRegistration()
+    {
+        if (_registration == null)
+            _registration = new Registration();
+        return _registration;
+    }
+    
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    /* -------------------------------------------------------- */
+    private class SingleThreadedWrapper implements Servlet
+    {
+        Stack<Servlet> _stack=new Stack<Servlet>();
+        
+        public void destroy()
+        {
+            synchronized(this)
+            {
+                while(_stack.size()>0)
+                    try { (_stack.pop()).destroy(); } catch (Exception e) { LOG.warn(e); }
+            }
+        }
+
+        public ServletConfig getServletConfig()
+        {
+            return _config;
+        }
+
+        public String getServletInfo()
+        {
+            return null;
+        }
+
+        public void init(ServletConfig config) throws ServletException
+        {
+            synchronized(this)
+            {
+                if(_stack.size()==0)
+                {
+                    try
+                    {
+                        Servlet s = newInstance();
+                        s.init(config);
+                        _stack.push(s);
+                    }
+                    catch (ServletException e)
+                    {
+                        throw e;
+                    }
+                    catch (Exception e)
+                    {
+                        throw new ServletException(e);
+                    }
+                }
+            }
+        }
+
+        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
+        {
+            Servlet s;
+            synchronized(this)
+            {
+                if(_stack.size()>0)
+                    s=(Servlet)_stack.pop();
+                else
+                {
+                    try
+                    {
+                        s = newInstance();
+                        s.init(_config);
+                    }
+                    catch (ServletException e)
+                    {
+                        throw e;
+                    }
+                    catch (Exception e)
+                    {
+                        throw new ServletException(e);
+                    }
+                }
+            }
+            
+            try
+            {
+                s.service(req,res);
+            }
+            finally
+            {
+                synchronized(this)
+                {
+                    _stack.push(s);
+                }
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the newly created Servlet instance
+     * @throws ServletException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    protected Servlet newInstance() throws ServletException, IllegalAccessException, InstantiationException
+    {
+        try
+        {
+            ServletContext ctx = getServletHandler().getServletContext();
+            if (ctx==null)
+                return getHeldClass().newInstance();
+            return ((ServletContextHandler.Context)ctx).createServlet(getHeldClass());
+        }
+        catch (ServletException se)
+        {
+            Throwable cause = se.getRootCause();
+            if (cause instanceof InstantiationException)
+                throw (InstantiationException)cause;
+            if (cause instanceof IllegalAccessException)
+                throw (IllegalAccessException)cause;
+            throw se;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/ServletMapping.java b/src/java/org/eclipse/jetty/servlet/ServletMapping.java
new file mode 100644
index 0000000..25c0ae0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/ServletMapping.java
@@ -0,0 +1,113 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+
+public class ServletMapping
+{
+    private String[] _pathSpecs;
+    private String _servletName;
+    private boolean _default;
+    
+
+    /* ------------------------------------------------------------ */
+    public ServletMapping()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the pathSpecs.
+     */
+    public String[] getPathSpecs()
+    {
+        return _pathSpecs;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the servletName.
+     */
+    public String getServletName()
+    {
+        return _servletName;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpecs The pathSpecs to set.
+     */
+    public void setPathSpecs(String[] pathSpecs)
+    {
+        _pathSpecs = pathSpecs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param pathSpec The pathSpec to set.
+     */
+    public void setPathSpec(String pathSpec)
+    {
+        _pathSpecs = new String[]{pathSpec};
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletName The servletName to set.
+     */
+    public void setServletName(String servletName)
+    {
+        _servletName = servletName;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return
+     */
+    public boolean isDefault()
+    {
+        return _default;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param default1
+     */
+    public void setDefault(boolean fromDefault)
+    {
+        _default = fromDefault;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return (_pathSpecs==null?"[]":Arrays.asList(_pathSpecs).toString())+"=>"+_servletName; 
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        out.append(String.valueOf(this)).append("\n");
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/StatisticsServlet.java b/src/java/org/eclipse/jetty/servlet/StatisticsServlet.java
new file mode 100644
index 0000000..6da92bb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/StatisticsServlet.java
@@ -0,0 +1,247 @@
+//
+//  ========================================================================
+//  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.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public class StatisticsServlet extends HttpServlet
+{
+    private static final Logger LOG = Log.getLogger(StatisticsServlet.class);
+
+    boolean _restrictToLocalhost = true; // defaults to true
+    private StatisticsHandler _statsHandler;
+    private MemoryMXBean _memoryBean;
+    private Connector[] _connectors;
+
+    public void init() throws ServletException
+    {
+        ServletContext context = getServletContext();
+        ContextHandler.Context scontext = (ContextHandler.Context) context;
+        Server _server = scontext.getContextHandler().getServer();
+
+        Handler handler = _server.getChildHandlerByClass(StatisticsHandler.class);
+
+        if (handler != null)
+        {
+            _statsHandler = (StatisticsHandler) handler;
+        }
+        else
+        {
+            LOG.warn("Statistics Handler not installed!");
+            return;
+        }
+        
+        _memoryBean = ManagementFactory.getMemoryMXBean();
+        _connectors = _server.getConnectors();
+
+        if (getInitParameter("restrictToLocalhost") != null)
+        {
+            _restrictToLocalhost = "true".equals(getInitParameter("restrictToLocalhost"));
+        }
+
+    }
+
+    public void doPost(HttpServletRequest sreq, HttpServletResponse sres) throws ServletException, IOException
+    {
+        doGet(sreq, sres);
+    }
+
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+    {
+        if (_statsHandler == null)
+        {
+            LOG.warn("Statistics Handler not installed!");
+            resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+            return;
+        }
+        if (_restrictToLocalhost)
+        {
+            if (!isLoopbackAddress(req.getRemoteAddr()))
+            {
+                resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                return;
+            }
+        }
+
+        String wantXml = req.getParameter("xml");
+        if (wantXml == null)
+          wantXml = req.getParameter("XML");
+
+        if (wantXml != null && "true".equalsIgnoreCase(wantXml))
+        {
+            sendXmlResponse(resp);
+        }
+        else
+        {
+            sendTextResponse(resp);
+        }
+
+    }
+
+    private boolean isLoopbackAddress(String address)
+    {
+        try
+        {
+            InetAddress addr = InetAddress.getByName(address); 
+            return addr.isLoopbackAddress();
+        }
+        catch (UnknownHostException e )
+        {
+            LOG.warn("Warning: attempt to access statistics servlet from " + address, e);
+            return false;
+        }
+    }
+
+    private void sendXmlResponse(HttpServletResponse response) throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<statistics>\n");
+
+        sb.append("  <requests>\n");
+        sb.append("    <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
+        
+        sb.append("    <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
+        sb.append("    <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
+        sb.append("    <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
+        sb.append("    <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
+        sb.append("    <requestsTimeMean>").append(_statsHandler.getRequestTimeMean()).append("</requestsTimeMean>\n");
+        sb.append("    <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
+        sb.append("    <requestsTimeStdDev>").append(_statsHandler.getRequestTimeStdDev()).append("</requestsTimeStdDev>\n");
+
+        sb.append("    <dispatched>").append(_statsHandler.getDispatched()).append("</dispatched>\n");
+        sb.append("    <dispatchedActive>").append(_statsHandler.getDispatchedActive()).append("</dispatchedActive>\n");
+        sb.append("    <dispatchedActiveMax>").append(_statsHandler.getDispatchedActiveMax()).append("</dispatchedActiveMax>\n");
+        sb.append("    <dispatchedTimeTotal>").append(_statsHandler.getDispatchedTimeTotal()).append("</dispatchedTimeTotal>\n");
+        sb.append("    <dispatchedTimeMean>").append(_statsHandler.getDispatchedTimeMean()).append("</dispatchedTimeMean>\n");
+        sb.append("    <dispatchedTimeMax>").append(_statsHandler.getDispatchedTimeMax()).append("</dispatchedTimeMax>\n");
+        sb.append("    <dispatchedTimeStdDev").append(_statsHandler.getDispatchedTimeStdDev()).append("</dispatchedTimeStdDev>\n");
+        
+        sb.append("    <requestsSuspended>").append(_statsHandler.getSuspends()).append("</requestsSuspended>\n");
+        sb.append("    <requestsExpired>").append(_statsHandler.getExpires()).append("</requestsExpired>\n");
+        sb.append("    <requestsResumed>").append(_statsHandler.getResumes()).append("</requestsResumed>\n");
+        sb.append("  </requests>\n");
+
+        sb.append("  <responses>\n");
+        sb.append("    <responses1xx>").append(_statsHandler.getResponses1xx()).append("</responses1xx>\n");
+        sb.append("    <responses2xx>").append(_statsHandler.getResponses2xx()).append("</responses2xx>\n");
+        sb.append("    <responses3xx>").append(_statsHandler.getResponses3xx()).append("</responses3xx>\n");
+        sb.append("    <responses4xx>").append(_statsHandler.getResponses4xx()).append("</responses4xx>\n");
+        sb.append("    <responses5xx>").append(_statsHandler.getResponses5xx()).append("</responses5xx>\n");
+        sb.append("    <responsesBytesTotal>").append(_statsHandler.getResponsesBytesTotal()).append("</responsesBytesTotal>\n");
+        sb.append("  </responses>\n");
+
+        sb.append("  <connections>\n");
+        for (Connector connector : _connectors)
+        {
+        	sb.append("    <connector>\n");
+        	sb.append("      <name>").append(connector.getName()).append("</name>\n");
+        	sb.append("      <statsOn>").append(connector.getStatsOn()).append("</statsOn>\n");
+            if (connector.getStatsOn())
+            {
+            	sb.append("    <statsOnMs>").append(connector.getStatsOnMs()).append("</statsOnMs>\n");
+            	sb.append("    <connections>").append(connector.getConnections()).append("</connections>\n");
+            	sb.append("    <connectionsOpen>").append(connector.getConnectionsOpen()).append("</connectionsOpen>\n");
+            	sb.append("    <connectionsOpenMax>").append(connector.getConnectionsOpenMax()).append("</connectionsOpenMax>\n");
+            	sb.append("    <connectionsDurationTotal>").append(connector.getConnectionsDurationTotal()).append("</connectionsDurationTotal>\n");
+            	sb.append("    <connectionsDurationMean>").append(connector.getConnectionsDurationMean()).append("</connectionsDurationMean>\n");
+            	sb.append("    <connectionsDurationMax>").append(connector.getConnectionsDurationMax()).append("</connectionsDurationMax>\n");
+                sb.append("    <connectionsDurationStdDev>").append(connector.getConnectionsDurationStdDev()).append("</connectionsDurationStdDev>\n");
+                sb.append("    <requests>").append(connector.getRequests()).append("</requests>\n");
+                sb.append("    <connectionsRequestsMean>").append(connector.getConnectionsRequestsMean()).append("</connectionsRequestsMean>\n");
+                sb.append("    <connectionsRequestsMax>").append(connector.getConnectionsRequestsMax()).append("</connectionsRequestsMax>\n");
+                sb.append("    <connectionsRequestsStdDev>").append(connector.getConnectionsRequestsStdDev()).append("</connectionsRequestsStdDev>\n");
+            }
+            sb.append("    </connector>\n");
+        }
+        sb.append("  </connections>\n");
+
+        sb.append("  <memory>\n");
+        sb.append("    <heapMemoryUsage>").append(_memoryBean.getHeapMemoryUsage().getUsed()).append("</heapMemoryUsage>\n");
+        sb.append("    <nonHeapMemoryUsage>").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append("</nonHeapMemoryUsage>\n");
+        sb.append("  </memory>\n");
+
+        sb.append("</statistics>\n");
+
+        response.setContentType("text/xml");
+        PrintWriter pout = response.getWriter();
+        pout.write(sb.toString());
+    }
+
+    private void sendTextResponse(HttpServletResponse response) throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(_statsHandler.toStatsHTML());
+
+        sb.append("<h2>Connections:</h2>\n");
+        for (Connector connector : _connectors)
+        {
+            sb.append("<h3>").append(connector.getName()).append("</h3>");
+
+            if (connector.getStatsOn())
+            {
+                sb.append("Statistics gathering started ").append(connector.getStatsOnMs()).append("ms ago").append("<br />\n");
+                sb.append("Total connections: ").append(connector.getConnections()).append("<br />\n");
+                sb.append("Current connections open: ").append(connector.getConnectionsOpen()).append("<br />\n");
+                sb.append("Max concurrent connections open: ").append(connector.getConnectionsOpenMax()).append("<br />\n");
+                sb.append("Total connections duration: ").append(connector.getConnectionsDurationTotal()).append("<br />\n");
+                sb.append("Mean connection duration: ").append(connector.getConnectionsDurationMean()).append("<br />\n");
+                sb.append("Max connection duration: ").append(connector.getConnectionsDurationMax()).append("<br />\n");
+                sb.append("Connection duration standard deviation: ").append(connector.getConnectionsDurationStdDev()).append("<br />\n");
+                sb.append("Total requests: ").append(connector.getRequests()).append("<br />\n");
+                sb.append("Mean requests per connection: ").append(connector.getConnectionsRequestsMean()).append("<br />\n");
+                sb.append("Max requests per connection: ").append(connector.getConnectionsRequestsMax()).append("<br />\n");
+                sb.append("Requests per connection standard deviation: ").append(connector.getConnectionsRequestsStdDev()).append("<br />\n");
+            }
+            else
+            {
+                sb.append("Statistics gathering off.\n");
+            }
+
+        }
+
+        sb.append("<h2>Memory:</h2>\n");
+        sb.append("Heap memory usage: ").append(_memoryBean.getHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
+        sb.append("Non-heap memory usage: ").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
+
+        response.setContentType("text/html");
+        PrintWriter pout = response.getWriter();
+        pout.write(sb.toString());
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/jmx/FilterMappingMBean.java b/src/java/org/eclipse/jetty/servlet/jmx/FilterMappingMBean.java
new file mode 100644
index 0000000..5521edc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/jmx/FilterMappingMBean.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.servlet.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.servlet.FilterMapping;
+
+public class FilterMappingMBean extends ObjectMBean
+{
+
+    public FilterMappingMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    public String getObjectNameBasis()
+    {
+        if (_managed != null && _managed instanceof FilterMapping)
+        {
+            FilterMapping mapping = (FilterMapping)_managed;
+            String name = mapping.getFilterName();
+            if (name != null)
+                return name;
+        }
+        
+        return super.getObjectNameBasis();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/jmx/HolderMBean.java b/src/java/org/eclipse/jetty/servlet/jmx/HolderMBean.java
new file mode 100644
index 0000000..5e1ec23
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/jmx/HolderMBean.java
@@ -0,0 +1,43 @@
+//
+//  ========================================================================
+//  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.servlet.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.servlet.Holder;
+
+public class HolderMBean extends ObjectMBean
+{
+    public HolderMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getObjectNameBasis()
+    {
+        if (_managed!=null && _managed instanceof Holder)
+        {
+            Holder holder = (Holder)_managed;
+            String name = holder.getName();
+            if (name!=null)
+                return name;
+        }
+        return super.getObjectNameBasis();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/jmx/ServletMappingMBean.java b/src/java/org/eclipse/jetty/servlet/jmx/ServletMappingMBean.java
new file mode 100644
index 0000000..a7c9898
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/jmx/ServletMappingMBean.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.servlet.jmx;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.servlet.ServletMapping;
+
+public class ServletMappingMBean extends ObjectMBean
+{
+
+    public ServletMappingMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    public String getObjectNameBasis()
+    {
+        if (_managed != null && _managed instanceof ServletMapping)
+        {
+            ServletMapping mapping = (ServletMapping)_managed;
+            String name = mapping.getServletName();
+            if (name != null)
+                return name;
+        }
+        
+        return super.getObjectNameBasis();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java b/src/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java
new file mode 100644
index 0000000..6af3c8e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java
@@ -0,0 +1,126 @@
+//
+//  ========================================================================
+//  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.servlet.listener;
+
+import java.lang.reflect.Field;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * ELContextCleaner
+ *
+ * Clean up BeanELResolver when the context is going out
+ * of service:
+ * 
+ * See http://java.net/jira/browse/GLASSFISH-1649
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=353095
+ */
+public class ELContextCleaner implements ServletContextListener
+{
+    private static final Logger LOG = Log.getLogger(ELContextCleaner.class);
+
+
+    public void contextInitialized(ServletContextEvent sce)
+    {
+    }
+
+    public void contextDestroyed(ServletContextEvent sce)
+    {
+        try
+        {
+            //Check that the BeanELResolver class is on the classpath
+            Class beanELResolver = Loader.loadClass(this.getClass(), "javax.el.BeanELResolver");
+
+            //Get a reference via reflection to the properties field which is holding class references
+            Field field = getField(beanELResolver);
+
+            //Get rid of references
+            purgeEntries(field);
+            
+            LOG.info("javax.el.BeanELResolver purged");
+        }
+        
+        catch (ClassNotFoundException e)
+        {
+            //BeanELResolver not on classpath, ignore
+        }
+        catch (SecurityException e)
+        {
+            LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
+        }
+        catch (IllegalArgumentException e)
+        {
+            LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
+        }
+        catch (NoSuchFieldException e)
+        {
+            LOG.info("Not cleaning cached beans: no such field javax.el.BeanELResolver.properties");
+        }
+       
+    }
+
+
+    protected Field getField (Class beanELResolver) 
+    throws SecurityException, NoSuchFieldException
+    {
+        if (beanELResolver == null)
+            return  null;
+
+        return beanELResolver.getDeclaredField("properties");
+    }
+
+    protected void purgeEntries (Field properties) 
+    throws IllegalArgumentException, IllegalAccessException
+    {
+        if (properties == null)
+            return;
+
+        if (!properties.isAccessible())
+            properties.setAccessible(true);
+
+        ConcurrentHashMap map = (ConcurrentHashMap) properties.get(null);
+        if (map == null)
+            return;
+        
+        Iterator<Class> itor = map.keySet().iterator();
+        while (itor.hasNext()) 
+        {
+            Class clazz = itor.next();
+            LOG.info("Clazz: "+clazz+" loaded by "+clazz.getClassLoader());
+            if (Thread.currentThread().getContextClassLoader().equals(clazz.getClassLoader()))
+            {
+                itor.remove();  
+                LOG.info("removed");
+            }
+            else
+                LOG.info("not removed: "+"contextclassloader="+Thread.currentThread().getContextClassLoader()+"clazz's classloader="+clazz.getClassLoader());
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlet/listener/IntrospectorCleaner.java b/src/java/org/eclipse/jetty/servlet/listener/IntrospectorCleaner.java
new file mode 100644
index 0000000..72a6f0d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlet/listener/IntrospectorCleaner.java
@@ -0,0 +1,45 @@
+//
+//  ========================================================================
+//  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.servlet.listener;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * IntrospectorCleaner
+ *
+ * Cleans a static cache of Methods held by java.beans.Introspector
+ * class when a context is undeployed.
+ * 
+ * @see java.beans.Introspector
+ */
+public class IntrospectorCleaner implements ServletContextListener
+{
+
+    public void contextInitialized(ServletContextEvent sce)
+    {
+        
+    }
+
+    public void contextDestroyed(ServletContextEvent sce)
+    {
+        java.beans.Introspector.flushCaches();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlets/BalancerServlet.java b/src/java/org/eclipse/jetty/servlets/BalancerServlet.java
new file mode 100644
index 0000000..f3e6140
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/BalancerServlet.java
@@ -0,0 +1,422 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.server.Request;
+
+/**
+ * 6
+ */
+public class BalancerServlet extends ProxyServlet
+{
+
+    private static final class BalancerMember
+    {
+
+        private String _name;
+
+        private String _proxyTo;
+
+        private HttpURI _backendURI;
+
+        public BalancerMember(String name, String proxyTo)
+        {
+            super();
+            _name = name;
+            _proxyTo = proxyTo;
+            _backendURI = new HttpURI(_proxyTo);
+        }
+
+        public String getProxyTo()
+        {
+            return _proxyTo;
+        }
+
+        public HttpURI getBackendURI()
+        {
+            return _backendURI;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "BalancerMember [_name=" + _name + ", _proxyTo=" + _proxyTo + "]";
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((_name == null)?0:_name.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            BalancerMember other = (BalancerMember)obj;
+            if (_name == null)
+            {
+                if (other._name != null)
+                    return false;
+            }
+            else if (!_name.equals(other._name))
+                return false;
+            return true;
+        }
+
+    }
+
+    private static final class RoundRobinIterator implements Iterator<BalancerMember>
+    {
+
+        private BalancerMember[] _balancerMembers;
+
+        private AtomicInteger _index;
+
+        public RoundRobinIterator(Collection<BalancerMember> balancerMembers)
+        {
+            _balancerMembers = (BalancerMember[])balancerMembers.toArray(new BalancerMember[balancerMembers.size()]);
+            _index = new AtomicInteger(-1);
+        }
+
+        public boolean hasNext()
+        {
+            return true;
+        }
+
+        public BalancerMember next()
+        {
+            BalancerMember balancerMember = null;
+            while (balancerMember == null)
+            {
+                int currentIndex = _index.get();
+                int nextIndex = (currentIndex + 1) % _balancerMembers.length;
+                if (_index.compareAndSet(currentIndex,nextIndex))
+                {
+                    balancerMember = _balancerMembers[nextIndex];
+                }
+            }
+            return balancerMember;
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+    }
+
+    private static final String BALANCER_MEMBER_PREFIX = "BalancerMember.";
+
+    private static final List<String> FORBIDDEN_CONFIG_PARAMETERS;
+    static
+    {
+        List<String> params = new LinkedList<String>();
+        params.add("HostHeader");
+        params.add("whiteList");
+        params.add("blackList");
+        FORBIDDEN_CONFIG_PARAMETERS = Collections.unmodifiableList(params);
+    }
+
+    private static final List<String> REVERSE_PROXY_HEADERS;
+    static
+    {
+        List<String> params = new LinkedList<String>();
+        params.add("Location");
+        params.add("Content-Location");
+        params.add("URI");
+        REVERSE_PROXY_HEADERS = Collections.unmodifiableList(params);
+    }
+
+    private static final String JSESSIONID = "jsessionid";
+
+    private static final String JSESSIONID_URL_PREFIX = JSESSIONID + "=";
+
+    private boolean _stickySessions;
+
+    private Set<BalancerMember> _balancerMembers = new HashSet<BalancerMember>();
+
+    private boolean _proxyPassReverse;
+
+    private RoundRobinIterator _roundRobinIterator;
+
+    @Override
+    public void init(ServletConfig config) throws ServletException
+    {
+        validateConfig(config);
+        super.init(config);
+        initStickySessions(config);
+        initBalancers(config);
+        initProxyPassReverse(config);
+        postInit();
+    }
+
+    private void validateConfig(ServletConfig config) throws ServletException
+    {
+        @SuppressWarnings("unchecked")
+        List<String> initParameterNames = Collections.list(config.getInitParameterNames());
+        for (String initParameterName : initParameterNames)
+        {
+            if (FORBIDDEN_CONFIG_PARAMETERS.contains(initParameterName))
+            {
+                throw new UnavailableException(initParameterName + " not supported in " + getClass().getName());
+            }
+        }
+    }
+
+    private void initStickySessions(ServletConfig config) throws ServletException
+    {
+        _stickySessions = "true".equalsIgnoreCase(config.getInitParameter("StickySessions"));
+    }
+
+    private void initBalancers(ServletConfig config) throws ServletException
+    {
+        Set<String> balancerNames = getBalancerNames(config);
+        for (String balancerName : balancerNames)
+        {
+            String memberProxyToParam = BALANCER_MEMBER_PREFIX + balancerName + ".ProxyTo";
+            String proxyTo = config.getInitParameter(memberProxyToParam);
+            if (proxyTo == null || proxyTo.trim().length() == 0)
+            {
+                throw new UnavailableException(memberProxyToParam + " parameter is empty.");
+            }
+            _balancerMembers.add(new BalancerMember(balancerName,proxyTo));
+        }
+    }
+
+    private void initProxyPassReverse(ServletConfig config)
+    {
+        _proxyPassReverse = "true".equalsIgnoreCase(config.getInitParameter("ProxyPassReverse"));
+    }
+
+    private void postInit()
+    {
+        _roundRobinIterator = new RoundRobinIterator(_balancerMembers);
+    }
+
+    private Set<String> getBalancerNames(ServletConfig config) throws ServletException
+    {
+        Set<String> names = new HashSet<String>();
+        @SuppressWarnings("unchecked")
+        List<String> initParameterNames = Collections.list(config.getInitParameterNames());
+        for (String initParameterName : initParameterNames)
+        {
+            if (!initParameterName.startsWith(BALANCER_MEMBER_PREFIX))
+            {
+                continue;
+            }
+            int endOfNameIndex = initParameterName.lastIndexOf(".");
+            if (endOfNameIndex <= BALANCER_MEMBER_PREFIX.length())
+            {
+                throw new UnavailableException(initParameterName + " parameter does not provide a balancer member name");
+            }
+            names.add(initParameterName.substring(BALANCER_MEMBER_PREFIX.length(),endOfNameIndex));
+        }
+        return names;
+    }
+
+    @Override
+    protected HttpURI proxyHttpURI(HttpServletRequest request, String uri) throws MalformedURLException
+    {
+        BalancerMember balancerMember = selectBalancerMember(request);
+        try
+        {
+            URI dstUri = new URI(balancerMember.getProxyTo() + "/" + uri).normalize();
+            return new HttpURI(dstUri.toString());
+        }
+        catch (URISyntaxException e)
+        {
+            throw new MalformedURLException(e.getMessage());
+        }
+    }
+
+    private BalancerMember selectBalancerMember(HttpServletRequest request)
+    {
+        BalancerMember balancerMember = null;
+        if (_stickySessions)
+        {
+            String name = getBalancerMemberNameFromSessionId(request);
+            if (name != null)
+            {
+                balancerMember = findBalancerMemberByName(name);
+                if (balancerMember != null)
+                {
+                    return balancerMember;
+                }
+            }
+        }
+        return _roundRobinIterator.next();
+    }
+
+    private BalancerMember findBalancerMemberByName(String name)
+    {
+        BalancerMember example = new BalancerMember(name,"");
+        for (BalancerMember balancerMember : _balancerMembers)
+        {
+            if (balancerMember.equals(example))
+            {
+                return balancerMember;
+            }
+        }
+        return null;
+    }
+
+    private String getBalancerMemberNameFromSessionId(HttpServletRequest request)
+    {
+        String name = getBalancerMemberNameFromSessionCookie(request);
+        if (name == null)
+        {
+            name = getBalancerMemberNameFromURL(request);
+        }
+        return name;
+    }
+
+    private String getBalancerMemberNameFromSessionCookie(HttpServletRequest request)
+    {
+        Cookie[] cookies = request.getCookies();
+        String name = null;
+        for (Cookie cookie : cookies)
+        {
+            if (JSESSIONID.equalsIgnoreCase(cookie.getName()))
+            {
+                name = extractBalancerMemberNameFromSessionId(cookie.getValue());
+                break;
+            }
+        }
+        return name;
+    }
+
+    private String getBalancerMemberNameFromURL(HttpServletRequest request)
+    {
+        String name = null;
+        String requestURI = request.getRequestURI();
+        int idx = requestURI.lastIndexOf(";");
+        if (idx != -1)
+        {
+            String requestURISuffix = requestURI.substring(idx);
+            if (requestURISuffix.startsWith(JSESSIONID_URL_PREFIX))
+            {
+                name = extractBalancerMemberNameFromSessionId(requestURISuffix.substring(JSESSIONID_URL_PREFIX.length()));
+            }
+        }
+        return name;
+    }
+
+    private String extractBalancerMemberNameFromSessionId(String sessionId)
+    {
+        String name = null;
+        int idx = sessionId.lastIndexOf(".");
+        if (idx != -1)
+        {
+            String sessionIdSuffix = sessionId.substring(idx + 1);
+            name = (sessionIdSuffix.length() > 0)?sessionIdSuffix:null;
+        }
+        return name;
+    }
+
+    @Override
+    protected String filterResponseHeaderValue(String headerName, String headerValue, HttpServletRequest request)
+    {
+        if (_proxyPassReverse && REVERSE_PROXY_HEADERS.contains(headerName))
+        {
+            HttpURI locationURI = new HttpURI(headerValue);
+            if (isAbsoluteLocation(locationURI) && isBackendLocation(locationURI))
+            {
+                Request jettyRequest = (Request)request;
+                URI reverseUri;
+                try
+                {
+                    reverseUri = new URI(jettyRequest.getRootURL().append(locationURI.getCompletePath()).toString()).normalize();
+                    return reverseUri.toURL().toString();
+                }
+                catch (Exception e)
+                {
+                    _log.warn("Not filtering header response",e);
+                    return headerValue;
+                }
+            }
+        }
+        return headerValue;
+    }
+
+    private boolean isBackendLocation(HttpURI locationURI)
+    {
+        for (BalancerMember balancerMember : _balancerMembers)
+        {
+            HttpURI backendURI = balancerMember.getBackendURI();
+            if (backendURI.getHost().equals(locationURI.getHost()) && backendURI.getScheme().equals(locationURI.getScheme())
+                    && backendURI.getPort() == locationURI.getPort())
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isAbsoluteLocation(HttpURI locationURI)
+    {
+        return locationURI.getHost() != null;
+    }
+
+    @Override
+    public String getHostHeader()
+    {
+        throw new UnsupportedOperationException("HostHeader not supported in " + getClass().getName());
+    }
+
+    @Override
+    public void setHostHeader(String hostHeader)
+    {
+        throw new UnsupportedOperationException("HostHeader not supported in " + getClass().getName());
+    }
+
+    @Override
+    public boolean validateDestination(String host, String path)
+    {
+        return true;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlets/CGI.java b/src/java/org/eclipse/jetty/servlets/CGI.java
new file mode 100644
index 0000000..83b2457
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/CGI.java
@@ -0,0 +1,515 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+//-----------------------------------------------------------------------------
+/**
+ * CGI Servlet.
+ * <p/>
+ * The cgi bin directory can be set with the "cgibinResourceBase" init parameter or it will default to the resource base of the context. If the
+ * "cgibinResourceBaseIsRelative" init parameter is set the resource base is relative to the webapp. For example "WEB-INF/cgi" would work.
+ * <br/>
+ * Not that this only works for extracted war files as "jar cf" will not reserve the execute permissions on the cgi files.
+ * <p/>
+ * The "commandPrefix" init parameter may be used to set a prefix to all commands passed to exec. This can be used on systems that need assistance to execute a
+ * particular file type. For example on windows this can be set to "perl" so that perl scripts are executed.
+ * <p/>
+ * The "Path" init param is passed to the exec environment as PATH. Note: Must be run unpacked somewhere in the filesystem.
+ * <p/>
+ * Any initParameter that starts with ENV_ is used to set an environment variable with the name stripped of the leading ENV_ and using the init parameter value.
+ */
+public class CGI extends HttpServlet
+{
+    /**
+     *
+     */
+    private static final long serialVersionUID = -6182088932884791073L;
+
+    private static final Logger LOG = Log.getLogger(CGI.class);
+
+    private boolean _ok;
+    private File _docRoot;
+    private String _path;
+    private String _cmdPrefix;
+    private EnvList _env;
+    private boolean _ignoreExitState;
+    private boolean _relative;
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void init() throws ServletException
+    {
+        _env = new EnvList();
+        _cmdPrefix = getInitParameter("commandPrefix");
+        _relative = Boolean.parseBoolean(getInitParameter("cgibinResourceBaseIsRelative"));
+
+        String tmp = getInitParameter("cgibinResourceBase");
+        if (tmp == null)
+        {
+            tmp = getInitParameter("resourceBase");
+            if (tmp == null)
+                tmp = getServletContext().getRealPath("/");
+        }
+        else if (_relative)
+        {
+            tmp = getServletContext().getRealPath(tmp);
+        }
+
+        if (tmp == null)
+        {
+            LOG.warn("CGI: no CGI bin !");
+            return;
+        }
+
+        File dir = new File(tmp);
+        if (!dir.exists())
+        {
+            LOG.warn("CGI: CGI bin does not exist - " + dir);
+            return;
+        }
+
+        if (!dir.canRead())
+        {
+            LOG.warn("CGI: CGI bin is not readable - " + dir);
+            return;
+        }
+
+        if (!dir.isDirectory())
+        {
+            LOG.warn("CGI: CGI bin is not a directory - " + dir);
+            return;
+        }
+
+        try
+        {
+            _docRoot = dir.getCanonicalFile();
+        }
+        catch (IOException e)
+        {
+            LOG.warn("CGI: CGI bin failed - " + dir,e);
+            return;
+        }
+
+        _path = getInitParameter("Path");
+        if (_path != null)
+            _env.set("PATH",_path);
+
+        _ignoreExitState = "true".equalsIgnoreCase(getInitParameter("ignoreExitState"));
+        Enumeration e = getInitParameterNames();
+        while (e.hasMoreElements())
+        {
+            String n = (String)e.nextElement();
+            if (n != null && n.startsWith("ENV_"))
+                _env.set(n.substring(4),getInitParameter(n));
+        }
+        if (!_env.envMap.containsKey("SystemRoot"))
+        {
+            String os = System.getProperty("os.name");
+            if (os != null && os.toLowerCase(Locale.ENGLISH).indexOf("windows") != -1)
+            {
+                _env.set("SystemRoot","C:\\WINDOWS");
+            }
+        }
+
+        _ok = true;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+    {
+        if (!_ok)
+        {
+            res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+            return;
+        }
+
+        String pathInContext = (_relative?"":StringUtil.nonNull(req.getServletPath())) + StringUtil.nonNull(req.getPathInfo());
+        if (LOG.isDebugEnabled())
+        {
+            LOG.debug("CGI: ContextPath : " + req.getContextPath());
+            LOG.debug("CGI: ServletPath : " + req.getServletPath());
+            LOG.debug("CGI: PathInfo    : " + req.getPathInfo());
+            LOG.debug("CGI: _docRoot    : " + _docRoot);
+            LOG.debug("CGI: _path       : " + _path);
+            LOG.debug("CGI: _ignoreExitState: " + _ignoreExitState);
+        }
+
+        // pathInContext may actually comprises scriptName/pathInfo...We will
+        // walk backwards up it until we find the script - the rest must
+        // be the pathInfo;
+
+        String both = pathInContext;
+        String first = both;
+        String last = "";
+
+        File exe = new File(_docRoot,first);
+
+        while ((first.endsWith("/") || !exe.exists()) && first.length() >= 0)
+        {
+            int index = first.lastIndexOf('/');
+
+            first = first.substring(0,index);
+            last = both.substring(index,both.length());
+            exe = new File(_docRoot,first);
+        }
+
+        if (first.length() == 0 || !exe.exists() || exe.isDirectory() || !exe.getCanonicalPath().equals(exe.getAbsolutePath()))
+        {
+            res.sendError(404);
+        }
+        else
+        {
+            if (LOG.isDebugEnabled())
+            {
+                LOG.debug("CGI: script is " + exe);
+                LOG.debug("CGI: pathInfo is " + last);
+            }
+            exec(exe,last,req,res);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @param root @param path @param req @param res @exception IOException
+     */
+    private void exec(File command, String pathInfo, HttpServletRequest req, HttpServletResponse res) throws IOException
+    {
+        String path = command.getAbsolutePath();
+        File dir = command.getParentFile();
+        String scriptName = req.getRequestURI().substring(0,req.getRequestURI().length() - pathInfo.length());
+        String scriptPath = getServletContext().getRealPath(scriptName);
+        String pathTranslated = req.getPathTranslated();
+
+        int len = req.getContentLength();
+        if (len < 0)
+            len = 0;
+        if ((pathTranslated == null) || (pathTranslated.length() == 0))
+            pathTranslated = path;
+
+        String bodyFormEncoded = null;
+        if ((HttpMethods.POST.equals(req.getMethod()) || HttpMethods.PUT.equals(req.getMethod())) && "application/x-www-form-urlencoded".equals(req.getContentType()))
+        {
+            MultiMap<String> parameterMap = new MultiMap<String>();
+            Enumeration names = req.getParameterNames();
+            while (names.hasMoreElements())
+            {
+                String parameterName = (String)names.nextElement();
+                parameterMap.addValues(parameterName, req.getParameterValues(parameterName));
+            }
+            bodyFormEncoded = UrlEncoded.encode(parameterMap, req.getCharacterEncoding(), true);
+        }
+
+        EnvList env = new EnvList(_env);
+        // these ones are from "The WWW Common Gateway Interface Version 1.1"
+        // look at :
+        // http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1
+        env.set("AUTH_TYPE", req.getAuthType());
+        if (bodyFormEncoded != null)
+        {
+            env.set("CONTENT_LENGTH", Integer.toString(bodyFormEncoded.length()));
+        }
+        else
+        {
+            env.set("CONTENT_LENGTH", Integer.toString(len));
+        }
+        env.set("CONTENT_TYPE", req.getContentType());
+        env.set("GATEWAY_INTERFACE", "CGI/1.1");
+        if ((pathInfo != null) && (pathInfo.length() > 0))
+        {
+            env.set("PATH_INFO", pathInfo);
+        }
+        env.set("PATH_TRANSLATED", pathTranslated);
+        env.set("QUERY_STRING", req.getQueryString());
+        env.set("REMOTE_ADDR", req.getRemoteAddr());
+        env.set("REMOTE_HOST", req.getRemoteHost());
+        // The identity information reported about the connection by a
+        // RFC 1413 [11] request to the remote agent, if
+        // available. Servers MAY choose not to support this feature, or
+        // not to request the data for efficiency reasons.
+        // "REMOTE_IDENT" => "NYI"
+        env.set("REMOTE_USER", req.getRemoteUser());
+        env.set("REQUEST_METHOD", req.getMethod());
+        env.set("SCRIPT_NAME", scriptName);
+        env.set("SCRIPT_FILENAME", scriptPath);
+        env.set("SERVER_NAME", req.getServerName());
+        env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
+        env.set("SERVER_PROTOCOL", req.getProtocol());
+        env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());
+
+        Enumeration enm = req.getHeaderNames();
+        while (enm.hasMoreElements())
+        {
+            String name = (String)enm.nextElement();
+            String value = req.getHeader(name);
+            env.set("HTTP_" + name.toUpperCase(Locale.ENGLISH).replace('-','_'),value);
+        }
+
+        // these extra ones were from printenv on www.dev.nomura.co.uk
+        env.set("HTTPS", (req.isSecure()?"ON":"OFF"));
+        // "DOCUMENT_ROOT" => root + "/docs",
+        // "SERVER_URL" => "NYI - http://us0245",
+        // "TZ" => System.getProperty("user.timezone"),
+
+        // are we meant to decode args here ? or does the script get them
+        // via PATH_INFO ? if we are, they should be decoded and passed
+        // into exec here...
+        String execCmd = path;
+        if ((execCmd.charAt(0) != '"') && (execCmd.indexOf(" ") >= 0))
+            execCmd = "\"" + execCmd + "\"";
+        if (_cmdPrefix != null)
+            execCmd = _cmdPrefix + " " + execCmd;
+
+        LOG.debug("Environment: " + env.getExportString());
+        LOG.debug("Command: " + execCmd);
+
+        Process p;
+        if (dir == null)
+            p = Runtime.getRuntime().exec(execCmd, env.getEnvArray());
+        else
+            p = Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir);
+
+        // hook processes input to browser's output (async)
+        if (bodyFormEncoded != null)
+            writeProcessInput(p, bodyFormEncoded);
+        else if (len > 0)
+            writeProcessInput(p, req.getInputStream(), len);
+
+        IO.copyThread(p.getErrorStream(), System.err);
+
+        // hook processes output to browser's input (sync)
+        // if browser closes stream, we should detect it and kill process...
+        OutputStream os = null;
+        try
+        {
+            // read any headers off the top of our input stream
+            // NOTE: Multiline header items not supported!
+            String line = null;
+            InputStream inFromCgi = p.getInputStream();
+
+            // br=new BufferedReader(new InputStreamReader(inFromCgi));
+            // while ((line=br.readLine())!=null)
+            while ((line = getTextLineFromStream(inFromCgi)).length() > 0)
+            {
+                if (!line.startsWith("HTTP"))
+                {
+                    int k = line.indexOf(':');
+                    if (k > 0)
+                    {
+                        String key = line.substring(0,k).trim();
+                        String value = line.substring(k + 1).trim();
+                        if ("Location".equals(key))
+                        {
+                            res.sendRedirect(res.encodeRedirectURL(value));
+                        }
+                        else if ("Status".equals(key))
+                        {
+                            String[] token = value.split(" ");
+                            int status = Integer.parseInt(token[0]);
+                            res.setStatus(status);
+                        }
+                        else
+                        {
+                            // add remaining header items to our response header
+                            res.addHeader(key,value);
+                        }
+                    }
+                }
+            }
+            // copy cgi content to response stream...
+            os = res.getOutputStream();
+            IO.copy(inFromCgi,os);
+            p.waitFor();
+
+            if (!_ignoreExitState)
+            {
+                int exitValue = p.exitValue();
+                if (0 != exitValue)
+                {
+                    LOG.warn("Non-zero exit status (" + exitValue + ") from CGI program: " + path);
+                    if (!res.isCommitted())
+                        res.sendError(500,"Failed to exec CGI");
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            // browser has probably closed its input stream - we
+            // terminate and clean up...
+            LOG.debug("CGI: Client closed connection!");
+        }
+        catch (InterruptedException ie)
+        {
+            LOG.debug("CGI: interrupted!");
+        }
+        finally
+        {
+            if (os != null)
+            {
+                try
+                {
+                    os.close();
+                }
+                catch (Exception e)
+                {
+                    LOG.debug(e);
+                }
+            }
+            p.destroy();
+            // LOG.debug("CGI: terminated!");
+        }
+    }
+
+    private static void writeProcessInput(final Process p, final String input)
+    {
+        new Thread(new Runnable()
+        {
+            public void run()
+            {
+                try
+                {
+                    Writer outToCgi = new OutputStreamWriter(p.getOutputStream());
+                    outToCgi.write(input);
+                    outToCgi.close();
+                }
+                catch (IOException e)
+                {
+                    LOG.debug(e);
+                }
+            }
+        }).start();
+    }
+
+    private static void writeProcessInput(final Process p, final InputStream input, final int len)
+    {
+        if (len <= 0) return;
+
+        new Thread(new Runnable()
+        {
+            public void run()
+            {
+                try
+                {
+                    OutputStream outToCgi = p.getOutputStream();
+                    IO.copy(input, outToCgi, len);
+                    outToCgi.close();
+                }
+                catch (IOException e)
+                {
+                    LOG.debug(e);
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * Utility method to get a line of text from the input stream.
+     *
+     * @param is
+     *            the input stream
+     * @return the line of text
+     * @throws IOException
+     */
+    private static String getTextLineFromStream(InputStream is) throws IOException
+    {
+        StringBuilder buffer = new StringBuilder();
+        int b;
+
+        while ((b = is.read()) != -1 && b != '\n')
+        {
+            buffer.append((char)b);
+        }
+        return buffer.toString().trim();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * private utility class that manages the Environment passed to exec.
+     */
+    private static class EnvList
+    {
+        private Map<String, String> envMap;
+
+        EnvList()
+        {
+            envMap = new HashMap<String, String>();
+        }
+
+        EnvList(EnvList l)
+        {
+            envMap = new HashMap<String,String>(l.envMap);
+        }
+
+        /**
+         * Set a name/value pair, null values will be treated as an empty String
+         */
+        public void set(String name, String value)
+        {
+            envMap.put(name,name + "=" + StringUtil.nonNull(value));
+        }
+
+        /** Get representation suitable for passing to exec. */
+        public String[] getEnvArray()
+        {
+            return envMap.values().toArray(new String[envMap.size()]);
+        }
+
+        public String getExportString()
+        {
+            StringBuilder sb = new StringBuilder();
+            for (String variable : getEnvArray())
+            {
+                sb.append("export \"");
+                sb.append(variable);
+                sb.append("\"; ");
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public String toString()
+        {
+            return envMap.toString();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java b/src/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java
new file mode 100644
index 0000000..90f780b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/CloseableDoSFilter.java
@@ -0,0 +1,53 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Closeable DoS Filter.
+ * This is an extension to the {@link DoSFilter} that uses Jetty APIs to allow
+ * connections to be closed cleanly. 
+ */
+
+public class CloseableDoSFilter extends DoSFilter
+{
+    private static final Logger LOG = Log.getLogger(CloseableDoSFilter.class);
+
+    protected void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread)
+    {
+        try
+        {
+            Request base_request=(request instanceof Request)?(Request)request:AbstractHttpConnection.getCurrentConnection().getRequest();
+            base_request.getConnection().getEndPoint().close();
+        }
+        catch(IOException e)
+        {
+            LOG.warn(e);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/ConcatServlet.java b/src/java/org/eclipse/jetty/servlets/ConcatServlet.java
new file mode 100644
index 0000000..d466813
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/ConcatServlet.java
@@ -0,0 +1,125 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/* ------------------------------------------------------------ */
+/** Concatenation Servlet
+ * This servlet may be used to concatenate multiple resources into
+ * a single response.  It is intended to be used to load multiple
+ * javascript or css files, but may be used for any content of the 
+ * same mime type that can be meaningfully concatenated.
+ * <p>
+ * The servlet uses {@link RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}
+ * to combine the requested content, so dynamically generated content
+ * may be combined (Eg engine.js for DWR).
+ * <p>
+ * The servlet uses parameter names of the query string as resource names
+ * relative to the context root.  So these script tags:
+ * <pre>
+ *  &lt;script type="text/javascript" src="../js/behaviour.js"&gt;&lt;/script&gt;
+ *  &lt;script type="text/javascript" src="../js/ajax.js&/chat/chat.js"&gt;&lt;/script&gt;
+ *  &lt;script type="text/javascript" src="../chat/chat.js"&gt;&lt;/script&gt;
+ * </pre> can be replaced with the single tag (with the ConcatServlet mapped to /concat):
+ * <pre>
+ *  &lt;script type="text/javascript" src="../concat?/js/behaviour.js&/js/ajax.js&/chat/chat.js"&gt;&lt;/script&gt;
+ * </pre>
+ * The {@link ServletContext#getMimeType(String)} method is used to determine the 
+ * mime type of each resource.  If the types of all resources do not match, then a 415 
+ * UNSUPPORTED_MEDIA_TYPE error is returned.
+ * <p>
+ * If the init parameter "development" is set to "true" then the servlet will run in
+ * development mode and the content will be concatenated on every request. Otherwise
+ * the init time of the servlet is used as the lastModifiedTime of the combined content
+ * and If-Modified-Since requests are handled with 206 NOT Modified responses if 
+ * appropriate. This means that when not in development mode, the servlet must be 
+ * restarted before changed content will be served.
+ * 
+ * 
+ *
+ */
+public class ConcatServlet extends HttpServlet
+{
+    boolean _development;
+    long _lastModified;
+    ServletContext _context;
+
+    /* ------------------------------------------------------------ */
+    public void init() throws ServletException
+    {
+        _lastModified=System.currentTimeMillis();
+        _context=getServletContext();   
+        _development="true".equals(getInitParameter("development"));
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @return The start time of the servlet unless in development mode, in which case -1 is returned.
+     */
+    protected long getLastModified(HttpServletRequest req)
+    {
+        return _development?-1:_lastModified;
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+    {
+        String q=req.getQueryString();
+        if (q==null)
+        {
+            resp.sendError(HttpServletResponse.SC_NO_CONTENT);
+            return;
+        }
+        
+        String[] parts = q.split("\\&");
+        String type=null;
+        for (int i=0;i<parts.length;i++)
+        {
+            String t = _context.getMimeType(parts[i]);
+            if (t!=null)
+            {
+                if (type==null)
+                    type=t;
+                else if (!type.equals(t))
+                {
+                    resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
+                    return;
+                }
+            }   
+        }
+
+        if (type!=null)
+            resp.setContentType(type);
+
+        for (int i=0;i<parts.length;i++)
+        {
+            RequestDispatcher dispatcher=_context.getRequestDispatcher(parts[i]);
+            if (dispatcher!=null)
+                dispatcher.include(req,resp);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/src/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
new file mode 100644
index 0000000..3c28b69
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -0,0 +1,426 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * <p>Implementation of the
+ * <a href="http://www.w3.org/TR/cors/">cross-origin resource sharing</a>.</p>
+ * <p>A typical example is to use this filter to allow cross-domain
+ * <a href="http://cometd.org">cometd</a> communication using the standard
+ * long polling transport instead of the JSONP transport (that is less
+ * efficient and less reactive to failures).</p>
+ * <p>This filter allows the following configuration parameters:
+ * <ul>
+ * <li><b>allowedOrigins</b>, a comma separated list of origins that are
+ * allowed to access the resources. Default value is <b>*</b>, meaning all
+ * origins.<br />
+ * If an allowed origin contains one or more * characters (for example
+ * http://*.domain.com), then "*" characters are converted to ".*", "."
+ * characters are escaped to "\." and the resulting allowed origin
+ * interpreted as a regular expression.<br />
+ * Allowed origins can therefore be more complex expressions such as
+ * https?://*.domain.[a-z]{3} that matches http or https, multiple subdomains
+ * and any 3 letter top-level domain (.com, .net, .org, etc.).</li>
+ * <li><b>allowedMethods</b>, a comma separated list of HTTP methods that
+ * are allowed to be used when accessing the resources. Default value is
+ * <b>GET,POST,HEAD</b></li>
+ * <li><b>allowedHeaders</b>, a comma separated list of HTTP headers that
+ * are allowed to be specified when accessing the resources. Default value
+ * is <b>X-Requested-With,Content-Type,Accept,Origin</b></li>
+ * <li><b>preflightMaxAge</b>, the number of seconds that preflight requests
+ * can be cached by the client. Default value is <b>1800</b> seconds, or 30
+ * minutes</li>
+ * <li><b>allowCredentials</b>, a boolean indicating if the resource allows
+ * requests with credentials. Default value is <b>false</b></li>
+ * <li><b>exposeHeaders</b>, a comma separated list of HTTP headers that
+ * are allowed to be exposed on the client. Default value is the
+ * <b>empty list</b></li>
+ * <li><b>chainPreflight</b>, if true preflight requests are chained to their
+ * target resource for normal handling (as an OPTION request).  Otherwise the 
+ * filter will response to the preflight. Default is true.</li>
+ * </ul></p>
+ * <p>A typical configuration could be:
+ * <pre>
+ * &lt;web-app ...&gt;
+ *     ...
+ *     &lt;filter&gt;
+ *         &lt;filter-name&gt;cross-origin&lt;/filter-name&gt;
+ *         &lt;filter-class&gt;org.eclipse.jetty.servlets.CrossOriginFilter&lt;/filter-class&gt;
+ *     &lt;/filter&gt;
+ *     &lt;filter-mapping&gt;
+ *         &lt;filter-name&gt;cross-origin&lt;/filter-name&gt;
+ *         &lt;url-pattern&gt;/cometd/*&lt;/url-pattern&gt;
+ *     &lt;/filter-mapping&gt;
+ *     ...
+ * &lt;/web-app&gt;
+ * </pre></p>
+ */
+public class CrossOriginFilter implements Filter
+{
+    private static final Logger LOG = Log.getLogger(CrossOriginFilter.class);
+
+    // Request headers
+    private static final String ORIGIN_HEADER = "Origin";
+    public static final String ACCESS_CONTROL_REQUEST_METHOD_HEADER = "Access-Control-Request-Method";
+    public static final String ACCESS_CONTROL_REQUEST_HEADERS_HEADER = "Access-Control-Request-Headers";
+    // Response headers
+    public static final String ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = "Access-Control-Allow-Origin";
+    public static final String ACCESS_CONTROL_ALLOW_METHODS_HEADER = "Access-Control-Allow-Methods";
+    public static final String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers";
+    public static final String ACCESS_CONTROL_MAX_AGE_HEADER = "Access-Control-Max-Age";
+    public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER = "Access-Control-Allow-Credentials";
+    public static final String ACCESS_CONTROL_EXPOSE_HEADERS_HEADER = "Access-Control-Expose-Headers";
+    // Implementation constants
+    public static final String ALLOWED_ORIGINS_PARAM = "allowedOrigins";
+    public static final String ALLOWED_METHODS_PARAM = "allowedMethods";
+    public static final String ALLOWED_HEADERS_PARAM = "allowedHeaders";
+    public static final String PREFLIGHT_MAX_AGE_PARAM = "preflightMaxAge";
+    public static final String ALLOW_CREDENTIALS_PARAM = "allowCredentials";
+    public static final String EXPOSED_HEADERS_PARAM = "exposedHeaders";
+    public static final String OLD_CHAIN_PREFLIGHT_PARAM = "forwardPreflight";
+    public static final String CHAIN_PREFLIGHT_PARAM = "chainPreflight";
+    private static final String ANY_ORIGIN = "*";
+    private static final List<String> SIMPLE_HTTP_METHODS = Arrays.asList("GET", "POST", "HEAD");
+
+    private boolean anyOriginAllowed;
+    private List<String> allowedOrigins = new ArrayList<String>();
+    private List<String> allowedMethods = new ArrayList<String>();
+    private List<String> allowedHeaders = new ArrayList<String>();
+    private List<String> exposedHeaders = new ArrayList<String>();
+    private int preflightMaxAge;
+    private boolean allowCredentials;
+    private boolean chainPreflight;
+
+    public void init(FilterConfig config) throws ServletException
+    {
+        String allowedOriginsConfig = config.getInitParameter(ALLOWED_ORIGINS_PARAM);
+        if (allowedOriginsConfig == null)
+            allowedOriginsConfig = "*";
+        String[] allowedOrigins = allowedOriginsConfig.split(",");
+        for (String allowedOrigin : allowedOrigins)
+        {
+            allowedOrigin = allowedOrigin.trim();
+            if (allowedOrigin.length() > 0)
+            {
+                if (ANY_ORIGIN.equals(allowedOrigin))
+                {
+                    anyOriginAllowed = true;
+                    this.allowedOrigins.clear();
+                    break;
+                }
+                else
+                {
+                    this.allowedOrigins.add(allowedOrigin);
+                }
+            }
+        }
+
+        String allowedMethodsConfig = config.getInitParameter(ALLOWED_METHODS_PARAM);
+        if (allowedMethodsConfig == null)
+            allowedMethodsConfig = "GET,POST,HEAD";
+        allowedMethods.addAll(Arrays.asList(allowedMethodsConfig.split(",")));
+
+        String allowedHeadersConfig = config.getInitParameter(ALLOWED_HEADERS_PARAM);
+        if (allowedHeadersConfig == null)
+            allowedHeadersConfig = "X-Requested-With,Content-Type,Accept,Origin";
+        allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig.split(",")));
+
+        String preflightMaxAgeConfig = config.getInitParameter(PREFLIGHT_MAX_AGE_PARAM);
+        if (preflightMaxAgeConfig == null)
+            preflightMaxAgeConfig = "1800"; // Default is 30 minutes
+        try
+        {
+            preflightMaxAge = Integer.parseInt(preflightMaxAgeConfig);
+        }
+        catch (NumberFormatException x)
+        {
+            LOG.info("Cross-origin filter, could not parse '{}' parameter as integer: {}", PREFLIGHT_MAX_AGE_PARAM, preflightMaxAgeConfig);
+        }
+
+        String allowedCredentialsConfig = config.getInitParameter(ALLOW_CREDENTIALS_PARAM);
+        if (allowedCredentialsConfig == null)
+            allowedCredentialsConfig = "true";
+        allowCredentials = Boolean.parseBoolean(allowedCredentialsConfig);
+
+        String exposedHeadersConfig = config.getInitParameter(EXPOSED_HEADERS_PARAM);
+        if (exposedHeadersConfig == null)
+            exposedHeadersConfig = "";
+        exposedHeaders.addAll(Arrays.asList(exposedHeadersConfig.split(",")));
+
+        String chainPreflightConfig = config.getInitParameter(OLD_CHAIN_PREFLIGHT_PARAM);
+        if (chainPreflightConfig!=null) // TODO remove this
+            LOG.warn("DEPRECATED CONFIGURATION: Use "+CHAIN_PREFLIGHT_PARAM+ " instead of "+OLD_CHAIN_PREFLIGHT_PARAM);
+        else
+            chainPreflightConfig = config.getInitParameter(CHAIN_PREFLIGHT_PARAM);
+        if (chainPreflightConfig == null)
+            chainPreflightConfig = "true";
+        chainPreflight = Boolean.parseBoolean(chainPreflightConfig);
+
+        if (LOG.isDebugEnabled())
+        {
+            LOG.debug("Cross-origin filter configuration: " +
+                    ALLOWED_ORIGINS_PARAM + " = " + allowedOriginsConfig + ", " +
+                    ALLOWED_METHODS_PARAM + " = " + allowedMethodsConfig + ", " +
+                    ALLOWED_HEADERS_PARAM + " = " + allowedHeadersConfig + ", " +
+                    PREFLIGHT_MAX_AGE_PARAM + " = " + preflightMaxAgeConfig + ", " +
+                    ALLOW_CREDENTIALS_PARAM + " = " + allowedCredentialsConfig + "," +
+                    EXPOSED_HEADERS_PARAM + " = " + exposedHeadersConfig + "," +
+                    CHAIN_PREFLIGHT_PARAM + " = " + chainPreflightConfig
+            );
+        }
+    }
+
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+    {
+        handle((HttpServletRequest)request, (HttpServletResponse)response, chain);
+    }
+
+    private void handle(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException
+    {
+        String origin = request.getHeader(ORIGIN_HEADER);
+        // Is it a cross origin request ?
+        if (origin != null && isEnabled(request))
+        {
+            if (originMatches(origin))
+            {
+                if (isSimpleRequest(request))
+                {
+                    LOG.debug("Cross-origin request to {} is a simple cross-origin request", request.getRequestURI());
+                    handleSimpleResponse(request, response, origin);
+                }
+                else if (isPreflightRequest(request))
+                {
+                    LOG.debug("Cross-origin request to {} is a preflight cross-origin request", request.getRequestURI());
+                    handlePreflightResponse(request, response, origin);
+                    if (chainPreflight)
+                        LOG.debug("Preflight cross-origin request to {} forwarded to application", request.getRequestURI());
+                    else
+                        return;
+                }
+                else
+                {
+                    LOG.debug("Cross-origin request to {} is a non-simple cross-origin request", request.getRequestURI());
+                    handleSimpleResponse(request, response, origin);
+                }
+            }
+            else
+            {
+                LOG.debug("Cross-origin request to " + request.getRequestURI() + " with origin " + origin + " does not match allowed origins " + allowedOrigins);
+            }
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    protected boolean isEnabled(HttpServletRequest request)
+    {
+        // WebSocket clients such as Chrome 5 implement a version of the WebSocket
+        // protocol that does not accept extra response headers on the upgrade response
+        for (Enumeration connections = request.getHeaders("Connection"); connections.hasMoreElements();)
+        {
+            String connection = (String)connections.nextElement();
+            if ("Upgrade".equalsIgnoreCase(connection))
+            {
+                for (Enumeration upgrades = request.getHeaders("Upgrade"); upgrades.hasMoreElements();)
+                {
+                    String upgrade = (String)upgrades.nextElement();
+                    if ("WebSocket".equalsIgnoreCase(upgrade))
+                        return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private boolean originMatches(String originList)
+    {
+        if (anyOriginAllowed)
+            return true;
+
+        if (originList.trim().length() == 0)
+            return false;
+
+        String[] origins = originList.split(" ");
+        for (String origin : origins)
+        {
+            if (origin.trim().length() == 0)
+                continue;
+
+            for (String allowedOrigin : allowedOrigins)
+            {
+                if (allowedOrigin.contains("*"))
+                {
+                    Matcher matcher = createMatcher(origin,allowedOrigin);
+                    if (matcher.matches())
+                        return true;
+                }
+                else if (allowedOrigin.equals(origin))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private Matcher createMatcher(String origin, String allowedOrigin)
+    {
+        String regex = parseAllowedWildcardOriginToRegex(allowedOrigin);
+        Pattern pattern = Pattern.compile(regex);
+        return pattern.matcher(origin);
+    }
+
+    private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
+    {
+        String regex = allowedOrigin.replace(".","\\.");
+        return regex.replace("*",".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
+    }
+
+    private boolean isSimpleRequest(HttpServletRequest request)
+    {
+        String method = request.getMethod();
+        if (SIMPLE_HTTP_METHODS.contains(method))
+        {
+            // TODO: implement better detection of simple headers
+            // The specification says that for a request to be simple, custom request headers must be simple.
+            // Here for simplicity I just check if there is a Access-Control-Request-Method header,
+            // which is required for preflight requests
+            return request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) == null;
+        }
+        return false;
+    }
+
+    private boolean isPreflightRequest(HttpServletRequest request)
+    {
+        String method = request.getMethod();
+        if (!"OPTIONS".equalsIgnoreCase(method))
+            return false;
+        if (request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER) == null)
+            return false;
+        return true;
+    }
+
+    private void handleSimpleResponse(HttpServletRequest request, HttpServletResponse response, String origin)
+    {
+        response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
+        if (allowCredentials)
+            response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
+        if (!exposedHeaders.isEmpty())
+            response.setHeader(ACCESS_CONTROL_EXPOSE_HEADERS_HEADER, commify(exposedHeaders));
+    }
+
+    private void handlePreflightResponse(HttpServletRequest request, HttpServletResponse response, String origin)
+    {
+        boolean methodAllowed = isMethodAllowed(request);
+        if (!methodAllowed)
+            return;
+        boolean headersAllowed = areHeadersAllowed(request);
+        if (!headersAllowed)
+            return;
+        response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
+        if (allowCredentials)
+            response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
+        if (preflightMaxAge > 0)
+            response.setHeader(ACCESS_CONTROL_MAX_AGE_HEADER, String.valueOf(preflightMaxAge));
+        response.setHeader(ACCESS_CONTROL_ALLOW_METHODS_HEADER, commify(allowedMethods));
+        response.setHeader(ACCESS_CONTROL_ALLOW_HEADERS_HEADER, commify(allowedHeaders));
+    }
+
+    private boolean isMethodAllowed(HttpServletRequest request)
+    {
+        String accessControlRequestMethod = request.getHeader(ACCESS_CONTROL_REQUEST_METHOD_HEADER);
+        LOG.debug("{} is {}", ACCESS_CONTROL_REQUEST_METHOD_HEADER, accessControlRequestMethod);
+        boolean result = false;
+        if (accessControlRequestMethod != null)
+            result = allowedMethods.contains(accessControlRequestMethod);
+        LOG.debug("Method {} is" + (result ? "" : " not") + " among allowed methods {}", accessControlRequestMethod, allowedMethods);
+        return result;
+    }
+
+    private boolean areHeadersAllowed(HttpServletRequest request)
+    {
+        String accessControlRequestHeaders = request.getHeader(ACCESS_CONTROL_REQUEST_HEADERS_HEADER);
+        LOG.debug("{} is {}", ACCESS_CONTROL_REQUEST_HEADERS_HEADER, accessControlRequestHeaders);
+        boolean result = true;
+        if (accessControlRequestHeaders != null)
+        {
+            String[] headers = accessControlRequestHeaders.split(",");
+            for (String header : headers)
+            {
+                boolean headerAllowed = false;
+                for (String allowedHeader : allowedHeaders)
+                {
+                    if (header.trim().equalsIgnoreCase(allowedHeader.trim()))
+                    {
+                        headerAllowed = true;
+                        break;
+                    }
+                }
+                if (!headerAllowed)
+                {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        LOG.debug("Headers [{}] are" + (result ? "" : " not") + " among allowed headers {}", accessControlRequestHeaders, allowedHeaders);
+        return result;
+    }
+
+    private String commify(List<String> strings)
+    {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < strings.size(); ++i)
+        {
+            if (i > 0) builder.append(",");
+            String string = strings.get(i);
+            builder.append(string);
+        }
+        return builder.toString();
+    }
+
+    public void destroy()
+    {
+        anyOriginAllowed = false;
+        allowedOrigins.clear();
+        allowedMethods.clear();
+        allowedHeaders.clear();
+        preflightMaxAge = 0;
+        allowCredentials = false;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/DoSFilter.java b/src/java/org/eclipse/jetty/servlets/DoSFilter.java
new file mode 100644
index 0000000..be20d58
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/DoSFilter.java
@@ -0,0 +1,1151 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Timeout;
+
+/**
+ * Denial of Service filter
+ * <p/>
+ * <p>
+ * This filter is useful for limiting
+ * exposure to abuse from request flooding, whether malicious, or as a result of
+ * a misconfigured client.
+ * <p>
+ * The filter keeps track of the number of requests from a connection per
+ * second. If a limit is exceeded, the request is either rejected, delayed, or
+ * throttled.
+ * <p>
+ * When a request is throttled, it is placed in a priority queue. Priority is
+ * given first to authenticated users and users with an HttpSession, then
+ * connections which can be identified by their IP addresses. Connections with
+ * no way to identify them are given lowest priority.
+ * <p>
+ * The {@link #extractUserId(ServletRequest request)} function should be
+ * implemented, in order to uniquely identify authenticated users.
+ * <p>
+ * The following init parameters control the behavior of the filter:<dl>
+ * <p/>
+ * <dt>maxRequestsPerSec</dt>
+ * <dd>the maximum number of requests from a connection per
+ * second. Requests in excess of this are first delayed,
+ * then throttled.</dd>
+ * <p/>
+ * <dt>delayMs</dt>
+ * <dd>is the delay given to all requests over the rate limit,
+ * before they are considered at all. -1 means just reject request,
+ * 0 means no delay, otherwise it is the delay.</dd>
+ * <p/>
+ * <dt>maxWaitMs</dt>
+ * <dd>how long to blocking wait for the throttle semaphore.</dd>
+ * <p/>
+ * <dt>throttledRequests</dt>
+ * <dd>is the number of requests over the rate limit able to be
+ * considered at once.</dd>
+ * <p/>
+ * <dt>throttleMs</dt>
+ * <dd>how long to async wait for semaphore.</dd>
+ * <p/>
+ * <dt>maxRequestMs</dt>
+ * <dd>how long to allow this request to run.</dd>
+ * <p/>
+ * <dt>maxIdleTrackerMs</dt>
+ * <dd>how long to keep track of request rates for a connection,
+ * before deciding that the user has gone away, and discarding it</dd>
+ * <p/>
+ * <dt>insertHeaders</dt>
+ * <dd>if true , insert the DoSFilter headers into the response. Defaults to true.</dd>
+ * <p/>
+ * <dt>trackSessions</dt>
+ * <dd>if true, usage rate is tracked by session if a session exists. Defaults to true.</dd>
+ * <p/>
+ * <dt>remotePort</dt>
+ * <dd>if true and session tracking is not used, then rate is tracked by IP+port (effectively connection). Defaults to false.</dd>
+ * <p/>
+ * <dt>ipWhitelist</dt>
+ * <dd>a comma-separated list of IP addresses that will not be rate limited</dd>
+ * <p/>
+ * <dt>managedAttr</dt>
+ * <dd>if set to true, then this servlet is set as a {@link ServletContext} attribute with the
+ * filter name as the attribute name.  This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
+ * manage the configuration of the filter.</dd>
+ * </dl>
+ * </p>
+ */
+public class DoSFilter implements Filter
+{
+    private static final Logger LOG = Log.getLogger(DoSFilter.class);
+
+    private static final String IPv4_GROUP = "(\\d{1,3})";
+    private static final Pattern IPv4_PATTERN = Pattern.compile(IPv4_GROUP+"\\."+IPv4_GROUP+"\\."+IPv4_GROUP+"\\."+IPv4_GROUP);
+    private static final String IPv6_GROUP = "(\\p{XDigit}{1,4})";
+    private static final Pattern IPv6_PATTERN = Pattern.compile(IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP+":"+IPv6_GROUP);
+    private static final Pattern CIDR_PATTERN = Pattern.compile("([^/]+)/(\\d+)");
+
+    private static final String __TRACKER = "DoSFilter.Tracker";
+    private static final String __THROTTLED = "DoSFilter.Throttled";
+
+    private static final int __DEFAULT_MAX_REQUESTS_PER_SEC = 25;
+    private static final int __DEFAULT_DELAY_MS = 100;
+    private static final int __DEFAULT_THROTTLE = 5;
+    private static final int __DEFAULT_MAX_WAIT_MS = 50;
+    private static final long __DEFAULT_THROTTLE_MS = 30000L;
+    private static final long __DEFAULT_MAX_REQUEST_MS_INIT_PARAM = 30000L;
+    private static final long __DEFAULT_MAX_IDLE_TRACKER_MS_INIT_PARAM = 30000L;
+
+    static final String MANAGED_ATTR_INIT_PARAM = "managedAttr";
+    static final String MAX_REQUESTS_PER_S_INIT_PARAM = "maxRequestsPerSec";
+    static final String DELAY_MS_INIT_PARAM = "delayMs";
+    static final String THROTTLED_REQUESTS_INIT_PARAM = "throttledRequests";
+    static final String MAX_WAIT_INIT_PARAM = "maxWaitMs";
+    static final String THROTTLE_MS_INIT_PARAM = "throttleMs";
+    static final String MAX_REQUEST_MS_INIT_PARAM = "maxRequestMs";
+    static final String MAX_IDLE_TRACKER_MS_INIT_PARAM = "maxIdleTrackerMs";
+    static final String INSERT_HEADERS_INIT_PARAM = "insertHeaders";
+    static final String TRACK_SESSIONS_INIT_PARAM = "trackSessions";
+    static final String REMOTE_PORT_INIT_PARAM = "remotePort";
+    static final String IP_WHITELIST_INIT_PARAM = "ipWhitelist";
+    static final String ENABLED_INIT_PARAM = "enabled";
+
+    private static final int USER_AUTH = 2;
+    private static final int USER_SESSION = 2;
+    private static final int USER_IP = 1;
+    private static final int USER_UNKNOWN = 0;
+
+    private ServletContext _context;
+    private volatile long _delayMs;
+    private volatile long _throttleMs;
+    private volatile long _maxWaitMs;
+    private volatile long _maxRequestMs;
+    private volatile long _maxIdleTrackerMs;
+    private volatile boolean _insertHeaders;
+    private volatile boolean _trackSessions;
+    private volatile boolean _remotePort;
+    private volatile boolean _enabled;
+    private Semaphore _passes;
+    private volatile int _throttledRequests;
+    private volatile int _maxRequestsPerSec;
+    private Queue<Continuation>[] _queue;
+    private ContinuationListener[] _listeners;
+    private final ConcurrentHashMap<String, RateTracker> _rateTrackers = new ConcurrentHashMap<String, RateTracker>();
+    private final List<String> _whitelist = new CopyOnWriteArrayList<String>();
+    private final Timeout _requestTimeoutQ = new Timeout();
+    private final Timeout _trackerTimeoutQ = new Timeout();
+    private Thread _timerThread;
+    private volatile boolean _running;
+
+    public void init(FilterConfig filterConfig)
+    {
+        _context = filterConfig.getServletContext();
+
+        _queue = new Queue[getMaxPriority() + 1];
+        _listeners = new ContinuationListener[getMaxPriority() + 1];
+        for (int p = 0; p < _queue.length; p++)
+        {
+            _queue[p] = new ConcurrentLinkedQueue<Continuation>();
+
+            final int priority = p;
+            _listeners[p] = new ContinuationListener()
+            {
+                public void onComplete(Continuation continuation)
+                {
+                }
+
+                public void onTimeout(Continuation continuation)
+                {
+                    _queue[priority].remove(continuation);
+                }
+            };
+        }
+
+        _rateTrackers.clear();
+
+        int maxRequests = __DEFAULT_MAX_REQUESTS_PER_SEC;
+        String parameter = filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM);
+        if (parameter != null)
+            maxRequests = Integer.parseInt(parameter);
+        setMaxRequestsPerSec(maxRequests);
+
+        long delay = __DEFAULT_DELAY_MS;
+        parameter = filterConfig.getInitParameter(DELAY_MS_INIT_PARAM);
+        if (parameter != null)
+            delay = Long.parseLong(parameter);
+        setDelayMs(delay);
+
+        int throttledRequests = __DEFAULT_THROTTLE;
+        parameter = filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM);
+        if (parameter != null)
+            throttledRequests = Integer.parseInt(parameter);
+        setThrottledRequests(throttledRequests);
+
+        long maxWait = __DEFAULT_MAX_WAIT_MS;
+        parameter = filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM);
+        if (parameter != null)
+            maxWait = Long.parseLong(parameter);
+        setMaxWaitMs(maxWait);
+
+        long throttle = __DEFAULT_THROTTLE_MS;
+        parameter = filterConfig.getInitParameter(THROTTLE_MS_INIT_PARAM);
+        if (parameter != null)
+            throttle = Long.parseLong(parameter);
+        setThrottleMs(throttle);
+
+        long maxRequestMs = __DEFAULT_MAX_REQUEST_MS_INIT_PARAM;
+        parameter = filterConfig.getInitParameter(MAX_REQUEST_MS_INIT_PARAM);
+        if (parameter != null)
+            maxRequestMs = Long.parseLong(parameter);
+        setMaxRequestMs(maxRequestMs);
+
+        long maxIdleTrackerMs = __DEFAULT_MAX_IDLE_TRACKER_MS_INIT_PARAM;
+        parameter = filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM);
+        if (parameter != null)
+            maxIdleTrackerMs = Long.parseLong(parameter);
+        setMaxIdleTrackerMs(maxIdleTrackerMs);
+
+        String whiteList = "";
+        parameter = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM);
+        if (parameter != null)
+            whiteList = parameter;
+        setWhitelist(whiteList);
+
+        parameter = filterConfig.getInitParameter(INSERT_HEADERS_INIT_PARAM);
+        setInsertHeaders(parameter == null || Boolean.parseBoolean(parameter));
+
+        parameter = filterConfig.getInitParameter(TRACK_SESSIONS_INIT_PARAM);
+        setTrackSessions(parameter == null || Boolean.parseBoolean(parameter));
+
+        parameter = filterConfig.getInitParameter(REMOTE_PORT_INIT_PARAM);
+        setRemotePort(parameter != null && Boolean.parseBoolean(parameter));
+
+        parameter = filterConfig.getInitParameter(ENABLED_INIT_PARAM);
+        setEnabled(parameter == null || Boolean.parseBoolean(parameter));
+
+        _requestTimeoutQ.setNow();
+        _requestTimeoutQ.setDuration(_maxRequestMs);
+
+        _trackerTimeoutQ.setNow();
+        _trackerTimeoutQ.setDuration(_maxIdleTrackerMs);
+
+        _running = true;
+        _timerThread = (new Thread()
+        {
+            public void run()
+            {
+                try
+                {
+                    while (_running)
+                    {
+                        long now = _requestTimeoutQ.setNow();
+                        _requestTimeoutQ.tick();
+                        _trackerTimeoutQ.setNow(now);
+                        _trackerTimeoutQ.tick();
+                        try
+                        {
+                            Thread.sleep(100);
+                        }
+                        catch (InterruptedException e)
+                        {
+                            LOG.ignore(e);
+                        }
+                    }
+                }
+                finally
+                {
+                    LOG.debug("DoSFilter timer exited");
+                }
+            }
+        });
+        _timerThread.start();
+
+        if (_context != null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
+            _context.setAttribute(filterConfig.getFilterName(), this);
+    }
+
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
+    {
+        doFilter((HttpServletRequest)request, (HttpServletResponse)response, filterChain);
+    }
+
+    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException
+    {
+        if (!isEnabled())
+        {
+            filterChain.doFilter(request, response);
+            return;
+        }
+
+        final long now = _requestTimeoutQ.getNow();
+
+        // Look for the rate tracker for this request
+        RateTracker tracker = (RateTracker)request.getAttribute(__TRACKER);
+
+        if (tracker == null)
+        {
+            // This is the first time we have seen this request.
+
+            // get a rate tracker associated with this request, and record one hit
+            tracker = getRateTracker(request);
+
+            // Calculate the rate and check it is over the allowed limit
+            final boolean overRateLimit = tracker.isRateExceeded(now);
+
+            // pass it through if  we are not currently over the rate limit
+            if (!overRateLimit)
+            {
+                doFilterChain(filterChain, request, response);
+                return;
+            }
+
+            // We are over the limit.
+
+            // So either reject it, delay it or throttle it
+            long delayMs = getDelayMs();
+            boolean insertHeaders = isInsertHeaders();
+            switch ((int)delayMs)
+            {
+                case -1:
+                {
+                    // Reject this request
+                    LOG.warn("DOS ALERT: Request rejected ip=" + request.getRemoteAddr() + ",session=" + request.getRequestedSessionId() + ",user=" + request.getUserPrincipal());
+                    if (insertHeaders)
+                        response.addHeader("DoSFilter", "unavailable");
+                    response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                    return;
+                }
+                case 0:
+                {
+                    // fall through to throttle code
+                    LOG.warn("DOS ALERT: Request throttled ip=" + request.getRemoteAddr() + ",session=" + request.getRequestedSessionId() + ",user=" + request.getUserPrincipal());
+                    request.setAttribute(__TRACKER, tracker);
+                    break;
+                }
+                default:
+                {
+                    // insert a delay before throttling the request
+                    LOG.warn("DOS ALERT: Request delayed="+delayMs+"ms ip=" + request.getRemoteAddr() + ",session=" + request.getRequestedSessionId() + ",user=" + request.getUserPrincipal());
+                    if (insertHeaders)
+                        response.addHeader("DoSFilter", "delayed");
+                    Continuation continuation = ContinuationSupport.getContinuation(request);
+                    request.setAttribute(__TRACKER, tracker);
+                    if (delayMs > 0)
+                        continuation.setTimeout(delayMs);
+                    continuation.suspend();
+                    return;
+                }
+            }
+        }
+
+        // Throttle the request
+        boolean accepted = false;
+        try
+        {
+            // check if we can afford to accept another request at this time
+            accepted = _passes.tryAcquire(getMaxWaitMs(), TimeUnit.MILLISECONDS);
+
+            if (!accepted)
+            {
+                // we were not accepted, so either we suspend to wait,or if we were woken up we insist or we fail
+                final Continuation continuation = ContinuationSupport.getContinuation(request);
+
+                Boolean throttled = (Boolean)request.getAttribute(__THROTTLED);
+                long throttleMs = getThrottleMs();
+                if (throttled != Boolean.TRUE && throttleMs > 0)
+                {
+                    int priority = getPriority(request, tracker);
+                    request.setAttribute(__THROTTLED, Boolean.TRUE);
+                    if (isInsertHeaders())
+                        response.addHeader("DoSFilter", "throttled");
+                    if (throttleMs > 0)
+                        continuation.setTimeout(throttleMs);
+                    continuation.suspend();
+
+                    continuation.addContinuationListener(_listeners[priority]);
+                    _queue[priority].add(continuation);
+                    return;
+                }
+                // else were we resumed?
+                else if (request.getAttribute("javax.servlet.resumed") == Boolean.TRUE)
+                {
+                    // we were resumed and somebody stole our pass, so we wait for the next one.
+                    _passes.acquire();
+                    accepted = true;
+                }
+            }
+
+            // if we were accepted (either immediately or after throttle)
+            if (accepted)
+                // call the chain
+                doFilterChain(filterChain, request, response);
+            else
+            {
+                // fail the request
+                if (isInsertHeaders())
+                    response.addHeader("DoSFilter", "unavailable");
+                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+            }
+        }
+        catch (InterruptedException e)
+        {
+            _context.log("DoS", e);
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+        }
+        finally
+        {
+            if (accepted)
+            {
+                // wake up the next highest priority request.
+                for (int p = _queue.length; p-- > 0; )
+                {
+                    Continuation continuation = _queue[p].poll();
+                    if (continuation != null && continuation.isSuspended())
+                    {
+                        continuation.resume();
+                        break;
+                    }
+                }
+                _passes.release();
+            }
+        }
+    }
+
+    protected void doFilterChain(FilterChain chain, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
+    {
+        final Thread thread = Thread.currentThread();
+
+        final Timeout.Task requestTimeout = new Timeout.Task()
+        {
+            public void expired()
+            {
+                closeConnection(request, response, thread);
+            }
+        };
+
+        try
+        {
+            _requestTimeoutQ.schedule(requestTimeout);
+            chain.doFilter(request, response);
+        }
+        finally
+        {
+            requestTimeout.cancel();
+        }
+    }
+
+    /**
+     * Takes drastic measures to return this response and stop this thread.
+     * Due to the way the connection is interrupted, may return mixed up headers.
+     *
+     * @param request  current request
+     * @param response current response, which must be stopped
+     * @param thread   the handling thread
+     */
+    protected void closeConnection(HttpServletRequest request, HttpServletResponse response, Thread thread)
+    {
+        // take drastic measures to return this response and stop this thread.
+        if (!response.isCommitted())
+        {
+            response.setHeader("Connection", "close");
+        }
+        try
+        {
+            try
+            {
+                response.getWriter().close();
+            }
+            catch (IllegalStateException e)
+            {
+                response.getOutputStream().close();
+            }
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+
+        // interrupt the handling thread
+        thread.interrupt();
+    }
+
+    /**
+     * Get priority for this request, based on user type
+     *
+     * @param request the current request
+     * @param tracker the rate tracker for this request
+     * @return the priority for this request
+     */
+    protected int getPriority(HttpServletRequest request, RateTracker tracker)
+    {
+        if (extractUserId(request) != null)
+            return USER_AUTH;
+        if (tracker != null)
+            return tracker.getType();
+        return USER_UNKNOWN;
+    }
+
+    /**
+     * @return the maximum priority that we can assign to a request
+     */
+    protected int getMaxPriority()
+    {
+        return USER_AUTH;
+    }
+
+    /**
+     * Return a request rate tracker associated with this connection; keeps
+     * track of this connection's request rate. If this is not the first request
+     * from this connection, return the existing object with the stored stats.
+     * If it is the first request, then create a new request tracker.
+     * <p/>
+     * Assumes that each connection has an identifying characteristic, and goes
+     * through them in order, taking the first that matches: user id (logged
+     * in), session id, client IP address. Unidentifiable connections are lumped
+     * into one.
+     * <p/>
+     * When a session expires, its rate tracker is automatically deleted.
+     *
+     * @param request the current request
+     * @return the request rate tracker for the current connection
+     */
+    public RateTracker getRateTracker(ServletRequest request)
+    {
+        HttpSession session = ((HttpServletRequest)request).getSession(false);
+
+        String loadId = extractUserId(request);
+        final int type;
+        if (loadId != null)
+        {
+            type = USER_AUTH;
+        }
+        else
+        {
+            if (_trackSessions && session != null && !session.isNew())
+            {
+                loadId = session.getId();
+                type = USER_SESSION;
+            }
+            else
+            {
+                loadId = _remotePort ? (request.getRemoteAddr() + request.getRemotePort()) : request.getRemoteAddr();
+                type = USER_IP;
+            }
+        }
+
+        RateTracker tracker = _rateTrackers.get(loadId);
+
+        if (tracker == null)
+        {
+            boolean allowed = checkWhitelist(_whitelist, request.getRemoteAddr());
+            tracker = allowed ? new FixedRateTracker(loadId, type, _maxRequestsPerSec)
+                    : new RateTracker(loadId, type, _maxRequestsPerSec);
+            RateTracker existing = _rateTrackers.putIfAbsent(loadId, tracker);
+            if (existing != null)
+                tracker = existing;
+
+            if (type == USER_IP)
+            {
+                // USER_IP expiration from _rateTrackers is handled by the _trackerTimeoutQ
+                _trackerTimeoutQ.schedule(tracker);
+            }
+            else if (session != null)
+            {
+                // USER_SESSION expiration from _rateTrackers are handled by the HttpSessionBindingListener
+                session.setAttribute(__TRACKER, tracker);
+            }
+        }
+
+        return tracker;
+    }
+
+    protected boolean checkWhitelist(List<String> whitelist, String candidate)
+    {
+        for (String address : whitelist)
+        {
+            if (address.contains("/"))
+            {
+                if (subnetMatch(address, candidate))
+                    return true;
+            }
+            else
+            {
+                if (address.equals(candidate))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    protected boolean subnetMatch(String subnetAddress, String address)
+    {
+        Matcher cidrMatcher = CIDR_PATTERN.matcher(subnetAddress);
+        if (!cidrMatcher.matches())
+            return false;
+
+        String subnet = cidrMatcher.group(1);
+        int prefix;
+        try
+        {
+            prefix = Integer.parseInt(cidrMatcher.group(2));
+        }
+        catch (NumberFormatException x)
+        {
+            LOG.info("Ignoring malformed CIDR address {}", subnetAddress);
+            return false;
+        }
+
+        byte[] subnetBytes = addressToBytes(subnet);
+        if (subnetBytes == null)
+        {
+            LOG.info("Ignoring malformed CIDR address {}", subnetAddress);
+            return false;
+        }
+        byte[] addressBytes = addressToBytes(address);
+        if (addressBytes == null)
+        {
+            LOG.info("Ignoring malformed remote address {}", address);
+            return false;
+        }
+
+        // Comparing IPv4 with IPv6 ?
+        int length = subnetBytes.length;
+        if (length != addressBytes.length)
+            return false;
+
+        byte[] mask = prefixToBytes(prefix, length);
+
+        for (int i = 0; i < length; ++i)
+        {
+            if ((subnetBytes[i] & mask[i]) != (addressBytes[i] & mask[i]))
+                return false;
+        }
+
+        return true;
+    }
+
+    private byte[] addressToBytes(String address)
+    {
+        Matcher ipv4Matcher = IPv4_PATTERN.matcher(address);
+        if (ipv4Matcher.matches())
+        {
+            byte[] result = new byte[4];
+            for (int i = 0; i < result.length; ++i)
+                result[i] = Integer.valueOf(ipv4Matcher.group(i + 1)).byteValue();
+            return result;
+        }
+        else
+        {
+            Matcher ipv6Matcher = IPv6_PATTERN.matcher(address);
+            if (ipv6Matcher.matches())
+            {
+                byte[] result = new byte[16];
+                for (int i = 0; i < result.length; i += 2)
+                {
+                    int word = Integer.valueOf(ipv6Matcher.group(i / 2 + 1), 16);
+                    result[i] = (byte)((word & 0xFF00) >>> 8);
+                    result[i + 1] = (byte)(word & 0xFF);
+                }
+                return result;
+            }
+        }
+        return null;
+    }
+
+    private byte[] prefixToBytes(int prefix, int length)
+    {
+        byte[] result = new byte[length];
+        int index = 0;
+        while (prefix / 8 > 0)
+        {
+            result[index] = -1;
+            prefix -= 8;
+            ++index;
+        }
+        // Sets the _prefix_ most significant bits to 1
+        result[index] = (byte)~((1 << (8 - prefix)) - 1);
+        return result;
+    }
+
+    public void destroy()
+    {
+        LOG.debug("Destroy {}",this);
+        _running = false;
+        _timerThread.interrupt();
+        _requestTimeoutQ.cancelAll();
+        _trackerTimeoutQ.cancelAll();
+        _rateTrackers.clear();
+        _whitelist.clear();
+    }
+
+    /**
+     * Returns the user id, used to track this connection.
+     * This SHOULD be overridden by subclasses.
+     *
+     * @param request the current request
+     * @return a unique user id, if logged in; otherwise null.
+     */
+    protected String extractUserId(ServletRequest request)
+    {
+        return null;
+    }
+
+    /**
+     * Get maximum number of requests from a connection per
+     * second. Requests in excess of this are first delayed,
+     * then throttled.
+     *
+     * @return maximum number of requests
+     */
+    public int getMaxRequestsPerSec()
+    {
+        return _maxRequestsPerSec;
+    }
+
+    /**
+     * Get maximum number of requests from a connection per
+     * second. Requests in excess of this are first delayed,
+     * then throttled.
+     *
+     * @param value maximum number of requests
+     */
+    public void setMaxRequestsPerSec(int value)
+    {
+        _maxRequestsPerSec = value;
+    }
+
+    /**
+     * Get delay (in milliseconds) that is applied to all requests
+     * over the rate limit, before they are considered at all.
+     */
+    public long getDelayMs()
+    {
+        return _delayMs;
+    }
+
+    /**
+     * Set delay (in milliseconds) that is applied to all requests
+     * over the rate limit, before they are considered at all.
+     *
+     * @param value delay (in milliseconds), 0 - no delay, -1 - reject request
+     */
+    public void setDelayMs(long value)
+    {
+        _delayMs = value;
+    }
+
+    /**
+     * Get maximum amount of time (in milliseconds) the filter will
+     * blocking wait for the throttle semaphore.
+     *
+     * @return maximum wait time
+     */
+    public long getMaxWaitMs()
+    {
+        return _maxWaitMs;
+    }
+
+    /**
+     * Set maximum amount of time (in milliseconds) the filter will
+     * blocking wait for the throttle semaphore.
+     *
+     * @param value maximum wait time
+     */
+    public void setMaxWaitMs(long value)
+    {
+        _maxWaitMs = value;
+    }
+
+    /**
+     * Get number of requests over the rate limit able to be
+     * considered at once.
+     *
+     * @return number of requests
+     */
+    public int getThrottledRequests()
+    {
+        return _throttledRequests;
+    }
+
+    /**
+     * Set number of requests over the rate limit able to be
+     * considered at once.
+     *
+     * @param value number of requests
+     */
+    public void setThrottledRequests(int value)
+    {
+        int permits = _passes == null ? 0 : _passes.availablePermits();
+        _passes = new Semaphore((value - _throttledRequests + permits), true);
+        _throttledRequests = value;
+    }
+
+    /**
+     * Get amount of time (in milliseconds) to async wait for semaphore.
+     *
+     * @return wait time
+     */
+    public long getThrottleMs()
+    {
+        return _throttleMs;
+    }
+
+    /**
+     * Set amount of time (in milliseconds) to async wait for semaphore.
+     *
+     * @param value wait time
+     */
+    public void setThrottleMs(long value)
+    {
+        _throttleMs = value;
+    }
+
+    /**
+     * Get maximum amount of time (in milliseconds) to allow
+     * the request to process.
+     *
+     * @return maximum processing time
+     */
+    public long getMaxRequestMs()
+    {
+        return _maxRequestMs;
+    }
+
+    /**
+     * Set maximum amount of time (in milliseconds) to allow
+     * the request to process.
+     *
+     * @param value maximum processing time
+     */
+    public void setMaxRequestMs(long value)
+    {
+        _maxRequestMs = value;
+    }
+
+    /**
+     * Get maximum amount of time (in milliseconds) to keep track
+     * of request rates for a connection, before deciding that
+     * the user has gone away, and discarding it.
+     *
+     * @return maximum tracking time
+     */
+    public long getMaxIdleTrackerMs()
+    {
+        return _maxIdleTrackerMs;
+    }
+
+    /**
+     * Set maximum amount of time (in milliseconds) to keep track
+     * of request rates for a connection, before deciding that
+     * the user has gone away, and discarding it.
+     *
+     * @param value maximum tracking time
+     */
+    public void setMaxIdleTrackerMs(long value)
+    {
+        _maxIdleTrackerMs = value;
+    }
+
+    /**
+     * Check flag to insert the DoSFilter headers into the response.
+     *
+     * @return value of the flag
+     */
+    public boolean isInsertHeaders()
+    {
+        return _insertHeaders;
+    }
+
+    /**
+     * Set flag to insert the DoSFilter headers into the response.
+     *
+     * @param value value of the flag
+     */
+    public void setInsertHeaders(boolean value)
+    {
+        _insertHeaders = value;
+    }
+
+    /**
+     * Get flag to have usage rate tracked by session if a session exists.
+     *
+     * @return value of the flag
+     */
+    public boolean isTrackSessions()
+    {
+        return _trackSessions;
+    }
+
+    /**
+     * Set flag to have usage rate tracked by session if a session exists.
+     *
+     * @param value value of the flag
+     */
+    public void setTrackSessions(boolean value)
+    {
+        _trackSessions = value;
+    }
+
+    /**
+     * Get flag to have usage rate tracked by IP+port (effectively connection)
+     * if session tracking is not used.
+     *
+     * @return value of the flag
+     */
+    public boolean isRemotePort()
+    {
+        return _remotePort;
+    }
+
+    /**
+     * Set flag to have usage rate tracked by IP+port (effectively connection)
+     * if session tracking is not used.
+     *
+     * @param value value of the flag
+     */
+    public void setRemotePort(boolean value)
+    {
+        _remotePort = value;
+    }
+
+    /**
+     * @return whether this filter is enabled
+     */
+    public boolean isEnabled()
+    {
+        return _enabled;
+    }
+
+    /**
+     * @param enabled whether this filter is enabled
+     */
+    public void setEnabled(boolean enabled)
+    {
+        _enabled = enabled;
+    }
+
+    /**
+     * Get a list of IP addresses that will not be rate limited.
+     *
+     * @return comma-separated whitelist
+     */
+    public String getWhitelist()
+    {
+        StringBuilder result = new StringBuilder();
+        for (Iterator<String> iterator = _whitelist.iterator(); iterator.hasNext();)
+        {
+            String address = iterator.next();
+            result.append(address);
+            if (iterator.hasNext())
+                result.append(",");
+        }
+        return result.toString();
+    }
+
+    /**
+     * Set a list of IP addresses that will not be rate limited.
+     *
+     * @param value comma-separated whitelist
+     */
+    public void setWhitelist(String value)
+    {
+        List<String> result = new ArrayList<String>();
+        for (String address : value.split(","))
+            addWhitelistAddress(result, address);
+        _whitelist.clear();
+        _whitelist.addAll(result);
+        LOG.debug("Whitelisted IP addresses: {}", result);
+    }
+
+    public void clearWhitelist()
+    {
+        _whitelist.clear();
+    }
+
+    public boolean addWhitelistAddress(String address)
+    {
+        return addWhitelistAddress(_whitelist, address);
+    }
+
+    private boolean addWhitelistAddress(List<String> list, String address)
+    {
+        address = address.trim();
+        return address.length() > 0 && list.add(address);
+    }
+
+    public boolean removeWhitelistAddress(String address)
+    {
+        return _whitelist.remove(address);
+    }
+
+    /**
+     * A RateTracker is associated with a connection, and stores request rate
+     * data.
+     */
+    class RateTracker extends Timeout.Task implements HttpSessionBindingListener, HttpSessionActivationListener, Serializable
+    {
+        private static final long serialVersionUID = 3534663738034577872L;
+
+        transient protected final String _id;
+        transient protected final int _type;
+        transient protected final long[] _timestamps;
+        transient protected int _next;
+
+        public RateTracker(String id, int type, int maxRequestsPerSecond)
+        {
+            _id = id;
+            _type = type;
+            _timestamps = new long[maxRequestsPerSecond];
+            _next = 0;
+        }
+
+        /**
+         * @return the current calculated request rate over the last second
+         */
+        public boolean isRateExceeded(long now)
+        {
+            final long last;
+            synchronized (this)
+            {
+                last = _timestamps[_next];
+                _timestamps[_next] = now;
+                _next = (_next + 1) % _timestamps.length;
+            }
+
+            return last != 0 && (now - last) < 1000L;
+        }
+
+        public String getId()
+        {
+            return _id;
+        }
+
+        public int getType()
+        {
+            return _type;
+        }
+
+        public void valueBound(HttpSessionBindingEvent event)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("Value bound: {}", getId());
+        }
+
+        public void valueUnbound(HttpSessionBindingEvent event)
+        {
+            //take the tracker out of the list of trackers
+            _rateTrackers.remove(_id);
+            if (LOG.isDebugEnabled())
+                LOG.debug("Tracker removed: {}", getId());
+        }
+
+        public void sessionWillPassivate(HttpSessionEvent se)
+        {
+            //take the tracker of the list of trackers (if its still there)
+            //and ensure that we take ourselves out of the session so we are not saved
+            _rateTrackers.remove(_id);
+            se.getSession().removeAttribute(__TRACKER);
+            if (LOG.isDebugEnabled()) LOG.debug("Value removed: {}", getId());
+        }
+
+        public void sessionDidActivate(HttpSessionEvent se)
+        {
+            LOG.warn("Unexpected session activation");
+        }
+
+        public void expired()
+        {
+            long now = _trackerTimeoutQ.getNow();
+            int latestIndex = _next == 0 ? (_timestamps.length - 1) : (_next - 1);
+            long last = _timestamps[latestIndex];
+            boolean hasRecentRequest = last != 0 && (now - last) < 1000L;
+
+            if (hasRecentRequest)
+                reschedule();
+            else
+                _rateTrackers.remove(_id);
+        }
+
+        @Override
+        public String toString()
+        {
+            return "RateTracker/" + _id + "/" + _type;
+        }
+    }
+
+    class FixedRateTracker extends RateTracker
+    {
+        public FixedRateTracker(String id, int type, int numRecentRequestsTracked)
+        {
+            super(id, type, numRecentRequestsTracked);
+        }
+
+        @Override
+        public boolean isRateExceeded(long now)
+        {
+            // rate limit is never exceeded, but we keep track of the request timestamps
+            // so that we know whether there was recent activity on this tracker
+            // and whether it should be expired
+            synchronized (this)
+            {
+                _timestamps[_next] = now;
+                _next = (_next + 1) % _timestamps.length;
+            }
+
+            return false;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Fixed" + super.toString();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/GzipFilter.java b/src/java/org/eclipse/jetty/servlets/GzipFilter.java
new file mode 100644
index 0000000..84303d5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/GzipFilter.java
@@ -0,0 +1,590 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.http.HttpMethods;
+import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
+import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** GZIP Filter
+ * This filter will gzip or deflate the content of a response if: <ul>
+ * <li>The filter is mapped to a matching path</li>
+ * <li>accept-encoding header is set to either gzip, deflate or a combination of those</li>
+ * <li>The response status code is >=200 and <300
+ * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li>
+ * <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or
+ * if no mimeTypes are defined the content-type is not "application/gzip"</li>
+ * <li>No content-encoding is specified by the resource</li>
+ * </ul>
+ * 
+ * <p>
+ * If both gzip and deflate are specified in the accept-encoding header, then gzip will be used.
+ * </p>
+ * <p>
+ * Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and
+ * CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be 
+ * prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is 
+ * advised instead.
+ * </p>
+ * <p>
+ * This filter extends {@link UserAgentFilter} and if the the initParameter <code>excludedAgents</code> 
+ * is set to a comma separated list of user agents, then these agents will be excluded from gzip content.
+ * </p>
+ * <p>Init Parameters:</p>
+ * <PRE>
+ * bufferSize                 The output buffer size. Defaults to 8192. Be careful as values <= 0 will lead to an 
+ *                            {@link IllegalArgumentException}. 
+ *                            See: {@link java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream, int)}
+ *                            and: {@link java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream, Deflater, int)}
+ *                      
+ * minGzipSize                Content will only be compressed if content length is either unknown or greater
+ *                            than <code>minGzipSize</code>.
+ *                      
+ * deflateCompressionLevel    The compression level used for deflate compression. (0-9).
+ *                            See: {@link java.util.zip.Deflater#Deflater(int, boolean)}
+ *                            
+ * deflateNoWrap              The noWrap setting for deflate compression. Defaults to true. (true/false)
+ *                            See: {@link java.util.zip.Deflater#Deflater(int, boolean)}
+ *
+ * methods                    Comma separated list of HTTP methods to compress. If not set, only GET requests are compressed.
+ * 
+ * mimeTypes                  Comma separated list of mime types to compress. See description above.
+ * 
+ * excludedAgents             Comma separated list of user agents to exclude from compression. Does a 
+ *                            {@link String#contains(CharSequence)} to check if the excluded agent occurs
+ *                            in the user-agent header. If it does -> no compression
+ *                            
+ * excludeAgentPatterns       Same as excludedAgents, but accepts regex patterns for more complex matching.
+ * 
+ * excludePaths               Comma separated list of paths to exclude from compression. 
+ *                            Does a {@link String#startsWith(String)} comparison to check if the path matches.
+ *                            If it does match -> no compression. To match subpaths use <code>excludePathPatterns</code>
+ *                            instead.
+ * 
+ * excludePathPatterns        Same as excludePath, but accepts regex patterns for more complex matching.
+ * 
+ * vary                       Set to the value of the Vary header sent with responses that could be compressed.  By default it is 
+ *                            set to 'Vary: Accept-Encoding, User-Agent' since IE6 is excluded by default from the excludedAgents. 
+ *                            If user-agents are not to be excluded, then this can be set to 'Vary: Accept-Encoding'.  Note also 
+ *                            that shared caches may cache copies of a resource that is varied by User-Agent - one per variation of 
+ *                            the User-Agent, unless the cache does some normalization of the UA string.
+ * </PRE>
+ */
+public class GzipFilter extends UserAgentFilter
+{
+    private static final Logger LOG = Log.getLogger(GzipFilter.class);
+    public final static String GZIP="gzip";
+    public final static String ETAG_GZIP="--gzip\"";
+    public final static String DEFLATE="deflate";
+    public final static String ETAG_DEFLATE="--deflate\"";
+    public final static String ETAG="o.e.j.s.GzipFilter.ETag";
+
+    protected ServletContext _context;
+    protected Set<String> _mimeTypes;
+    protected int _bufferSize=8192;
+    protected int _minGzipSize=256;
+    protected int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION;
+    protected boolean _deflateNoWrap = true;
+
+    protected final Set<String> _methods=new HashSet<String>();
+    protected Set<String> _excludedAgents;
+    protected Set<Pattern> _excludedAgentPatterns;
+    protected Set<String> _excludedPaths;
+    protected Set<Pattern> _excludedPathPatterns;
+    protected String _vary="Accept-Encoding, User-Agent";
+    
+    private static final int STATE_SEPARATOR = 0;
+    private static final int STATE_Q = 1;
+    private static final int STATE_QVALUE = 2;
+    private static final int STATE_DEFAULT = 3;
+
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
+     */
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        super.init(filterConfig);
+        
+        _context=filterConfig.getServletContext();
+        
+        String tmp=filterConfig.getInitParameter("bufferSize");
+        if (tmp!=null)
+            _bufferSize=Integer.parseInt(tmp);
+
+        tmp=filterConfig.getInitParameter("minGzipSize");
+        if (tmp!=null)
+            _minGzipSize=Integer.parseInt(tmp);
+        
+        tmp=filterConfig.getInitParameter("deflateCompressionLevel");
+        if (tmp!=null)
+            _deflateCompressionLevel=Integer.parseInt(tmp);
+        
+        tmp=filterConfig.getInitParameter("deflateNoWrap");
+        if (tmp!=null)
+            _deflateNoWrap=Boolean.parseBoolean(tmp);
+        
+        tmp=filterConfig.getInitParameter("methods");
+        if (tmp!=null)
+        {
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+                _methods.add(tok.nextToken().trim().toUpperCase());
+        }
+        else
+            _methods.add(HttpMethods.GET);
+        
+        tmp=filterConfig.getInitParameter("mimeTypes");
+        if (tmp!=null)
+        {
+            _mimeTypes=new HashSet<String>();
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+                _mimeTypes.add(tok.nextToken());
+        }
+        tmp=filterConfig.getInitParameter("excludedAgents");
+        if (tmp!=null)
+        {
+            _excludedAgents=new HashSet<String>();
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+               _excludedAgents.add(tok.nextToken());
+        }
+        
+                tmp=filterConfig.getInitParameter("excludeAgentPatterns");
+        if (tmp!=null)
+        {
+            _excludedAgentPatterns=new HashSet<Pattern>();
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+                _excludedAgentPatterns.add(Pattern.compile(tok.nextToken()));            
+        }        
+        
+        tmp=filterConfig.getInitParameter("excludePaths");
+        if (tmp!=null)
+        {
+            _excludedPaths=new HashSet<String>();
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+                _excludedPaths.add(tok.nextToken());            
+        }
+        
+        tmp=filterConfig.getInitParameter("excludePathPatterns");
+        if (tmp!=null)
+        {
+            _excludedPathPatterns=new HashSet<Pattern>();
+            StringTokenizer tok = new StringTokenizer(tmp,",",false);
+            while (tok.hasMoreTokens())
+                _excludedPathPatterns.add(Pattern.compile(tok.nextToken()));            
+        }       
+        
+        tmp=filterConfig.getInitParameter("vary");
+        if (tmp!=null)
+            _vary=tmp;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
+     */
+    @Override
+    public void destroy()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+     */
+    @Override
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
+        throws IOException, ServletException
+    {
+        HttpServletRequest request=(HttpServletRequest)req;
+        HttpServletResponse response=(HttpServletResponse)res;
+
+        // If not a supported method or it is an Excluded URI - no Vary because no matter what client, this URI is always excluded
+        String requestURI = request.getRequestURI();
+        if (!_methods.contains(request.getMethod()) || isExcludedPath(requestURI))
+        {
+            super.doFilter(request,response,chain);
+            return;
+        }
+        
+        // Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
+        if (_mimeTypes!=null && _mimeTypes.size()>0)
+        {
+            String mimeType = _context.getMimeType(request.getRequestURI());
+            
+            if (mimeType!=null && !_mimeTypes.contains(mimeType))
+            {
+                // handle normally without setting vary header
+                super.doFilter(request,response,chain);
+                return;
+            }
+        }
+        
+        // Excluded User-Agents
+        String ua = getUserAgent(request);
+        boolean ua_excluded=ua!=null&&isExcludedAgent(ua);
+        
+        // Acceptable compression type
+        String compressionType = ua_excluded?null:selectCompression(request.getHeader("accept-encoding"));
+        
+        // Special handling for etags
+        String etag = request.getHeader("If-None-Match"); 
+        if (etag!=null)
+        {
+            int dd=etag.indexOf("--");
+            if (dd>0)
+                request.setAttribute(ETAG,etag.substring(0,dd)+(etag.endsWith("\"")?"\"":""));
+        }
+
+        CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType);
+
+        boolean exceptional=true;
+        try
+        {
+            super.doFilter(request,wrappedResponse,chain);
+            exceptional=false;
+        }
+        finally
+        {
+            Continuation continuation = ContinuationSupport.getContinuation(request);
+            if (continuation.isSuspended() && continuation.isResponseWrapped())   
+            {
+                continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse));
+            }
+            else if (exceptional && !response.isCommitted())
+            {
+                wrappedResponse.resetBuffer();
+                wrappedResponse.noCompression();
+            }
+            else
+                wrappedResponse.finish();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private String selectCompression(String encodingHeader)
+    {
+        // TODO, this could be a little more robust.
+        // prefer gzip over deflate
+        String compression = null;
+        if (encodingHeader!=null)
+        {
+            
+            String[] encodings = getEncodings(encodingHeader);
+            if (encodings != null)
+            {
+                for (int i=0; i< encodings.length; i++)
+                {
+                    if (encodings[i].toLowerCase(Locale.ENGLISH).contains(GZIP))
+                    {
+                        if (isEncodingAcceptable(encodings[i]))
+                        {
+                            compression = GZIP;
+                            break; //prefer Gzip over deflate
+                        }
+                    }
+
+                    if (encodings[i].toLowerCase(Locale.ENGLISH).contains(DEFLATE))
+                    {
+                        if (isEncodingAcceptable(encodings[i]))
+                        {
+                            compression = DEFLATE; //Keep checking in case gzip is acceptable
+                        }
+                    }
+                }
+            }
+        }
+        return compression;
+    }
+    
+    
+    private String[] getEncodings (String encodingHeader)
+    {
+        if (encodingHeader == null)
+            return null;
+        return encodingHeader.split(",");
+    }
+    
+    private boolean isEncodingAcceptable(String encoding)
+    {    
+        int state = STATE_DEFAULT;
+        int qvalueIdx = -1;
+        for (int i=0;i<encoding.length();i++)
+        {
+            char c = encoding.charAt(i);
+            switch (state)
+            {
+                case STATE_DEFAULT:
+                {
+                    if (';' == c)
+                        state = STATE_SEPARATOR;
+                    break;
+                }
+                case STATE_SEPARATOR:
+                {
+                    if ('q' == c || 'Q' == c)
+                        state = STATE_Q;
+                    break;
+                }
+                case STATE_Q:
+                {
+                    if ('=' == c)
+                        state = STATE_QVALUE;
+                    break;
+                }
+                case STATE_QVALUE:
+                {
+                    if (qvalueIdx < 0 && '0' == c || '1' == c)
+                        qvalueIdx = i;
+                    break;
+                }
+            }
+        }
+        
+        if (qvalueIdx < 0)
+            return true;
+               
+        if ("0".equals(encoding.substring(qvalueIdx).trim()))
+            return false;
+        return true;
+    }
+    
+    
+    protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
+    {
+        CompressedResponseWrapper wrappedResponse = null;
+        if (compressionType==null)
+        {
+            wrappedResponse = new CompressedResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(null,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return null;
+                        }
+                    };
+                }
+            };
+        }
+        else if (compressionType.equals(GZIP))
+        {
+            wrappedResponse = new CompressedResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(compressionType,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return new GZIPOutputStream(_response.getOutputStream(),_bufferSize)
+                            {
+                                /**
+                                 * Work around a bug in the jvm GzipOutputStream whereby it is not
+                                 * thread safe when thread A calls finish, but thread B is writing
+                                 * @see java.util.zip.GZIPOutputStream#finish()
+                                 */
+                                @Override
+                                public synchronized void finish() throws IOException
+                                {
+                                    super.finish();
+                                }
+                                
+                                /**
+                                 * Work around a bug in the jvm GzipOutputStream whereby it is not
+                                 * thread safe when thread A calls close(), but thread B is writing
+                                 * @see java.util.zip.GZIPOutputStream#close()
+                                 */
+                                @Override
+                                public synchronized void close() throws IOException
+                                {
+                                    super.close();
+                                }           
+                            };
+                        }
+                    };
+                }
+            };
+        }
+        else if (compressionType.equals(DEFLATE))
+        {
+            wrappedResponse = new CompressedResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(compressionType,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel,_deflateNoWrap));
+                        }
+                    };
+                }
+            };
+        } 
+        else
+        {
+            throw new IllegalStateException(compressionType + " not supported");
+        }
+        configureWrappedResponse(wrappedResponse);
+        return wrappedResponse;
+    }
+
+    protected void configureWrappedResponse(CompressedResponseWrapper wrappedResponse)
+    {
+        wrappedResponse.setMimeTypes(_mimeTypes);
+        wrappedResponse.setBufferSize(_bufferSize);
+        wrappedResponse.setMinCompressSize(_minGzipSize);
+    }
+     
+    private class ContinuationListenerWaitingForWrappedResponseToFinish implements ContinuationListener
+    {    
+        private CompressedResponseWrapper wrappedResponse;
+
+        public ContinuationListenerWaitingForWrappedResponseToFinish(CompressedResponseWrapper wrappedResponse)
+        {
+            this.wrappedResponse = wrappedResponse;
+        }
+
+        public void onComplete(Continuation continuation)
+        {
+            try
+            {
+                wrappedResponse.finish();
+            }
+            catch (IOException e)
+            {
+                LOG.warn(e);
+            }
+        }
+
+        public void onTimeout(Continuation continuation)
+        {
+        }
+    }
+    
+    /**
+     * Checks to see if the userAgent is excluded
+     * 
+     * @param ua
+     *            the user agent
+     * @return boolean true if excluded
+     */
+    private boolean isExcludedAgent(String ua)
+    {
+        if (ua == null)
+            return false;
+
+        if (_excludedAgents != null)
+        {
+            if (_excludedAgents.contains(ua))
+            {
+                return true;
+            }
+        }
+        if (_excludedAgentPatterns != null)
+        {
+            for (Pattern pattern : _excludedAgentPatterns)
+            {
+                if (pattern.matcher(ua).matches())
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks to see if the path is excluded
+     * 
+     * @param requestURI
+     *            the request uri
+     * @return boolean true if excluded
+     */
+    private boolean isExcludedPath(String requestURI)
+    {
+        if (requestURI == null)
+            return false;
+        if (_excludedPaths != null)
+        {
+            for (String excludedPath : _excludedPaths)
+            {
+                if (requestURI.startsWith(excludedPath))
+                {
+                    return true;
+                }
+            }
+        }
+        if (_excludedPathPatterns != null)
+        {
+            for (Pattern pattern : _excludedPathPatterns)
+            {
+                if (pattern.matcher(requestURI).matches())
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/src/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
new file mode 100644
index 0000000..04aebdc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java
@@ -0,0 +1,171 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.gzip.CompressedResponseWrapper;
+import org.eclipse.jetty.http.gzip.AbstractCompressedStream;
+import org.eclipse.jetty.io.UncheckedPrintWriter;
+
+/* ------------------------------------------------------------ */
+/** Includable GZip Filter.
+ * This extension to the {@link GzipFilter} that uses Jetty features to allow
+ * headers to be set during calls to 
+ * {@link javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}.
+ * This allows the gzip filter to function correct during includes and to make a decision to gzip or not
+ * at the time the buffer fills and on the basis of all response headers.
+ * 
+ * If the init parameter "uncheckedPrintWriter" is set to "true", then the PrintWriter used by
+ * the wrapped getWriter will be {@link UncheckedPrintWriter}.
+ *
+ */
+public class IncludableGzipFilter extends GzipFilter
+{
+    boolean _uncheckedPrintWriter=false;
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        super.init(filterConfig);
+        
+        String tmp=filterConfig.getInitParameter("uncheckedPrintWriter");
+        if (tmp!=null)
+            _uncheckedPrintWriter=Boolean.valueOf(tmp).booleanValue();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.servlets.GzipFilter#createWrappedResponse(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
+     */
+    @Override
+    protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType)
+    {
+        CompressedResponseWrapper wrappedResponse = null;
+        if (compressionType==null)
+        {
+            wrappedResponse = new IncludableResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(null,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return null;
+                        }
+                    };
+                }
+            };
+        }
+        else if (compressionType.equals(GZIP))
+        {
+            wrappedResponse = new IncludableResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(compressionType,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return new GZIPOutputStream(_response.getOutputStream(),_bufferSize);
+                        }
+                    };
+                }
+            };
+        }
+        else if (compressionType.equals(DEFLATE))
+        {
+            wrappedResponse = new IncludableResponseWrapper(request,response)
+            {
+                @Override
+                protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException
+                {
+                    return new AbstractCompressedStream(compressionType,request,this,_vary)
+                    {
+                        @Override
+                        protected DeflaterOutputStream createStream() throws IOException
+                        {
+                            return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap));
+                        }
+                    };
+                }
+            };
+        }
+        else
+        {
+            throw new IllegalStateException(compressionType + " not supported");
+        }
+        configureWrappedResponse(wrappedResponse);
+        return wrappedResponse;
+    }
+
+
+    // Extend CompressedResponseWrapper to be able to set headers during include and to create unchecked printwriters
+    private abstract class IncludableResponseWrapper extends CompressedResponseWrapper
+    {
+        public IncludableResponseWrapper(HttpServletRequest request, HttpServletResponse response)
+        {
+            super(request,response);
+        }
+
+        @Override
+        public void setHeader(String name,String value)
+        {
+            super.setHeader(name,value);
+            HttpServletResponse response = (HttpServletResponse)getResponse();
+            if (!response.containsHeader(name))
+                response.setHeader("org.eclipse.jetty.server.include."+name,value);
+        }
+
+        @Override
+        public void addHeader(String name, String value)
+        {
+            super.addHeader(name, value);
+            HttpServletResponse response = (HttpServletResponse)getResponse();
+            if (!response.containsHeader(name))
+                setHeader(name,value);
+        }
+        
+        @Override
+        protected PrintWriter newWriter(OutputStream out, String encoding) throws UnsupportedEncodingException
+        {
+            if (_uncheckedPrintWriter)
+                return encoding == null?new UncheckedPrintWriter(out):new UncheckedPrintWriter(new OutputStreamWriter(out,encoding));
+            return super.newWriter(out,encoding);
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/src/java/org/eclipse/jetty/servlets/MultiPartFilter.java
new file mode 100644
index 0000000..980c1af
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/MultiPartFilter.java
@@ -0,0 +1,372 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.Part;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.MultiPartInputStream;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Multipart Form Data Filter.
+ * <p>
+ * This class decodes the multipart/form-data stream sent by a HTML form that uses a file input
+ * item.  Any files sent are stored to a temporary file and a File object added to the request 
+ * as an attribute.  All other values are made available via the normal getParameter API and
+ * the setCharacterEncoding mechanism is respected when converting bytes to Strings.
+ * <p>
+ * If the init parameter "delete" is set to "true", any files created will be deleted when the
+ * current request returns.
+ * <p>
+ * The init parameter maxFormKeys sets the maximum number of keys that may be present in a 
+ * form (default set by system property org.eclipse.jetty.server.Request.maxFormKeys or 1000) to protect 
+ * against DOS attacks by bad hash keys. 
+ * <p>
+ * The init parameter deleteFiles controls if uploaded files are automatically deleted after the request
+ * completes.
+ * 
+ * Use init parameter "maxFileSize" to set the max size file that can be uploaded.
+ * 
+ * Use init parameter "maxRequestSize" to limit the size of the multipart request.
+ * 
+ */
+public class MultiPartFilter implements Filter
+{
+    private static final Logger LOG = Log.getLogger(MultiPartFilter.class);
+    public final static String CONTENT_TYPE_SUFFIX=".org.eclipse.jetty.servlet.contentType";
+    private final static String MULTIPART = "org.eclipse.jetty.servlet.MultiPartFile.multiPartInputStream";
+    private File tempdir;
+    private boolean _deleteFiles;
+    private ServletContext _context;
+    private int _fileOutputBuffer = 0;
+    private long _maxFileSize = -1L;
+    private long _maxRequestSize = -1L;
+    private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys",1000).intValue();
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        tempdir=(File)filterConfig.getServletContext().getAttribute("javax.servlet.context.tempdir");
+        _deleteFiles="true".equals(filterConfig.getInitParameter("deleteFiles"));
+        String fileOutputBuffer = filterConfig.getInitParameter("fileOutputBuffer");
+        if(fileOutputBuffer!=null)
+            _fileOutputBuffer = Integer.parseInt(fileOutputBuffer);
+        String maxFileSize = filterConfig.getInitParameter("maxFileSize");
+        if (maxFileSize != null)
+            _maxFileSize = Long.parseLong(maxFileSize.trim());
+        String maxRequestSize = filterConfig.getInitParameter("maxRequestSize");
+        if (maxRequestSize != null)
+            _maxRequestSize = Long.parseLong(maxRequestSize.trim());
+        
+        _context=filterConfig.getServletContext();
+        String mfks = filterConfig.getInitParameter("maxFormKeys");
+        if (mfks!=null)
+            _maxFormKeys=Integer.parseInt(mfks);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
+     *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
+     */
+    public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) 
+        throws IOException, ServletException
+    {
+        HttpServletRequest srequest=(HttpServletRequest)request;
+        if(srequest.getContentType()==null||!srequest.getContentType().startsWith("multipart/form-data"))
+        {
+            chain.doFilter(request,response);
+            return;
+        }
+
+        InputStream in = new BufferedInputStream(request.getInputStream());
+        String content_type=srequest.getContentType();
+        
+        //Get current parameters so we can merge into them
+        MultiMap<String> params = new MultiMap<String>();
+        for (Iterator<Map.Entry<String,String[]>> i = request.getParameterMap().entrySet().iterator();i.hasNext();)
+        {
+            Map.Entry<String,String[]> entry=i.next();
+            Object value=entry.getValue();
+            if (value instanceof String[])
+                params.addValues(entry.getKey(),(String[])value);
+            else
+                params.add(entry.getKey(),value);
+        }
+        
+        MultipartConfigElement config = new MultipartConfigElement(tempdir.getCanonicalPath(), _maxFileSize, _maxRequestSize, _fileOutputBuffer);
+        MultiPartInputStream mpis = new MultiPartInputStream(in, content_type, config, tempdir);
+        mpis.setDeleteOnExit(_deleteFiles);
+        request.setAttribute(MULTIPART, mpis);
+
+        try
+        {
+            Collection<Part> parts = mpis.getParts();
+            if (parts != null)
+            {
+                Iterator<Part> itor = parts.iterator();
+                while (itor.hasNext() && params.size() < _maxFormKeys)
+                {
+                    Part p = itor.next();
+                    MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p;
+                    if (mp.getFile() != null)
+                    {
+                        request.setAttribute(mp.getName(),mp.getFile());
+                        if (mp.getContentDispositionFilename() != null)
+                        {
+                            params.add(mp.getName(), mp.getContentDispositionFilename());
+                            if (mp.getContentType() != null)
+                                params.add(mp.getName()+CONTENT_TYPE_SUFFIX, mp.getContentType());
+                        }
+                    }
+                    else
+                    {
+                        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+                        IO.copy(p.getInputStream(), bytes);
+                        params.add(p.getName(), bytes.toByteArray());
+                        if (p.getContentType() != null)
+                            params.add(p.getName()+CONTENT_TYPE_SUFFIX, p.getContentType());
+                    }
+                }
+            }
+
+            // handle request
+            chain.doFilter(new Wrapper(srequest,params),response);
+        }
+        finally
+        {
+            deleteFiles(request);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private void deleteFiles(ServletRequest request)
+    {
+        if (!_deleteFiles)
+            return;
+        
+        MultiPartInputStream mpis = (MultiPartInputStream)request.getAttribute(MULTIPART);
+        if (mpis != null)
+        {
+            try
+            {
+                mpis.deleteParts();
+            }
+            catch (Exception e)
+            {
+                _context.log("Error deleting multipart tmp files", e);
+            }
+        }
+        request.removeAttribute(MULTIPART);
+    }
+    
+ 
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy()
+    {
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    private static class Wrapper extends HttpServletRequestWrapper
+    {
+        String _encoding=StringUtil.__UTF8;
+        MultiMap _params;
+        
+        /* ------------------------------------------------------------------------------- */
+        /** Constructor.
+         * @param request
+         */
+        public Wrapper(HttpServletRequest request, MultiMap map)
+        {
+            super(request);
+            this._params=map;
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#getContentLength()
+         */
+        @Override
+        public int getContentLength()
+        {
+            return 0;
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
+         */
+        @Override
+        public String getParameter(String name)
+        {
+            Object o=_params.get(name);
+            if (!(o instanceof byte[]) && LazyList.size(o)>0)
+                o=LazyList.get(o,0);
+            
+            if (o instanceof byte[])
+            {
+                try
+                {
+                   return getParameterBytesAsString(name, (byte[])o);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn(e);
+                }
+            }
+            else if (o!=null)
+                return String.valueOf(o);
+            return null;
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#getParameterMap()
+         */
+        @Override
+        public Map getParameterMap()
+        {
+            Map<String, String[]> cmap = new HashMap<String,String[]>();
+            
+            for ( Object key : _params.keySet() )
+            {
+                cmap.put((String)key,getParameterValues((String)key));
+            }
+            
+            return Collections.unmodifiableMap(cmap);
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#getParameterNames()
+         */
+        @Override
+        public Enumeration getParameterNames()
+        {
+            return Collections.enumeration(_params.keySet());
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
+         */
+        @Override
+        public String[] getParameterValues(String name)
+        {
+            List l=_params.getValues(name);
+            if (l==null || l.size()==0)
+                return new String[0];
+            String[] v = new String[l.size()];
+            for (int i=0;i<l.size();i++)
+            {
+                Object o=l.get(i);
+                if (o instanceof byte[])
+                {
+                    try
+                    {
+                        v[i]=getParameterBytesAsString(name, (byte[])o);
+                    }
+                    catch(Exception e)
+                    {
+                        throw new RuntimeException(e);
+                    }
+                }
+                else if (o instanceof String)
+                    v[i]=(String)o;
+            }
+            return v;
+        }
+        
+        /* ------------------------------------------------------------------------------- */
+        /**
+         * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+         */
+        @Override
+        public void setCharacterEncoding(String enc) 
+            throws UnsupportedEncodingException
+        {
+            _encoding=enc;
+        }
+        
+        
+        /* ------------------------------------------------------------------------------- */
+        private String getParameterBytesAsString (String name, byte[] bytes) 
+        throws UnsupportedEncodingException
+        {
+            //check if there is a specific encoding for the parameter
+            Object ct = _params.get(name+CONTENT_TYPE_SUFFIX);
+            //use default if not
+            String contentType = _encoding;
+            if (ct != null)
+            {
+                String tmp = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer((String)ct));
+                contentType = (tmp == null?_encoding:tmp);
+            }
+            
+            return new String(bytes,contentType);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/ProxyServlet.java b/src/java/org/eclipse/jetty/servlets/ProxyServlet.java
new file mode 100644
index 0000000..86f208b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/ProxyServlet.java
@@ -0,0 +1,908 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpExchange;
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.http.HttpHeaderValues;
+import org.eclipse.jetty.http.HttpHeaders;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.http.PathMap;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.util.HostMap;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+/**
+ * Asynchronous Proxy Servlet.
+ *
+ * Forward requests to another server either as a standard web proxy (as defined by RFC2616) or as a transparent proxy.
+ * <p>
+ * This servlet needs the jetty-util and jetty-client classes to be available to the web application.
+ * <p>
+ * To facilitate JMX monitoring, the "HttpClient" and "ThreadPool" are set as context attributes prefixed with the servlet name.
+ * <p>
+ * The following init parameters may be used to configure the servlet:
+ * <ul>
+ * <li>name - Name of Proxy servlet (default: "ProxyServlet"
+ * <li>maxThreads - maximum threads
+ * <li>maxConnections - maximum connections per destination
+ * <li>timeout - the period in ms the client will wait for a response from the proxied server
+ * <li>idleTimeout - the period in ms a connection to proxied server can be idle for before it is closed
+ * <li>requestHeaderSize - the size of the request header buffer (d. 6,144)
+ * <li>requestBufferSize - the size of the request buffer (d. 12,288)
+ * <li>responseHeaderSize - the size of the response header buffer (d. 6,144)
+ * <li>responseBufferSize - the size of the response buffer (d. 32,768)
+ * <li>HostHeader - Force the host header to a particular value
+ * <li>whiteList - comma-separated list of allowed proxy destinations
+ * <li>blackList - comma-separated list of forbidden proxy destinations
+ * </ul>
+ *
+ * @see org.eclipse.jetty.server.handler.ConnectHandler
+ */
+public class ProxyServlet implements Servlet
+{
+    protected Logger _log;
+    protected HttpClient _client;
+    protected String _hostHeader;
+
+    protected HashSet<String> _DontProxyHeaders = new HashSet<String>();
+    {
+        _DontProxyHeaders.add("proxy-connection");
+        _DontProxyHeaders.add("connection");
+        _DontProxyHeaders.add("keep-alive");
+        _DontProxyHeaders.add("transfer-encoding");
+        _DontProxyHeaders.add("te");
+        _DontProxyHeaders.add("trailer");
+        _DontProxyHeaders.add("proxy-authorization");
+        _DontProxyHeaders.add("proxy-authenticate");
+        _DontProxyHeaders.add("upgrade");
+    }
+
+    protected ServletConfig _config;
+    protected ServletContext _context;
+    protected HostMap<PathMap> _white = new HostMap<PathMap>();
+    protected HostMap<PathMap> _black = new HostMap<PathMap>();
+
+    /* ------------------------------------------------------------ */
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
+     */
+    public void init(ServletConfig config) throws ServletException
+    {
+        _config = config;
+        _context = config.getServletContext();
+
+        _hostHeader = config.getInitParameter("HostHeader");
+
+        try
+        {
+            _log = createLogger(config);
+
+            _client = createHttpClient(config);
+
+            if (_context != null)
+            {
+                _context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
+                _context.setAttribute(config.getServletName() + ".HttpClient",_client);
+            }
+
+            String white = config.getInitParameter("whiteList");
+            if (white != null)
+            {
+                parseList(white,_white);
+            }
+            String black = config.getInitParameter("blackList");
+            if (black != null)
+            {
+                parseList(black,_black);
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ServletException(e);
+        }
+    }
+
+    public void destroy()
+    {
+        try
+        {
+            _client.stop();
+        }
+        catch (Exception x)
+        {
+            _log.debug(x);
+        }
+    }
+
+
+    /**
+     * Create and return a logger based on the ServletConfig for use in the
+     * proxy servlet
+     *
+     * @param config
+     * @return Logger
+     */
+    protected Logger createLogger(ServletConfig config)
+    {
+        return Log.getLogger("org.eclipse.jetty.servlets." + config.getServletName());
+    }
+
+    /**
+     * Create and return an HttpClientInstance
+     *
+     * @return HttpClient
+     */
+    protected HttpClient createHttpClientInstance()
+    {
+        return new HttpClient();
+    }
+
+    /**
+     * Create and return an HttpClient based on ServletConfig
+     *
+     * By default this implementation will create an instance of the
+     * HttpClient for use by this proxy servlet.
+     *
+     * @param config
+     * @return HttpClient
+     * @throws Exception
+     */
+    protected HttpClient createHttpClient(ServletConfig config) throws Exception
+    {
+        HttpClient client = createHttpClientInstance();
+        client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
+
+        String t = config.getInitParameter("maxThreads");
+
+        if (t != null)
+        {
+            client.setThreadPool(new QueuedThreadPool(Integer.parseInt(t)));
+        }
+        else
+        {
+            client.setThreadPool(new QueuedThreadPool());
+        }
+
+        ((QueuedThreadPool)client.getThreadPool()).setName(config.getServletName());
+
+        t = config.getInitParameter("maxConnections");
+
+        if (t != null)
+        {
+            client.setMaxConnectionsPerAddress(Integer.parseInt(t));
+        }
+
+        t = config.getInitParameter("timeout");
+
+        if ( t != null )
+        {
+            client.setTimeout(Long.parseLong(t));
+        }
+
+        t = config.getInitParameter("idleTimeout");
+
+        if ( t != null )
+        {
+            client.setIdleTimeout(Long.parseLong(t));
+        }
+
+        t = config.getInitParameter("requestHeaderSize");
+
+        if ( t != null )
+        {
+            client.setRequestHeaderSize(Integer.parseInt(t));
+        }
+
+        t = config.getInitParameter("requestBufferSize");
+
+        if ( t != null )
+        {
+            client.setRequestBufferSize(Integer.parseInt(t));
+        }
+
+        t = config.getInitParameter("responseHeaderSize");
+
+        if ( t != null )
+        {
+            client.setResponseHeaderSize(Integer.parseInt(t));
+        }
+
+        t = config.getInitParameter("responseBufferSize");
+
+        if ( t != null )
+        {
+            client.setResponseBufferSize(Integer.parseInt(t));
+        }
+
+        client.start();
+
+        return client;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Helper function to process a parameter value containing a list of new entries and initialize the specified host map.
+     *
+     * @param list
+     *            comma-separated list of new entries
+     * @param hostMap
+     *            target host map
+     */
+    private void parseList(String list, HostMap<PathMap> hostMap)
+    {
+        if (list != null && list.length() > 0)
+        {
+            int idx;
+            String entry;
+
+            StringTokenizer entries = new StringTokenizer(list,",");
+            while (entries.hasMoreTokens())
+            {
+                entry = entries.nextToken();
+                idx = entry.indexOf('/');
+
+                String host = idx > 0?entry.substring(0,idx):entry;
+                String path = idx > 0?entry.substring(idx):"/*";
+
+                host = host.trim();
+                PathMap pathMap = hostMap.get(host);
+                if (pathMap == null)
+                {
+                    pathMap = new PathMap(true);
+                    hostMap.put(host,pathMap);
+                }
+                if (path != null)
+                {
+                    pathMap.put(path,path);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Check the request hostname and path against white- and blacklist.
+     *
+     * @param host
+     *            hostname to check
+     * @param path
+     *            path to check
+     * @return true if request is allowed to be proxied
+     */
+    public boolean validateDestination(String host, String path)
+    {
+        if (_white.size() > 0)
+        {
+            boolean match = false;
+
+            Object whiteObj = _white.getLazyMatches(host);
+            if (whiteObj != null)
+            {
+                List whiteList = (whiteObj instanceof List)?(List)whiteObj:Collections.singletonList(whiteObj);
+
+                for (Object entry : whiteList)
+                {
+                    PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
+                    if (match = (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null)))
+                        break;
+                }
+            }
+
+            if (!match)
+                return false;
+        }
+
+        if (_black.size() > 0)
+        {
+            Object blackObj = _black.getLazyMatches(host);
+            if (blackObj != null)
+            {
+                List blackList = (blackObj instanceof List)?(List)blackObj:Collections.singletonList(blackObj);
+
+                for (Object entry : blackList)
+                {
+                    PathMap pathMap = ((Map.Entry<String, PathMap>)entry).getValue();
+                    if (pathMap != null && (pathMap.size() == 0 || pathMap.match(path) != null))
+                        return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.servlet.Servlet#getServletConfig()
+     */
+    public ServletConfig getServletConfig()
+    {
+        return _config;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the hostHeader.
+     *
+     * @return the hostHeader
+     */
+    public String getHostHeader()
+    {
+        return _hostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the hostHeader.
+     *
+     * @param hostHeader
+     *            the hostHeader to set
+     */
+    public void setHostHeader(String hostHeader)
+    {
+        _hostHeader = hostHeader;
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
+    {
+        final int debug = _log.isDebugEnabled()?req.hashCode():0;
+
+        final HttpServletRequest request = (HttpServletRequest)req;
+        final HttpServletResponse response = (HttpServletResponse)res;
+
+        if ("CONNECT".equalsIgnoreCase(request.getMethod()))
+        {
+            handleConnect(request,response);
+        }
+        else
+        {
+            final InputStream in = request.getInputStream();
+            final OutputStream out = response.getOutputStream();
+
+            final Continuation continuation = ContinuationSupport.getContinuation(request);
+
+            if (!continuation.isInitial())
+                response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial
+            else
+            {
+
+                String uri = request.getRequestURI();
+                if (request.getQueryString() != null)
+                    uri += "?" + request.getQueryString();
+
+                HttpURI url = proxyHttpURI(request,uri);
+
+                if (debug != 0)
+                    _log.debug(debug + " proxy " + uri + "-->" + url);
+
+                if (url == null)
+                {
+                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                    return;
+                }
+
+                HttpExchange exchange = new HttpExchange()
+                {
+                    @Override
+                    protected void onRequestCommitted() throws IOException
+                    {
+                    }
+
+                    @Override
+                    protected void onRequestComplete() throws IOException
+                    {
+                    }
+
+                    @Override
+                    protected void onResponseComplete() throws IOException
+                    {
+                        if (debug != 0)
+                            _log.debug(debug + " complete");
+                        continuation.complete();
+                    }
+
+                    @Override
+                    protected void onResponseContent(Buffer content) throws IOException
+                    {
+                        if (debug != 0)
+                            _log.debug(debug + " content" + content.length());
+                        content.writeTo(out);
+                    }
+
+                    @Override
+                    protected void onResponseHeaderComplete() throws IOException
+                    {
+                    }
+
+                    @Override
+                    protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
+                    {
+                        if (debug != 0)
+                            _log.debug(debug + " " + version + " " + status + " " + reason);
+
+                        if (reason != null && reason.length() > 0)
+                            response.setStatus(status,reason.toString());
+                        else
+                            response.setStatus(status);
+                    }
+
+                    @Override
+                    protected void onResponseHeader(Buffer name, Buffer value) throws IOException
+                    {
+                        String nameString = name.toString();
+                        String s = nameString.toLowerCase(Locale.ENGLISH);
+                        if (!_DontProxyHeaders.contains(s) || (HttpHeaders.CONNECTION_BUFFER.equals(name) && HttpHeaderValues.CLOSE_BUFFER.equals(value)))
+                        {
+                            if (debug != 0)
+                                _log.debug(debug + " " + name + ": " + value);
+
+                            String filteredHeaderValue = filterResponseHeaderValue(nameString,value.toString(),request);
+                            if (filteredHeaderValue != null && filteredHeaderValue.trim().length() > 0)
+                            {
+                                if (debug != 0)
+                                    _log.debug(debug + " " + name + ": (filtered): " + filteredHeaderValue);
+                                response.addHeader(nameString,filteredHeaderValue);
+                            }
+                        }
+                        else if (debug != 0)
+                            _log.debug(debug + " " + name + "! " + value);
+                    }
+
+                    @Override
+                    protected void onConnectionFailed(Throwable ex)
+                    {
+                        handleOnConnectionFailed(ex,request,response);
+
+                        // it is possible this might trigger before the
+                        // continuation.suspend()
+                        if (!continuation.isInitial())
+                        {
+                            continuation.complete();
+                        }
+                    }
+
+                    @Override
+                    protected void onException(Throwable ex)
+                    {
+                        if (ex instanceof EofException)
+                        {
+                            _log.ignore(ex);
+                            //return;
+                        }
+                        handleOnException(ex,request,response);
+
+                        // it is possible this might trigger before the
+                        // continuation.suspend()
+                        if (!continuation.isInitial())
+                        {
+                            continuation.complete();
+                        }
+                    }
+
+                    @Override
+                    protected void onExpire()
+                    {
+                        handleOnExpire(request,response);
+                        continuation.complete();
+                    }
+
+                };
+
+                exchange.setScheme(HttpSchemes.HTTPS.equals(request.getScheme())?HttpSchemes.HTTPS_BUFFER:HttpSchemes.HTTP_BUFFER);
+                exchange.setMethod(request.getMethod());
+                exchange.setURL(url.toString());
+                exchange.setVersion(request.getProtocol());
+
+
+                if (debug != 0)
+                    _log.debug(debug + " " + request.getMethod() + " " + url + " " + request.getProtocol());
+
+                // check connection header
+                String connectionHdr = request.getHeader("Connection");
+                if (connectionHdr != null)
+                {
+                    connectionHdr = connectionHdr.toLowerCase(Locale.ENGLISH);
+                    if (connectionHdr.indexOf("keep-alive") < 0 && connectionHdr.indexOf("close") < 0)
+                        connectionHdr = null;
+                }
+
+                // force host
+                if (_hostHeader != null)
+                    exchange.setRequestHeader("Host",_hostHeader);
+
+                // copy headers
+                boolean xForwardedFor = false;
+                boolean hasContent = false;
+                long contentLength = -1;
+                Enumeration<?> enm = request.getHeaderNames();
+                while (enm.hasMoreElements())
+                {
+                    // TODO could be better than this!
+                    String hdr = (String)enm.nextElement();
+                    String lhdr = hdr.toLowerCase(Locale.ENGLISH);
+
+                    if ("transfer-encoding".equals(lhdr))
+                    {
+                        if (request.getHeader("transfer-encoding").indexOf("chunk")>=0)
+                            hasContent = true;
+                    }
+                    
+                    if (_DontProxyHeaders.contains(lhdr))
+                        continue;
+                    if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0)
+                        continue;
+                    if (_hostHeader != null && "host".equals(lhdr))
+                        continue;
+
+                    if ("content-type".equals(lhdr))
+                        hasContent = true;
+                    else if ("content-length".equals(lhdr))
+                    {
+                        contentLength = request.getContentLength();
+                        exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,Long.toString(contentLength));
+                        if (contentLength > 0)
+                            hasContent = true;
+                    }
+                    else if ("x-forwarded-for".equals(lhdr))
+                        xForwardedFor = true;
+
+                    Enumeration<?> vals = request.getHeaders(hdr);
+                    while (vals.hasMoreElements())
+                    {
+                        String val = (String)vals.nextElement();
+                        if (val != null)
+                        {
+                            if (debug != 0)
+                                _log.debug(debug + " " + hdr + ": " + val);
+
+                            exchange.setRequestHeader(hdr,val);
+                        }
+                    }
+                }
+
+                // Proxy headers
+                exchange.setRequestHeader("Via","1.1 (jetty)");
+                if (!xForwardedFor)
+                {
+                    exchange.addRequestHeader("X-Forwarded-For",request.getRemoteAddr());
+                    exchange.addRequestHeader("X-Forwarded-Proto",request.getScheme());
+                    exchange.addRequestHeader("X-Forwarded-Host",request.getHeader("Host"));
+                    exchange.addRequestHeader("X-Forwarded-Server",request.getLocalName());
+                }
+
+                if (hasContent)
+                {
+                    exchange.setRequestContentSource(in);
+                }
+
+                customizeExchange(exchange, request);
+
+                /*
+                 * we need to set the timeout on the continuation to take into
+                 * account the timeout of the HttpClient and the HttpExchange
+                 */
+                long ctimeout = (_client.getTimeout() > exchange.getTimeout()) ? _client.getTimeout() : exchange.getTimeout();
+
+                // continuation fudge factor of 1000, underlying components
+                // should fail/expire first from exchange
+                if ( ctimeout == 0 )
+                {
+                    continuation.setTimeout(0);  // ideally never times out
+                }
+                else
+                {
+                    continuation.setTimeout(ctimeout + 1000);
+                }
+
+                customizeContinuation(continuation);
+
+                continuation.suspend(response);
+                _client.send(exchange);
+
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handleConnect(HttpServletRequest request, HttpServletResponse response) throws IOException
+    {
+        String uri = request.getRequestURI();
+
+        String port = "";
+        String host = "";
+
+        int c = uri.indexOf(':');
+        if (c >= 0)
+        {
+            port = uri.substring(c + 1);
+            host = uri.substring(0,c);
+            if (host.indexOf('/') > 0)
+                host = host.substring(host.indexOf('/') + 1);
+        }
+
+        // TODO - make this async!
+
+        InetSocketAddress inetAddress = new InetSocketAddress(host,Integer.parseInt(port));
+
+        // if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false))
+        // {
+        // sendForbid(request,response,uri);
+        // }
+        // else
+        {
+            InputStream in = request.getInputStream();
+            OutputStream out = response.getOutputStream();
+
+            Socket socket = new Socket(inetAddress.getAddress(),inetAddress.getPort());
+
+            response.setStatus(200);
+            response.setHeader("Connection","close");
+            response.flushBuffer();
+            // TODO prevent real close!
+
+            IO.copyThread(socket.getInputStream(),out);
+            IO.copy(in,socket.getOutputStream());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected HttpURI proxyHttpURI(HttpServletRequest request, String uri) throws MalformedURLException
+    {
+        return proxyHttpURI(request.getScheme(), request.getServerName(), request.getServerPort(), uri);
+    }
+
+    protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException
+    {
+        if (!validateDestination(serverName,uri))
+            return null;
+
+        return new HttpURI(scheme + "://" + serverName + ":" + serverPort + uri);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.servlet.Servlet#getServletInfo()
+     */
+    public String getServletInfo()
+    {
+        return "Proxy Servlet";
+    }
+
+
+    /**
+     * Extension point for subclasses to customize an exchange. Useful for setting timeouts etc. The default implementation does nothing.
+     *
+     * @param exchange
+     * @param request
+     */
+    protected void customizeExchange(HttpExchange exchange, HttpServletRequest request)
+    {
+
+    }
+
+    /**
+     * Extension point for subclasses to customize the Continuation after it's initial creation in the service method. Useful for setting timeouts etc. The
+     * default implementation does nothing.
+     *
+     * @param continuation
+     */
+    protected void customizeContinuation(Continuation continuation)
+    {
+
+    }
+
+    /**
+     * Extension point for custom handling of an HttpExchange's onConnectionFailed method. The default implementation delegates to
+     * {@link #handleOnException(Throwable, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+     *
+     * @param ex
+     * @param request
+     * @param response
+     */
+    protected void handleOnConnectionFailed(Throwable ex, HttpServletRequest request, HttpServletResponse response)
+    {
+        handleOnException(ex,request,response);
+    }
+
+    /**
+     * Extension point for custom handling of an HttpExchange's onException method. The default implementation sets the response status to
+     * HttpServletResponse.SC_INTERNAL_SERVER_ERROR (503)
+     *
+     * @param ex
+     * @param request
+     * @param response
+     */
+    protected void handleOnException(Throwable ex, HttpServletRequest request, HttpServletResponse response)
+    {
+        if (ex instanceof IOException)
+        {
+            _log.warn(ex.toString());
+            _log.debug(ex);
+        }
+        else
+            _log.warn(ex);
+        
+        if (!response.isCommitted())
+        {
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * Extension point for custom handling of an HttpExchange's onExpire method. The default implementation sets the response status to
+     * HttpServletResponse.SC_GATEWAY_TIMEOUT (504)
+     *
+     * @param request
+     * @param response
+     */
+    protected void handleOnExpire(HttpServletRequest request, HttpServletResponse response)
+    {
+        if (!response.isCommitted())
+        {
+            response.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
+        }
+    }
+
+    /**
+     * Extension point for remote server response header filtering. The default implementation returns the header value as is. If null is returned, this header
+     * won't be forwarded back to the client.
+     * 
+     * @param headerName
+     * @param headerValue
+     * @param request
+     * @return filteredHeaderValue
+     */
+    protected String filterResponseHeaderValue(String headerName, String headerValue, HttpServletRequest request)
+    {
+        return headerValue;
+    }
+
+    /**
+     * Transparent Proxy.
+     * 
+     * This convenience extension to ProxyServlet configures the servlet as a transparent proxy. The servlet is configured with init parameters:
+     * <ul>
+     * <li>ProxyTo - a URI like http://host:80/context to which the request is proxied.
+     * <li>Prefix - a URI prefix that is striped from the start of the forwarded URI.
+     * </ul>
+     * For example, if a request was received at /foo/bar and the ProxyTo was http://host:80/context and the Prefix was /foo, then the request would be proxied
+     * to http://host:80/context/bar
+     * 
+     */
+    public static class Transparent extends ProxyServlet
+    {
+        String _prefix;
+        String _proxyTo;
+
+        public Transparent()
+        {
+        }
+
+        public Transparent(String prefix, String host, int port)
+        {
+            this(prefix,"http",host,port,null);
+        }
+
+        public Transparent(String prefix, String schema, String host, int port, String path)
+        {
+            try
+            {
+                if (prefix != null)
+                {
+                    _prefix = new URI(prefix).normalize().toString();
+                }
+                _proxyTo = new URI(schema,null,host,port,path,null,null).normalize().toString();
+            }
+            catch (URISyntaxException ex)
+            {
+                _log.debug("Invalid URI syntax",ex);
+            }
+        }
+
+        @Override
+        public void init(ServletConfig config) throws ServletException
+        {
+            super.init(config);
+
+            String prefix = config.getInitParameter("Prefix");
+            _prefix = prefix == null?_prefix:prefix;
+
+            // Adjust prefix value to account for context path
+            String contextPath = _context.getContextPath();
+            _prefix = _prefix == null?contextPath:(contextPath + _prefix);
+
+            String proxyTo = config.getInitParameter("ProxyTo");
+            _proxyTo = proxyTo == null?_proxyTo:proxyTo;
+
+            if (_proxyTo == null)
+                throw new UnavailableException("ProxyTo parameter is requred.");
+
+            if (!_prefix.startsWith("/"))
+                throw new UnavailableException("Prefix parameter must start with a '/'.");
+
+            _log.info(config.getServletName() + " @ " + _prefix + " to " + _proxyTo);
+        }
+
+        @Override
+        protected HttpURI proxyHttpURI(final String scheme, final String serverName, int serverPort, final String uri) throws MalformedURLException
+        {
+            try
+            {
+                if (!uri.startsWith(_prefix))
+                    return null;
+
+                URI dstUri = new URI(_proxyTo + uri.substring(_prefix.length())).normalize();
+
+                if (!validateDestination(dstUri.getHost(),dstUri.getPath()))
+                    return null;
+
+                return new HttpURI(dstUri.toString());
+            }
+            catch (URISyntaxException ex)
+            {
+                throw new MalformedURLException(ex.getMessage());
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/PutFilter.java b/src/java/org/eclipse/jetty/servlets/PutFilter.java
new file mode 100644
index 0000000..fa64e24
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/PutFilter.java
@@ -0,0 +1,374 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.URIUtil;
+
+/**
+ * PutFilter
+ * 
+ * A Filter that handles PUT, DELETE and MOVE methods.
+ * Files are hidden during PUT operations, so that 404's result.
+ * 
+ * The following init parameters pay be used:<ul>
+ * <li><b>baseURI</b> - The file URI of the document root for put content.
+ * <li><b>delAllowed</b> - boolean, if true DELETE and MOVE methods are supported.
+ * <li><b>putAtomic</b> - boolean, if true PUT files are written to a temp location and moved into place.
+ * </ul>
+ *
+ */
+public class PutFilter implements Filter 
+{
+    public final static String __PUT="PUT";
+    public final static String __DELETE="DELETE";
+    public final static String __MOVE="MOVE";
+    public final static String __OPTIONS="OPTIONS";
+
+    Set<String> _operations = new HashSet<String>();
+    private ConcurrentMap<String,String> _hidden = new ConcurrentHashMap<String, String>();
+
+    private ServletContext _context;
+    private String _baseURI;
+    private boolean _delAllowed;
+    private boolean _putAtomic;
+    private File _tmpdir;
+    
+    
+    /* ------------------------------------------------------------ */
+    public void init(FilterConfig config) throws ServletException
+    {
+        _context=config.getServletContext();
+        
+        _tmpdir=(File)_context.getAttribute("javax.servlet.context.tempdir");
+            
+        if (_context.getRealPath("/")==null)
+           throw new UnavailableException("Packed war");
+        
+        String b = config.getInitParameter("baseURI");
+        if (b != null)
+        {
+            _baseURI=b;
+        }
+        else
+        {
+            File base=new File(_context.getRealPath("/"));
+            _baseURI=base.toURI().toString();
+        }
+        
+        _delAllowed = getInitBoolean(config,"delAllowed");
+        _putAtomic = getInitBoolean(config,"putAtomic");
+
+        _operations.add(__OPTIONS);
+        _operations.add(__PUT);
+        if (_delAllowed)
+        {
+            _operations.add(__DELETE);
+            _operations.add(__MOVE);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean getInitBoolean(FilterConfig config,String name)
+    {
+        String value = config.getInitParameter(name);
+        return value != null && value.length() > 0 && (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || value.startsWith("Y") || value.startsWith("1"));
+    }
+
+    /* ------------------------------------------------------------ */
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
+    {
+        HttpServletRequest request=(HttpServletRequest)req;
+        HttpServletResponse response=(HttpServletResponse)res;
+
+        String servletPath =request.getServletPath();
+        String pathInfo = request.getPathInfo();
+        String pathInContext = URIUtil.addPaths(servletPath, pathInfo);    
+
+        String resource = URIUtil.addPaths(_baseURI,pathInContext); 
+       
+        String method = request.getMethod();
+        boolean op = _operations.contains(method);
+        
+        if (op)
+        {
+            File file = null;
+            try
+            {
+                if (method.equals(__OPTIONS))
+                    handleOptions(chain,request, response);
+                else
+                {
+                    file=new File(new URI(resource));
+                    boolean exists = file.exists();
+                    if (exists && !passConditionalHeaders(request, response, file))
+                        return;
+                    
+                    if (method.equals(__PUT))
+                        handlePut(request, response,pathInContext, file);
+                    else if (method.equals(__DELETE))
+                        handleDelete(request, response, pathInContext, file);
+                    else if (method.equals(__MOVE))
+                        handleMove(request, response, pathInContext, file);
+                    else
+                        throw new IllegalStateException();
+                }
+            }
+            catch(Exception e)
+            {
+                _context.log(e.toString(),e);
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+        }
+        else
+        {
+            if (isHidden(pathInContext))
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            else
+                chain.doFilter(request,response);
+            return;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean isHidden(String pathInContext)
+    {
+        return _hidden.containsKey(pathInContext);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void destroy()
+    {
+    }
+
+    /* ------------------------------------------------------------------- */
+    public void handlePut(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException
+    {
+        boolean exists = file.exists();
+        if (pathInContext.endsWith("/"))
+        {
+            if (!exists)
+            {
+                if (!file.mkdirs())
+                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                else
+                {
+                    response.setStatus(HttpServletResponse.SC_CREATED);
+                    response.flushBuffer();
+                }
+            }
+            else
+            {
+                response.setStatus(HttpServletResponse.SC_OK);
+                response.flushBuffer();
+            }
+        }
+        else
+        {
+            boolean ok=false;
+            try
+            {
+                _hidden.put(pathInContext,pathInContext);
+                File parent = file.getParentFile();
+                parent.mkdirs();
+                int toRead = request.getContentLength();
+                InputStream in = request.getInputStream();
+                
+                    
+                if (_putAtomic)
+                {
+                    File tmp=File.createTempFile(file.getName(),null,_tmpdir);
+                    OutputStream out = new FileOutputStream(tmp,false);
+                    if (toRead >= 0)
+                        IO.copy(in, out, toRead);
+                    else
+                        IO.copy(in, out);
+                    out.close();
+                    
+                    if (!tmp.renameTo(file))
+                        throw new IOException("rename from "+tmp+" to "+file+" failed");
+                }
+                else
+                {
+                    OutputStream out = new FileOutputStream(file,false);
+                    if (toRead >= 0)
+                        IO.copy(in, out, toRead);
+                    else
+                        IO.copy(in, out);
+                    out.close();
+                }
+
+                response.setStatus(exists ? HttpServletResponse.SC_OK : HttpServletResponse.SC_CREATED);
+                response.flushBuffer();
+                ok=true;
+            }
+            catch (Exception ex)
+            {
+                _context.log(ex.toString(),ex);
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+            }
+            finally
+            {
+                if (!ok)
+                {
+                    try
+                    {
+                        if (file.exists())
+                            file.delete();
+                    }
+                    catch(Exception e)
+                    {
+                        _context.log(e.toString(),e);
+                    }
+                }
+                _hidden.remove(pathInContext);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------------- */
+    public void handleDelete(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException
+    {
+        try
+        {
+            // delete the file
+            if (file.delete())
+            {
+                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                response.flushBuffer();
+            }
+            else
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+        catch (SecurityException sex)
+        {
+            _context.log(sex.toString(),sex);
+            response.sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+    }
+
+    /* ------------------------------------------------------------------- */
+    public void handleMove(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) 
+        throws ServletException, IOException, URISyntaxException
+    {
+        String newPath = URIUtil.canonicalPath(request.getHeader("new-uri"));
+        if (newPath == null)
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+        
+        String contextPath = request.getContextPath();
+        if (contextPath != null && !newPath.startsWith(contextPath))
+        {
+            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            return;
+        }
+        String newInfo = newPath;
+        if (contextPath != null)
+            newInfo = newInfo.substring(contextPath.length());
+
+        String new_resource = URIUtil.addPaths(_baseURI,newInfo);
+        File new_file=new File(new URI(new_resource));
+
+        file.renameTo(new_file);
+
+        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+        response.flushBuffer();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handleOptions(FilterChain chain, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        chain.doFilter(request,new HttpServletResponseWrapper(response)
+        {
+            @Override
+            public void setHeader(String name, String value)
+            {
+                if ("Allow".equalsIgnoreCase(name))
+                {
+                    Set<String> options = new HashSet<String>();
+                    options.addAll(Arrays.asList(value.split(" *, *")));
+                    options.addAll(_operations);
+                    value=null;
+                    for (String o : options)
+                        value=value==null?o:(value+", "+o);
+                }
+                    
+                super.setHeader(name,value);
+            }
+        });
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Check modification date headers.
+     */
+    protected boolean passConditionalHeaders(HttpServletRequest request, HttpServletResponse response, File file) throws IOException
+    {
+        long date = 0;
+        
+        if ((date = request.getDateHeader("if-unmodified-since")) > 0)
+        {
+            if (file.lastModified() / 1000 > date / 1000)
+            {
+                response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                return false;
+            }
+        }
+
+        if ((date = request.getDateHeader("if-modified-since")) > 0)
+        {
+            if (file.lastModified() / 1000 <= date / 1000)
+            {
+                response.reset();
+                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                response.flushBuffer();
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/QoSFilter.java b/src/java/org/eclipse/jetty/servlets/QoSFilter.java
new file mode 100644
index 0000000..8844789
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/QoSFilter.java
@@ -0,0 +1,347 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
+import org.eclipse.jetty.continuation.ContinuationSupport;
+import org.eclipse.jetty.server.handler.ContextHandler;
+
+/**
+ * Quality of Service Filter.
+ * 
+ * This filter limits the number of active requests to the number set by the "maxRequests" init parameter (default 10).
+ * If more requests are received, they are suspended and placed on priority queues.  Priorities are determined by 
+ * the {@link #getPriority(ServletRequest)} method and are a value between 0 and the value given by the "maxPriority" 
+ * init parameter (default 10), with higher values having higher priority.
+ * </p><p>
+ * This filter is ideal to prevent wasting threads waiting for slow/limited 
+ * resources such as a JDBC connection pool.  It avoids the situation where all of a 
+ * containers thread pool may be consumed blocking on such a slow resource.
+ * By limiting the number of active threads, a smaller thread pool may be used as 
+ * the threads are not wasted waiting.  Thus more memory may be available for use by 
+ * the active threads.
+ * </p><p>
+ * Furthermore, this filter uses a priority when resuming waiting requests. So that if
+ * a container is under load, and there are many requests waiting for resources,
+ * the {@link #getPriority(ServletRequest)} method is used, so that more important 
+ * requests are serviced first.     For example, this filter could be deployed with a 
+ * maxRequest limit slightly smaller than the containers thread pool and a high priority 
+ * allocated to admin users.  Thus regardless of load, admin users would always be
+ * able to access the web application.
+ * </p><p>
+ * The maxRequest limit is policed by a {@link Semaphore} and the filter will wait a short while attempting to acquire
+ * the semaphore. This wait is controlled by the "waitMs" init parameter and allows the expense of a suspend to be
+ * avoided if the semaphore is shortly available.  If the semaphore cannot be obtained, the request will be suspended
+ * for the default suspend period of the container or the valued set as the "suspendMs" init parameter.
+ * </p><p>
+ * If the "managedAttr" init parameter is set to true, then this servlet is set as a {@link ServletContext} attribute with the 
+ * filter name as the attribute name.  This allows context external mechanism (eg JMX via {@link ContextHandler#MANAGED_ATTRIBUTES}) to
+ * manage the configuration of the filter.
+ * </p>
+ * 
+ *
+ */
+public class QoSFilter implements Filter
+{
+    final static int __DEFAULT_MAX_PRIORITY=10;
+    final static int __DEFAULT_PASSES=10;
+    final static int __DEFAULT_WAIT_MS=50;
+    final static long __DEFAULT_TIMEOUT_MS = -1;
+    
+    final static String MANAGED_ATTR_INIT_PARAM="managedAttr";
+    final static String MAX_REQUESTS_INIT_PARAM="maxRequests";
+    final static String MAX_PRIORITY_INIT_PARAM="maxPriority";
+    final static String MAX_WAIT_INIT_PARAM="waitMs";
+    final static String SUSPEND_INIT_PARAM="suspendMs";
+    
+    ServletContext _context;
+
+    protected long _waitMs;
+    protected long _suspendMs;
+    protected int _maxRequests;
+    
+    private Semaphore _passes;
+    private Queue<Continuation>[] _queue;
+    private ContinuationListener[] _listener;
+    private String _suspended="QoSFilter@"+this.hashCode();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    public void init(FilterConfig filterConfig) 
+    {
+        _context=filterConfig.getServletContext();
+
+        int max_priority=__DEFAULT_MAX_PRIORITY;
+        if (filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM)!=null)
+            max_priority=Integer.parseInt(filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM));
+        _queue=new Queue[max_priority+1];
+        _listener = new ContinuationListener[max_priority + 1];
+        for (int p=0;p<_queue.length;p++)
+        {
+            _queue[p]=new ConcurrentLinkedQueue<Continuation>();
+
+            final int priority=p;
+            _listener[p] = new ContinuationListener()
+            {
+                public void onComplete(Continuation continuation)
+                {}
+
+                public void onTimeout(Continuation continuation)
+                {
+                    _queue[priority].remove(continuation);
+                }
+            };
+        }
+        
+        int maxRequests=__DEFAULT_PASSES;
+        if (filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)!=null)
+            maxRequests=Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM));
+        _passes=new Semaphore(maxRequests,true);
+        _maxRequests = maxRequests;
+        
+        long wait = __DEFAULT_WAIT_MS;
+        if (filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM)!=null)
+            wait=Integer.parseInt(filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM));
+        _waitMs=wait;
+        
+        long suspend = __DEFAULT_TIMEOUT_MS;
+        if (filterConfig.getInitParameter(SUSPEND_INIT_PARAM)!=null)
+            suspend=Integer.parseInt(filterConfig.getInitParameter(SUSPEND_INIT_PARAM));
+        _suspendMs=suspend;
+
+        if (_context!=null && Boolean.parseBoolean(filterConfig.getInitParameter(MANAGED_ATTR_INIT_PARAM)))
+            _context.setAttribute(filterConfig.getFilterName(),this);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+     */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
+    throws IOException, ServletException
+    {
+        boolean accepted=false;
+        try
+        {
+            if (request.getAttribute(_suspended)==null)
+            {
+                accepted=_passes.tryAcquire(_waitMs,TimeUnit.MILLISECONDS);
+                if (accepted)
+                {
+                    request.setAttribute(_suspended,Boolean.FALSE);
+                }
+                else
+                {
+                    request.setAttribute(_suspended,Boolean.TRUE);
+                    int priority = getPriority(request);
+                    Continuation continuation = ContinuationSupport.getContinuation(request);
+                    if (_suspendMs>0)
+                        continuation.setTimeout(_suspendMs);
+                    continuation.suspend();
+                    continuation.addContinuationListener(_listener[priority]);
+                    _queue[priority].add(continuation);
+                    return;
+                }
+            }
+            else
+            {
+                Boolean suspended=(Boolean)request.getAttribute(_suspended);
+                
+                if (suspended.booleanValue())
+                {
+                    request.setAttribute(_suspended,Boolean.FALSE);
+                    if (request.getAttribute("javax.servlet.resumed")==Boolean.TRUE)
+                    {
+                        _passes.acquire();
+                        accepted=true;
+                    }
+                    else 
+                    {
+                        // Timeout! try 1 more time.
+                        accepted = _passes.tryAcquire(_waitMs,TimeUnit.MILLISECONDS);
+                    }
+                }
+                else
+                {
+                    // pass through resume of previously accepted request
+                    _passes.acquire();
+                    accepted = true;
+                }
+            }
+
+            if (accepted)
+            {
+                chain.doFilter(request,response);
+            }
+            else
+            {
+                ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+            }
+        }
+        catch(InterruptedException e)
+        {
+            _context.log("QoS",e);
+            ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+        }
+        finally
+        {
+            if (accepted)
+            {
+                for (int p=_queue.length;p-->0;)
+                {
+                    Continuation continutaion=_queue[p].poll();
+                    if (continutaion!=null && continutaion.isSuspended())
+                    {
+                        continutaion.resume();
+                        break;
+                    }
+                }
+                _passes.release();
+            }
+        }
+    }
+
+    /** 
+     * Get the request Priority.
+     * <p> The default implementation assigns the following priorities:<ul>
+     * <li> 2 - for a authenticated request
+     * <li> 1 - for a request with valid /non new session 
+     * <li> 0 - for all other requests.
+     * </ul>
+     * This method may be specialised to provide application specific priorities.
+     * 
+     * @param request
+     * @return the request priority
+     */
+    protected int getPriority(ServletRequest request)
+    {
+        HttpServletRequest baseRequest = (HttpServletRequest)request;
+        if (baseRequest.getUserPrincipal() != null )
+            return 2;
+        else 
+        {
+            HttpSession session = baseRequest.getSession(false);
+            if (session!=null && !session.isNew()) 
+                return 1;
+            else
+                return 0;
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy(){}
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * Get the (short) amount of time (in milliseconds) that the filter would wait
+     * for the semaphore to become available before suspending a request.
+     * 
+     * @return wait time (in milliseconds)
+     */
+    public long getWaitMs()
+    {
+        return _waitMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the (short) amount of time (in milliseconds) that the filter would wait
+     * for the semaphore to become available before suspending a request.
+     * 
+     * @param value wait time (in milliseconds)
+     */
+    public void setWaitMs(long value)
+    {
+        _waitMs = value;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the amount of time (in milliseconds) that the filter would suspend
+     * a request for while waiting for the semaphore to become available.
+     * 
+     * @return suspend time (in milliseconds)
+     */
+    public long getSuspendMs()
+    {
+        return _suspendMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the amount of time (in milliseconds) that the filter would suspend
+     * a request for while waiting for the semaphore to become available.
+     * 
+     * @param value suspend time (in milliseconds)
+     */
+    public void setSuspendMs(long value)
+    {
+        _suspendMs = value;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the maximum number of requests allowed to be processed
+     * at the same time.
+     * 
+     * @return maximum number of requests
+     */
+    public int getMaxRequests()
+    {
+        return _maxRequests;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the maximum number of requests allowed to be processed
+     * at the same time.
+     * 
+     * @param value the number of requests
+     */
+    public void setMaxRequests(int value)
+    {
+        _passes = new Semaphore((value-_maxRequests+_passes.availablePermits()), true);
+        _maxRequests = value;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/servlets/UserAgentFilter.java b/src/java/org/eclipse/jetty/servlets/UserAgentFilter.java
new file mode 100644
index 0000000..3ab465e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/UserAgentFilter.java
@@ -0,0 +1,157 @@
+//
+//  ========================================================================
+//  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.servlets;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+/* ------------------------------------------------------------ */
+/** User Agent Filter.
+ * <p>
+ * This filter allows efficient matching of user agent strings for
+ * downstream or extended filters to use for browser specific logic.
+ * </p>
+ * <p>
+ * The filter is configured with the following init parameters:
+ * <dl>
+ * <dt>attribute</dt><dd>If set, then the request attribute of this name is set with the matched user agent string</dd>
+ * <dt>cacheSize</dt><dd>The size of the user-agent cache, used to avoid reparsing of user agent strings. The entire cache is flushed
+ * when this size is reached</dd>
+ * <dt>userAgent</dt><dd>A regex {@link Pattern} to extract the essential elements of the user agent.
+ * The concatenation of matched pattern groups is used as the user agent name</dd>
+ * <dl>
+ * An example value for pattern is <code>(?:Mozilla[^\(]*\(compatible;\s*+([^;]*);.*)|(?:.*?([^\s]+/[^\s]+).*)</code>. These two
+ * pattern match the common compatibility user-agent strings and extract the real user agent, failing that, the first
+ * element of the agent string is returned.
+ *
+ *
+ */
+public class UserAgentFilter implements Filter
+{
+    private static final String __defaultPattern = "(?:Mozilla[^\\(]*\\(compatible;\\s*+([^;]*);.*)|(?:.*?([^\\s]+/[^\\s]+).*)";
+    private Pattern _pattern = Pattern.compile(__defaultPattern);
+    private Map<String, String> _agentCache = new ConcurrentHashMap<String, String>();
+    private int _agentCacheSize=1024;
+    private String _attribute;
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+     */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
+    {
+        if (_attribute!=null && _pattern!=null)
+        {
+            String ua=getUserAgent(request);
+            request.setAttribute(_attribute,ua);
+        }
+        chain.doFilter(request,response);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        _attribute=filterConfig.getInitParameter("attribute");
+
+        String p=filterConfig.getInitParameter("userAgent");
+        if (p!=null)
+            _pattern=Pattern.compile(p);
+
+        String size=filterConfig.getInitParameter("cacheSize");
+        if (size!=null)
+            _agentCacheSize=Integer.parseInt(size);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getUserAgent(ServletRequest request)
+    {
+        String ua=((HttpServletRequest)request).getHeader("User-Agent");
+        return getUserAgent(ua);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get UserAgent.
+     * The configured agent patterns are used to match against the passed user agent string.
+     * If any patterns match, the concatenation of pattern groups is returned as the user agent
+     * string. Match results are cached.
+     * @param ua A user agent string
+     * @return The matched pattern groups or the original user agent string
+     */
+    public String getUserAgent(String ua)
+    {
+        if (ua == null)
+            return null;
+
+        String tag = _agentCache.get(ua);
+
+        if (tag == null)
+        {
+            if (_pattern != null)
+            {
+                Matcher matcher = _pattern.matcher(ua);
+                if (matcher.matches())
+                {
+                    if (matcher.groupCount() > 0)
+                    {
+                        for (int g = 1; g <= matcher.groupCount(); g++)
+                        {
+                            String group = matcher.group(g);
+                            if (group != null)
+                                tag = tag == null ? group : tag + group;
+                        }
+                    }
+                    else
+                    {
+                        tag = matcher.group();
+                    }
+                }
+            }
+
+            if (tag == null)
+                tag = ua;
+
+            if (_agentCache.size() >= _agentCacheSize)
+                _agentCache.clear();
+            _agentCache.put(ua, tag);
+        }
+
+        return tag;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/servlets/WelcomeFilter.java b/src/java/org/eclipse/jetty/servlets/WelcomeFilter.java
new file mode 100644
index 0000000..7d9a3b3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/servlets/WelcomeFilter.java
@@ -0,0 +1,70 @@
+//
+//  ========================================================================
+//  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.servlets;
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+/* ------------------------------------------------------------ */
+/** Welcome Filter
+ * This filter can be used to server an index file for a directory 
+ * when no index file actually exists (thus the web.xml mechanism does
+ * not work).
+ * 
+ * This filter will dispatch requests to a directory (URLs ending with /)
+ * to the welcome URL determined by the "welcome" init parameter.  So if
+ * the filter "welcome" init parameter is set to "index.do" then a request
+ * to "/some/directory/" will be dispatched to "/some/directory/index.do" and
+ * will be handled by any servlets mapped to that URL.
+ *
+ * Requests to "/some/directory" will be redirected to "/some/directory/".
+ */
+public  class WelcomeFilter implements Filter
+{
+    private String welcome;
+    
+    public void init(FilterConfig filterConfig)
+    {
+        welcome=filterConfig.getInitParameter("welcome");
+	if (welcome==null)
+	    welcome="index.html";
+    }
+
+    /* ------------------------------------------------------------ */
+    public void doFilter(ServletRequest request,
+                         ServletResponse response,
+                         FilterChain chain)
+	throws IOException, ServletException
+    {
+        String path=((HttpServletRequest)request).getServletPath();
+        if (welcome!=null && path.endsWith("/"))
+            request.getRequestDispatcher(path+welcome).forward(request,response);
+        else
+            chain.doFilter(request, response);
+    }
+
+    public void destroy() {}
+}
+
diff --git a/src/java/org/eclipse/jetty/util/ArrayQueue.java b/src/java/org/eclipse/jetty/util/ArrayQueue.java
new file mode 100644
index 0000000..7554169
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ArrayQueue.java
@@ -0,0 +1,379 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.AbstractList;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+/* ------------------------------------------------------------ */
+/**
+ * Queue backed by circular array.
+ * <p/>
+ * This partial Queue implementation (also with {@link #remove()} for stack operation)
+ * is backed by a growable circular array.
+ *
+ * @param <E>
+ */
+public class ArrayQueue<E> extends AbstractList<E> implements Queue<E>
+{
+    public static final int DEFAULT_CAPACITY = 64;
+    public static final int DEFAULT_GROWTH = 32;
+
+    protected final Object _lock;
+    protected final int _growCapacity;
+    protected Object[] _elements;
+    protected int _nextE;
+    protected int _nextSlot;
+    protected int _size;
+
+    /* ------------------------------------------------------------ */
+    public ArrayQueue()
+    {
+        this(DEFAULT_CAPACITY, -1);
+    }
+
+    /* ------------------------------------------------------------ */
+    public ArrayQueue(int capacity)
+    {
+        this(capacity, -1);
+    }
+
+    /* ------------------------------------------------------------ */
+    public ArrayQueue(int initCapacity, int growBy)
+    {
+        this(initCapacity, growBy, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public ArrayQueue(int initCapacity, int growBy, Object lock)
+    {
+        _lock = lock == null ? this : lock;
+        _growCapacity = growBy;
+        _elements = new Object[initCapacity];
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getCapacity()
+    {
+        synchronized (_lock)
+        {
+            return _elements.length;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean add(E e)
+    {
+        if (!offer(e))
+            throw new IllegalStateException("Full");
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean offer(E e)
+    {
+        synchronized (_lock)
+        {
+            return enqueue(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean enqueue(E e)
+    {
+        if (_size == _elements.length && !grow())
+            return false;
+
+        _size++;
+        _elements[_nextSlot++] = e;
+        if (_nextSlot == _elements.length)
+            _nextSlot = 0;
+
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add without synchronization or bounds checking
+     *
+     * @param e the element to add
+     * @see #add(Object)
+     */
+    public void addUnsafe(E e)
+    {
+        if (!enqueue(e))
+            throw new IllegalStateException("Full");
+    }
+
+    /* ------------------------------------------------------------ */
+    public E element()
+    {
+        synchronized (_lock)
+        {
+            if (isEmpty())
+                throw new NoSuchElementException();
+            return at(_nextE);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private E at(int index)
+    {
+        return (E)_elements[index];
+    }
+
+    /* ------------------------------------------------------------ */
+    public E peek()
+    {
+        synchronized (_lock)
+        {
+            if (isEmpty())
+                return null;
+            return at(_nextE);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public E poll()
+    {
+        synchronized (_lock)
+        {
+            if (_size == 0)
+                return null;
+            return dequeue();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private E dequeue()
+    {
+        E e = at(_nextE);
+        _elements[_nextE] = null;
+        _size--;
+        if (++_nextE == _elements.length)
+            _nextE = 0;
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    public E remove()
+    {
+        synchronized (_lock)
+        {
+            if (_size == 0)
+                throw new NoSuchElementException();
+            return dequeue();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void clear()
+    {
+        synchronized (_lock)
+        {
+            _size = 0;
+            _nextE = 0;
+            _nextSlot = 0;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isEmpty()
+    {
+        synchronized (_lock)
+        {
+            return _size == 0;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int size()
+    {
+        synchronized (_lock)
+        {
+            return _size;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public E get(int index)
+    {
+        synchronized (_lock)
+        {
+            if (index < 0 || index >= _size)
+                throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")");
+            return getUnsafe(index);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get without synchronization or bounds checking.
+     *
+     * @param  index index of the element to return
+     * @return the element at the specified index
+     * @see #get(int)
+     */
+    public E getUnsafe(int index)
+    {
+        int i = (_nextE + index) % _elements.length;
+        return at(i);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public E remove(int index)
+    {
+        synchronized (_lock)
+        {
+            if (index < 0 || index >= _size)
+                throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")");
+
+            int i = (_nextE + index) % _elements.length;
+            E old = at(i);
+
+            if (i < _nextSlot)
+            {
+                // 0                         _elements.length
+                //       _nextE........._nextSlot
+                System.arraycopy(_elements, i + 1, _elements, i, _nextSlot - i);
+                _nextSlot--;
+                _size--;
+            }
+            else
+            {
+                // 0                         _elements.length
+                // ......_nextSlot   _nextE..........
+                System.arraycopy(_elements, i + 1, _elements, i, _elements.length - i - 1);
+                if (_nextSlot > 0)
+                {
+                    _elements[_elements.length - 1] = _elements[0];
+                    System.arraycopy(_elements, 1, _elements, 0, _nextSlot - 1);
+                    _nextSlot--;
+                }
+                else
+                    _nextSlot = _elements.length - 1;
+
+                _size--;
+            }
+
+            return old;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public E set(int index, E element)
+    {
+        synchronized (_lock)
+        {
+            if (index < 0 || index >= _size)
+                throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")");
+
+            int i = _nextE + index;
+            if (i >= _elements.length)
+                i -= _elements.length;
+            E old = at(i);
+            _elements[i] = element;
+            return old;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void add(int index, E element)
+    {
+        synchronized (_lock)
+        {
+            if (index < 0 || index > _size)
+                throw new IndexOutOfBoundsException("!(" + 0 + "<" + index + "<=" + _size + ")");
+
+            if (_size == _elements.length && !grow())
+                throw new IllegalStateException("Full");
+
+            if (index == _size)
+            {
+                add(element);
+            }
+            else
+            {
+                int i = _nextE + index;
+                if (i >= _elements.length)
+                    i -= _elements.length;
+
+                _size++;
+                _nextSlot++;
+                if (_nextSlot == _elements.length)
+                    _nextSlot = 0;
+
+                if (i < _nextSlot)
+                {
+                    // 0                         _elements.length
+                    //       _nextE.....i..._nextSlot
+                    // 0                         _elements.length
+                    // ..i..._nextSlot   _nextE..........
+                    System.arraycopy(_elements, i, _elements, i + 1, _nextSlot - i);
+                    _elements[i] = element;
+                }
+                else
+                {
+                    // 0                         _elements.length
+                    // ......_nextSlot   _nextE.....i....
+                    if (_nextSlot > 0)
+                    {
+                        System.arraycopy(_elements, 0, _elements, 1, _nextSlot);
+                        _elements[0] = _elements[_elements.length - 1];
+                    }
+
+                    System.arraycopy(_elements, i, _elements, i + 1, _elements.length - i - 1);
+                    _elements[i] = element;
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    protected boolean grow()
+    {
+        synchronized (_lock)
+        {
+            if (_growCapacity <= 0)
+                return false;
+
+            Object[] elements = new Object[_elements.length + _growCapacity];
+
+            int split = _elements.length - _nextE;
+            if (split > 0)
+                System.arraycopy(_elements, _nextE, elements, 0, split);
+            if (_nextE != 0)
+                System.arraycopy(_elements, 0, elements, split, _nextSlot);
+
+            _elements = elements;
+            _nextE = 0;
+            _nextSlot = _size;
+            return true;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Atomics.java b/src/java/org/eclipse/jetty/util/Atomics.java
new file mode 100644
index 0000000..42fb489
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Atomics.java
@@ -0,0 +1,73 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class Atomics
+{
+    private Atomics()
+    {
+    }
+
+    public static void updateMin(AtomicLong currentMin, long newValue)
+    {
+        long oldValue = currentMin.get();
+        while (newValue < oldValue)
+        {
+            if (currentMin.compareAndSet(oldValue, newValue))
+                break;
+            oldValue = currentMin.get();
+        }
+    }
+
+    public static void updateMax(AtomicLong currentMax, long newValue)
+    {
+        long oldValue = currentMax.get();
+        while (newValue > oldValue)
+        {
+            if (currentMax.compareAndSet(oldValue, newValue))
+                break;
+            oldValue = currentMax.get();
+        }
+    }
+
+    public static void updateMin(AtomicInteger currentMin, int newValue)
+    {
+        int oldValue = currentMin.get();
+        while (newValue < oldValue)
+        {
+            if (currentMin.compareAndSet(oldValue, newValue))
+                break;
+            oldValue = currentMin.get();
+        }
+    }
+
+    public static void updateMax(AtomicInteger currentMax, int newValue)
+    {
+        int oldValue = currentMax.get();
+        while (newValue > oldValue)
+        {
+            if (currentMax.compareAndSet(oldValue, newValue))
+                break;
+            oldValue = currentMax.get();
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Attributes.java b/src/java/org/eclipse/jetty/util/Attributes.java
new file mode 100644
index 0000000..c65abc2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Attributes.java
@@ -0,0 +1,36 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.Enumeration;
+
+/* ------------------------------------------------------------ */
+/** Attributes.
+ * Interface commonly used for storing attributes.
+ * 
+ *
+ */
+public interface Attributes
+{
+    public void removeAttribute(String name);
+    public void setAttribute(String name, Object attribute);
+    public Object getAttribute(String name);
+    public Enumeration<String> getAttributeNames();
+    public void clearAttributes();
+}
diff --git a/src/java/org/eclipse/jetty/util/AttributesMap.java b/src/java/org/eclipse/jetty/util/AttributesMap.java
new file mode 100644
index 0000000..e3b55af
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/AttributesMap.java
@@ -0,0 +1,163 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/* ------------------------------------------------------------ */
+/** AttributesMap.
+ * 
+ *
+ */
+public class AttributesMap implements Attributes
+{
+    protected final Map<String,Object> _map;
+
+    /* ------------------------------------------------------------ */
+    public AttributesMap()
+    {
+        _map=new HashMap<String,Object>();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public AttributesMap(Map<String,Object> map)
+    {
+        _map=map;
+    }
+
+    /* ------------------------------------------------------------ */
+    public AttributesMap(AttributesMap map)
+    {
+        _map=new HashMap<String,Object>(map._map);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name)
+    {
+        _map.remove(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object attribute)
+    {
+        if (attribute==null)
+            _map.remove(name);
+        else
+            _map.put(name, attribute);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name)
+    {
+        return _map.get(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#getAttributeNames()
+     */
+    public Enumeration<String> getAttributeNames()
+    {
+        return Collections.enumeration(_map.keySet());
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#getAttributeNames()
+     */
+    public Set<String> getAttributeNameSet()
+    {
+        return _map.keySet();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Set<Map.Entry<String, Object>> getAttributeEntrySet()
+    {
+        return _map.entrySet();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#getAttributeNames()
+     */
+    public static Enumeration<String> getAttributeNamesCopy(Attributes attrs)
+    {
+        if (attrs instanceof AttributesMap)
+            return Collections.enumeration(((AttributesMap)attrs)._map.keySet());
+        
+        List<String> names = new ArrayList<String>();
+        names.addAll(Collections.list(attrs.getAttributeNames()));
+        return Collections.enumeration(names);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* 
+     * @see org.eclipse.jetty.util.Attributes#clear()
+     */
+    public void clearAttributes()
+    {
+        _map.clear();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int size()
+    {
+        return _map.size();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return _map.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Set<String> keySet()
+    {
+        return _map.keySet();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void addAll(Attributes attributes)
+    {
+        Enumeration<String> e = attributes.getAttributeNames();
+        while (e.hasMoreElements())
+        {
+            String name=e.nextElement();
+            setAttribute(name,attributes.getAttribute(name));
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/B64Code.java b/src/java/org/eclipse/jetty/util/B64Code.java
new file mode 100644
index 0000000..684c008
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/B64Code.java
@@ -0,0 +1,450 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+
+/* ------------------------------------------------------------ */
+/** Fast B64 Encoder/Decoder as described in RFC 1421.
+ * <p>Does not insert or interpret whitespace as described in RFC
+ * 1521. If you require this you must pre/post process your data.
+ * <p> Note that in a web context the usual case is to not want
+ * linebreaks or other white space in the encoded output.
+ * 
+ */
+public class B64Code
+{
+    // ------------------------------------------------------------------
+    static final char __pad='=';
+    static final char[] __rfc1421alphabet=
+            {
+                'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
+                'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
+                'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
+                'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
+            };
+
+    static final byte[] __rfc1421nibbles;
+
+    static
+    {
+        __rfc1421nibbles=new byte[256];
+        for (int i=0;i<256;i++)
+            __rfc1421nibbles[i]=-1;
+        for (byte b=0;b<64;b++)
+            __rfc1421nibbles[(byte)__rfc1421alphabet[b]]=b;
+        __rfc1421nibbles[(byte)__pad]=0;
+    }
+
+    // ------------------------------------------------------------------
+    /**
+     * Base 64 encode as described in RFC 1421.
+     * <p>Does not insert whitespace as described in RFC 1521.
+     * @param s String to encode.
+     * @return String containing the encoded form of the input.
+     */
+    static public String encode(String s)
+    {
+        try
+        {
+            return encode(s,null);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new IllegalArgumentException(e.toString());
+        }
+    }
+
+    // ------------------------------------------------------------------
+    /**
+     * Base 64 encode as described in RFC 1421.
+     * <p>Does not insert whitespace as described in RFC 1521.
+     * @param s String to encode.
+     * @param charEncoding String representing the name of
+     *        the character encoding of the provided input String.
+     * @return String containing the encoded form of the input.
+     */
+    static public String encode(String s,String charEncoding)
+            throws UnsupportedEncodingException
+    {
+        byte[] bytes;
+        if (charEncoding==null)
+            bytes=s.getBytes(StringUtil.__ISO_8859_1);
+        else
+            bytes=s.getBytes(charEncoding);
+
+        return new String(encode(bytes));
+    }
+    
+    // ------------------------------------------------------------------
+    /**
+     * Fast Base 64 encode as described in RFC 1421.
+     * <p>Does not insert whitespace as described in RFC 1521.
+     * <p> Avoids creating extra copies of the input/output.
+     * @param b byte array to encode.
+     * @return char array containing the encoded form of the input.
+     */
+    static public char[] encode(byte[] b)
+    {
+        if (b==null)
+            return null;
+
+        int bLen=b.length;
+        int cLen=((bLen+2)/3)*4;
+        char c[]=new char[cLen];
+        int ci=0;
+        int bi=0;
+        byte b0, b1, b2;
+        int stop=(bLen/3)*3;
+        while (bi<stop)
+        {
+            b0=b[bi++];
+            b1=b[bi++];
+            b2=b[bi++];
+            c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+            c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
+            c[ci++]=__rfc1421alphabet[(b1<<2)&0x3f|(b2>>>6)&0x03];
+            c[ci++]=__rfc1421alphabet[b2&077];
+        }
+
+        if (bLen!=bi)
+        {
+            switch (bLen%3)
+            {
+                case 2:
+                    b0=b[bi++];
+                    b1=b[bi++];
+                    c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+                    c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
+                    c[ci++]=__rfc1421alphabet[(b1<<2)&0x3f];
+                    c[ci++]=__pad;
+                    break;
+
+                case 1:
+                    b0=b[bi++];
+                    c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+                    c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f];
+                    c[ci++]=__pad;
+                    c[ci++]=__pad;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        return c;
+    }
+    
+    // ------------------------------------------------------------------
+    /**
+     * Fast Base 64 encode as described in RFC 1421 and RFC2045
+     * <p>Does not insert whitespace as described in RFC 1521, unless rfc2045 is passed as true.
+     * <p> Avoids creating extra copies of the input/output.
+     * @param b byte array to encode.
+     * @param rfc2045 If true, break lines at 76 characters with CRLF
+     * @return char array containing the encoded form of the input.
+     */
+    static public char[] encode(byte[] b, boolean rfc2045)
+    {
+        if (b==null)
+            return null;
+        if (!rfc2045)
+            return encode(b);
+
+        int bLen=b.length;
+        int cLen=((bLen+2)/3)*4;
+        cLen+=2+2*(cLen/76);
+        char c[]=new char[cLen];
+        int ci=0;
+        int bi=0;
+        byte b0, b1, b2;
+        int stop=(bLen/3)*3;
+        int l=0;
+        while (bi<stop)
+        {
+            b0=b[bi++];
+            b1=b[bi++];
+            b2=b[bi++];
+            c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+            c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
+            c[ci++]=__rfc1421alphabet[(b1<<2)&0x3f|(b2>>>6)&0x03];
+            c[ci++]=__rfc1421alphabet[b2&077];
+            l+=4;
+            if (l%76==0)
+            {
+                c[ci++]=13;
+                c[ci++]=10;
+            }
+        }
+
+        if (bLen!=bi)
+        {
+            switch (bLen%3)
+            {
+                case 2:
+                    b0=b[bi++];
+                    b1=b[bi++];
+                    c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+                    c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f|(b1>>>4)&0x0f];
+                    c[ci++]=__rfc1421alphabet[(b1<<2)&0x3f];
+                    c[ci++]=__pad;
+                    break;
+
+                case 1:
+                    b0=b[bi++];
+                    c[ci++]=__rfc1421alphabet[(b0>>>2)&0x3f];
+                    c[ci++]=__rfc1421alphabet[(b0<<4)&0x3f];
+                    c[ci++]=__pad;
+                    c[ci++]=__pad;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        c[ci++]=13;
+        c[ci++]=10;
+        return c;
+    }
+
+    // ------------------------------------------------------------------
+    /**
+     * Base 64 decode as described in RFC 2045.
+     * <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
+     * @param encoded String to decode.
+     * @param charEncoding String representing the character encoding
+     *        used to map the decoded bytes into a String.
+     * @return String decoded byte array.
+     * @throws UnsupportedEncodingException if the encoding is not supported
+     * @throws IllegalArgumentException if the input is not a valid
+     *         B64 encoding.
+     */
+    static public String decode(String encoded,String charEncoding)
+            throws UnsupportedEncodingException
+    {
+        byte[] decoded=decode(encoded);
+        if (charEncoding==null)
+            return new String(decoded);
+        return new String(decoded,charEncoding);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Fast Base 64 decode as described in RFC 1421.
+     * 
+     * <p>Unlike other decode methods, this does not attempt to 
+     * cope with extra whitespace as described in RFC 1521/2045.
+     * <p> Avoids creating extra copies of the input/output.
+     * <p> Note this code has been flattened for performance.
+     * @param b char array to decode.
+     * @return byte array containing the decoded form of the input.
+     * @throws IllegalArgumentException if the input is not a valid
+     *         B64 encoding.
+     */
+    static public byte[] decode(char[] b)
+    {
+        if (b==null)
+            return null;
+
+        int bLen=b.length;
+        if (bLen%4!=0)
+            throw new IllegalArgumentException("Input block size is not 4");
+
+        int li=bLen-1;
+        while (li>=0 && b[li]==(byte)__pad)
+            li--;
+
+        if (li<0)
+            return new byte[0];
+
+        // Create result array of exact required size.
+        int rLen=((li+1)*3)/4;
+        byte r[]=new byte[rLen];
+        int ri=0;
+        int bi=0;
+        int stop=(rLen/3)*3;
+        byte b0,b1,b2,b3;
+        try
+        {
+            while (ri<stop)
+            {
+                b0=__rfc1421nibbles[b[bi++]];
+                b1=__rfc1421nibbles[b[bi++]];
+                b2=__rfc1421nibbles[b[bi++]];
+                b3=__rfc1421nibbles[b[bi++]];
+                if (b0<0 || b1<0 || b2<0 || b3<0)
+                    throw new IllegalArgumentException("Not B64 encoded");
+
+                r[ri++]=(byte)(b0<<2|b1>>>4);
+                r[ri++]=(byte)(b1<<4|b2>>>2);
+                r[ri++]=(byte)(b2<<6|b3);
+            }
+
+            if (rLen!=ri)
+            {
+                switch (rLen%3)
+                {
+                    case 2:
+                        b0=__rfc1421nibbles[b[bi++]];
+                        b1=__rfc1421nibbles[b[bi++]];
+                        b2=__rfc1421nibbles[b[bi++]];
+                        if (b0<0 || b1<0 || b2<0)
+                            throw new IllegalArgumentException("Not B64 encoded");
+                        r[ri++]=(byte)(b0<<2|b1>>>4);
+                        r[ri++]=(byte)(b1<<4|b2>>>2);
+                        break;
+
+                    case 1:
+                        b0=__rfc1421nibbles[b[bi++]];
+                        b1=__rfc1421nibbles[b[bi++]];
+                        if (b0<0 || b1<0)
+                            throw new IllegalArgumentException("Not B64 encoded");
+                        r[ri++]=(byte)(b0<<2|b1>>>4);
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+        }
+        catch (IndexOutOfBoundsException e)
+        {
+            throw new IllegalArgumentException("char "+bi
+                    +" was not B64 encoded");
+        }
+
+        return r;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Base 64 decode as described in RFC 2045.
+     * <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
+     * @param encoded String to decode.
+     * @return byte array containing the decoded form of the input.
+     * @throws IllegalArgumentException if the input is not a valid
+     *         B64 encoding.
+     */
+    static public byte[] decode(String encoded)
+    {
+        if (encoded==null)
+            return null;
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(4*encoded.length()/3);        
+        decode(encoded, bout);
+        return bout.toByteArray();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Base 64 decode as described in RFC 2045.
+     * <p>Unlike {@link #decode(char[])}, extra whitespace is ignored.
+     * @param encoded String to decode.
+     * @param output stream for decoded bytes
+     * @return byte array containing the decoded form of the input.
+     * @throws IllegalArgumentException if the input is not a valid
+     *         B64 encoding.
+     */
+    static public void decode (String encoded, ByteArrayOutputStream bout)
+    {
+        if (encoded==null)
+            return;
+        
+        if (bout == null)
+            throw new IllegalArgumentException("No outputstream for decoded bytes");
+        
+        int ci=0;
+        byte nibbles[] = new byte[4];
+        int s=0;
+  
+        while (ci<encoded.length())
+        {
+            char c=encoded.charAt(ci++);
+
+            if (c==__pad)
+                break;
+            
+            if (Character.isWhitespace(c))
+                continue;
+
+            byte nibble=__rfc1421nibbles[c];
+            if (nibble<0)
+                throw new IllegalArgumentException("Not B64 encoded");
+
+            nibbles[s++]=__rfc1421nibbles[c];
+
+            switch(s)
+            {
+                case 1:
+                    break;
+                case 2:
+                    bout.write(nibbles[0]<<2|nibbles[1]>>>4);
+                    break;
+                case 3:
+                    bout.write(nibbles[1]<<4|nibbles[2]>>>2);
+                    break;
+                case 4:
+                    bout.write(nibbles[2]<<6|nibbles[3]);
+                    s=0;
+                    break;
+            }
+
+        }
+
+        return;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public static void encode(int value,Appendable buf) throws IOException
+    {
+        buf.append(__rfc1421alphabet[0x3f&((0xFC000000&value)>>26)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x03F00000&value)>>20)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x000FC000&value)>>14)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x00003F00&value)>>8)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x000000FC&value)>>2)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x00000003&value)<<4)]);
+        buf.append('=');
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static void encode(long lvalue,Appendable buf) throws IOException
+    {
+        int value=(int)(0xFFFFFFFC&(lvalue>>32));
+        buf.append(__rfc1421alphabet[0x3f&((0xFC000000&value)>>26)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x03F00000&value)>>20)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x000FC000&value)>>14)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x00003F00&value)>>8)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x000000FC&value)>>2)]);
+        
+        buf.append(__rfc1421alphabet[0x3f&((0x00000003&value)<<4) + (0xf&(int)(lvalue>>28))]);
+        
+        value=0x0FFFFFFF&(int)lvalue;
+        buf.append(__rfc1421alphabet[0x3f&((0x0FC00000&value)>>22)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x003F0000&value)>>16)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x0000FC00&value)>>10)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x000003F0&value)>>4)]);
+        buf.append(__rfc1421alphabet[0x3f&((0x0000000F&value)<<2)]);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/BlockingArrayQueue.java b/src/java/org/eclipse/jetty/util/BlockingArrayQueue.java
new file mode 100644
index 0000000..80e3c6b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/BlockingArrayQueue.java
@@ -0,0 +1,704 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+
+/* ------------------------------------------------------------ */
+/** Queue backed by a circular array.
+ * 
+ * This queue is uses  a variant of the two lock queue algorithm to
+ * provide an efficient queue or list backed by a growable circular
+ * array.  This queue also has a partial implementation of 
+ * {@link java.util.concurrent.BlockingQueue}, specifically the {@link #take()} and 
+ * {@link #poll(long, TimeUnit)} methods.  
+ * Unlike {@link java.util.concurrent.ArrayBlockingQueue}, this class is
+ * able to grow and provides a blocking put call.
+ * <p>
+ * The queue has both a capacity (the size of the array currently allocated)
+ * and a limit (the maximum size that may be allocated), which defaults to 
+ * {@link Integer#MAX_VALUE}.
+ * 
+ * @param <E> The element type
+ */
+public class BlockingArrayQueue<E> extends AbstractList<E> implements BlockingQueue<E>
+{
+    public final int DEFAULT_CAPACITY=128;
+    public final int DEFAULT_GROWTH=64;
+    private final int _limit;
+    private final AtomicInteger _size=new AtomicInteger();
+    private final int _growCapacity;
+    
+    private volatile int _capacity;
+    private Object[] _elements;
+    
+    private final ReentrantLock _headLock = new ReentrantLock();
+    private final Condition _notEmpty = _headLock.newCondition();
+    private int _head;
+
+    // spacers created to prevent false sharing between head and tail http://en.wikipedia.org/wiki/False_sharing
+    // TODO verify this has benefits
+    private long _space0;
+    private long _space1;
+    private long _space2;
+    private long _space3;
+    private long _space4;
+    private long _space5;
+    private long _space6;
+    private long _space7;
+    
+    private final ReentrantLock _tailLock = new ReentrantLock();
+    private int _tail;
+    
+
+    /* ------------------------------------------------------------ */
+    /** Create a growing partially blocking Queue
+     * 
+     */
+    public BlockingArrayQueue()
+    {
+        _elements=new Object[DEFAULT_CAPACITY];
+        _growCapacity=DEFAULT_GROWTH;
+        _capacity=_elements.length;
+        _limit=Integer.MAX_VALUE;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Create a fixed size partially blocking Queue
+     * @param limit The initial capacity and the limit.
+     */
+    public BlockingArrayQueue(int limit)
+    {
+        _elements=new Object[limit];
+        _capacity=_elements.length;
+        _growCapacity=-1;
+        _limit=limit;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Create a growing partially blocking Queue.
+     * @param capacity Initial capacity
+     * @param growBy Incremental capacity.
+     */
+    public BlockingArrayQueue(int capacity,int growBy)
+    {
+        _elements=new Object[capacity];
+        _capacity=_elements.length;
+        _growCapacity=growBy;
+        _limit=Integer.MAX_VALUE;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Create a growing limited partially blocking Queue.
+     * @param capacity Initial capacity
+     * @param growBy Incremental capacity.
+     * @param limit maximum capacity.
+     */
+    public BlockingArrayQueue(int capacity,int growBy,int limit)
+    {
+        if (capacity>limit)
+            throw new IllegalArgumentException();
+        
+        _elements=new Object[capacity];
+        _capacity=_elements.length;
+        _growCapacity=growBy;
+        _limit=limit;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getCapacity()
+    {
+        return _capacity;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getLimit()
+    {
+        return _limit;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean add(E e)
+    {
+        return offer(e);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public E element()
+    {
+        E e = peek();
+        if (e==null)
+            throw new NoSuchElementException();
+        return e;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    public E peek()
+    {
+        if (_size.get() == 0)
+            return null;
+        
+        E e = null;
+        _headLock.lock(); // Size cannot shrink
+        try 
+        {
+            if (_size.get() > 0) 
+                e = (E)_elements[_head];
+        } 
+        finally 
+        {
+            _headLock.unlock();
+        }
+        
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean offer(E e)
+    {
+        if (e == null) 
+            throw new NullPointerException();
+        
+        boolean not_empty=false;
+        _tailLock.lock();  // size cannot grow... only shrink
+        try 
+        {
+            if (_size.get() >= _limit) 
+                return false;
+            
+            // should we expand array?
+            if (_size.get()==_capacity)
+            {
+                _headLock.lock();   // Need to grow array
+                try
+                {
+                    if (!grow())
+                        return false;
+                }
+                finally
+                {
+                    _headLock.unlock();
+                }
+            }
+
+            // add the element
+            _elements[_tail]=e;
+            _tail=(_tail+1)%_capacity;
+
+            not_empty=0==_size.getAndIncrement();
+            
+        } 
+        finally 
+        {
+            _tailLock.unlock();
+        }
+        
+        if (not_empty)
+        {
+            _headLock.lock();
+            try
+            {
+                _notEmpty.signal();
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }  
+
+        return true;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    public E poll()
+    {
+        if (_size.get() == 0)
+            return null;
+        
+        E e = null;
+        _headLock.lock(); // Size cannot shrink
+        try 
+        {
+            if (_size.get() > 0) 
+            {
+                final int head=_head;
+                e = (E)_elements[head];
+                _elements[head]=null;
+                _head=(head+1)%_capacity;
+                
+                if (_size.decrementAndGet()>0)
+                    _notEmpty.signal();
+            }
+        } 
+        finally 
+        {
+            _headLock.unlock();
+        }
+        
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieves and removes the head of this queue, waiting
+     * if no elements are present on this queue.
+     * @return the head of this queue
+     * @throws InterruptedException if interrupted while waiting.
+     */
+    @SuppressWarnings("unchecked")
+    public E take() throws InterruptedException
+    {
+        E e = null;
+        _headLock.lockInterruptibly();  // Size cannot shrink
+        try 
+        {
+            try 
+            {
+                while (_size.get() == 0)
+                {
+                    _notEmpty.await();
+                }
+            } 
+            catch (InterruptedException ie) 
+            {
+                _notEmpty.signal();
+                throw ie;
+            }
+
+            final int head=_head;
+            e = (E)_elements[head];
+            _elements[head]=null;
+            _head=(head+1)%_capacity;
+
+            if (_size.decrementAndGet()>0)
+                _notEmpty.signal();
+        } 
+        finally 
+        {
+            _headLock.unlock();
+        }
+        
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieves and removes the head of this queue, waiting
+     * if necessary up to the specified wait time if no elements are
+     * present on this queue.
+     * @param time how long to wait before giving up, in units of
+     * <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     * <tt>timeout</tt> parameter
+     * @return the head of this queue, or <tt>null</tt> if the
+     * specified waiting time elapses before an element is present.
+     * @throws InterruptedException if interrupted while waiting.
+     */
+    @SuppressWarnings("unchecked")
+    public E poll(long time, TimeUnit unit) throws InterruptedException
+    {
+        
+        E e = null;
+
+        long nanos = unit.toNanos(time);
+        
+        _headLock.lockInterruptibly(); // Size cannot shrink
+        try 
+        {    
+            try 
+            {
+                while (_size.get() == 0)
+                {
+                    if (nanos<=0)
+                        return null;
+                    nanos = _notEmpty.awaitNanos(nanos);
+                }
+            } 
+            catch (InterruptedException ie) 
+            {
+                _notEmpty.signal();
+                throw ie;
+            }
+
+            e = (E)_elements[_head];
+            _elements[_head]=null;
+            _head=(_head+1)%_capacity;
+
+            if (_size.decrementAndGet()>0)
+                _notEmpty.signal();
+        } 
+        finally 
+        {
+            _headLock.unlock();
+        }
+        
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    public E remove()
+    {
+        E e=poll();
+        if (e==null)
+            throw new NoSuchElementException();
+        return e;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void clear()
+    {
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+                _head=0;
+                _tail=0;
+                _size.set(0);
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isEmpty()
+    {
+        return _size.get()==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int size()
+    {
+        return _size.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    @Override
+    public E get(int index)
+    {
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+                if (index<0 || index>=_size.get())
+                    throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
+                int i = _head+index;
+                if (i>=_capacity)
+                    i-=_capacity;
+                return (E)_elements[i];
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public E remove(int index)
+    {
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+
+                if (index<0 || index>=_size.get())
+                    throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
+
+                int i = _head+index;
+                if (i>=_capacity)
+                    i-=_capacity;
+                @SuppressWarnings("unchecked")
+                E old=(E)_elements[i];
+
+                if (i<_tail)
+                {
+                    System.arraycopy(_elements,i+1,_elements,i,_tail-i);
+                    _tail--;
+                    _size.decrementAndGet();
+                }
+                else
+                {
+                    System.arraycopy(_elements,i+1,_elements,i,_capacity-i-1);
+                    if (_tail>0)
+                    {
+                        _elements[_capacity]=_elements[0];
+                        System.arraycopy(_elements,1,_elements,0,_tail-1);
+                        _tail--;
+                    }
+                    else
+                        _tail=_capacity-1;
+
+                    _size.decrementAndGet();
+                }
+
+                return old;
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public E set(int index, E e)
+    {
+        if (e == null) 
+            throw new NullPointerException();
+
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+
+                if (index<0 || index>=_size.get())
+                    throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
+
+                int i = _head+index;
+                if (i>=_capacity)
+                    i-=_capacity;
+                @SuppressWarnings("unchecked")
+                E old=(E)_elements[i];
+                _elements[i]=e;
+                return old;
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void add(int index, E e)
+    {
+        if (e == null) 
+            throw new NullPointerException();
+
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+
+                if (index<0 || index>_size.get())
+                    throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
+
+                if (index==_size.get())
+                {
+                    add(e);
+                }
+                else
+                {
+                    if (_tail==_head)
+                        if (!grow())
+                            throw new IllegalStateException("full");
+
+                    int i = _head+index;
+                    if (i>=_capacity)
+                        i-=_capacity;
+
+                    _size.incrementAndGet();
+                    _tail=(_tail+1)%_capacity;
+
+
+                    if (i<_tail)
+                    {
+                        System.arraycopy(_elements,i,_elements,i+1,_tail-i);
+                        _elements[i]=e;
+                    }
+                    else
+                    {
+                        if (_tail>0)
+                        {
+                            System.arraycopy(_elements,0,_elements,1,_tail);
+                            _elements[0]=_elements[_capacity-1];
+                        }
+
+                        System.arraycopy(_elements,i,_elements,i+1,_capacity-i-1);
+                        _elements[i]=e;
+                    }
+                }
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean grow()
+    {
+        if (_growCapacity<=0)
+            return false;
+
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+                final int head=_head;
+                final int tail=_tail;
+                final int new_tail;
+
+                Object[] elements=new Object[_capacity+_growCapacity];
+
+                if (head<tail)
+                {
+                    new_tail=tail-head;
+                    System.arraycopy(_elements,head,elements,0,new_tail);
+                }
+                else if (head>tail || _size.get()>0)
+                {
+                    new_tail=_capacity+tail-head;
+                    int cut=_capacity-head;
+                    System.arraycopy(_elements,head,elements,0,cut);
+                    System.arraycopy(_elements,0,elements,cut,tail);
+                }
+                else
+                {
+                    new_tail=0;
+                }
+
+                _elements=elements;
+                _capacity=_elements.length;
+                _head=0;
+                _tail=new_tail; 
+                return true;
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+
+    }
+
+    /* ------------------------------------------------------------ */
+    public int drainTo(Collection<? super E> c)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    public int drainTo(Collection<? super E> c, int maxElements)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean offer(E o, long timeout, TimeUnit unit) throws InterruptedException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void put(E o) throws InterruptedException
+    {
+        if (!add(o))
+            throw new IllegalStateException("full");
+    }
+
+    /* ------------------------------------------------------------ */
+    public int remainingCapacity()
+    {
+        _tailLock.lock();
+        try
+        {
+            _headLock.lock();
+            try
+            {
+                return getCapacity()-size();
+            }
+            finally
+            {
+                _headLock.unlock();
+            }
+        }
+        finally
+        {
+            _tailLock.unlock();
+        }
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    long sumOfSpace()
+    {
+        // this method exists to stop clever optimisers removing the spacers
+        return _space0++ +_space1++ +_space2++ +_space3++ +_space4++ +_space5++ +_space6++ +_space7++; 
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ByteArrayISO8859Writer.java b/src/java/org/eclipse/jetty/util/ByteArrayISO8859Writer.java
new file mode 100644
index 0000000..6085d30
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ByteArrayISO8859Writer.java
@@ -0,0 +1,272 @@
+//
+//  ========================================================================
+//  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.util;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+
+/* ------------------------------------------------------------ */
+/** Byte Array ISO 8859 writer. 
+ * This class combines the features of a OutputStreamWriter for
+ * ISO8859 encoding with that of a ByteArrayOutputStream.  It avoids
+ * many inefficiencies associated with these standard library classes.
+ * It has been optimized for standard ASCII characters.
+ * 
+ * 
+ */
+public class ByteArrayISO8859Writer extends Writer
+{
+    private byte[] _buf;
+    private int _size;
+    private ByteArrayOutputStream2 _bout=null;
+    private OutputStreamWriter _writer=null;
+    private boolean _fixed=false;
+
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     */
+    public ByteArrayISO8859Writer()
+    {
+        _buf=new byte[2048];
+    } 
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param capacity Buffer capacity
+     */
+    public ByteArrayISO8859Writer(int capacity)
+    {
+        _buf=new byte[capacity];
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ByteArrayISO8859Writer(byte[] buf)
+    {
+        _buf=buf;
+        _fixed=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object getLock()
+    {
+        return lock;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int size()
+    {
+        return _size;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int capacity()
+    {
+        return _buf.length;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int spareCapacity()
+    {
+        return _buf.length-_size;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setLength(int l)
+    {
+        _size=l;
+    }
+
+    /* ------------------------------------------------------------ */
+    public byte[] getBuf()
+    {
+        return _buf;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void writeTo(OutputStream out)
+        throws IOException
+    {
+        out.write(_buf,0,_size);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void write(char c)
+        throws IOException
+    {
+        ensureSpareCapacity(1);
+        if (c>=0&&c<=0x7f)
+            _buf[_size++]=(byte)c;
+        else
+        {
+            char[] ca ={c};
+            writeEncoded(ca,0,1);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(char[] ca)
+        throws IOException
+    {
+        ensureSpareCapacity(ca.length);
+        for (int i=0;i<ca.length;i++)
+        {
+            char c=ca[i];
+            if (c>=0&&c<=0x7f)
+                _buf[_size++]=(byte)c;
+            else
+            {
+                writeEncoded(ca,i,ca.length-i);
+                break;
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(char[] ca,int offset, int length)
+        throws IOException
+    {
+        ensureSpareCapacity(length);
+        for (int i=0;i<length;i++)
+        {
+            char c=ca[offset+i];
+            if (c>=0&&c<=0x7f)
+                _buf[_size++]=(byte)c;
+            else
+            {
+                writeEncoded(ca,offset+i,length-i);
+                break;
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(String s)
+        throws IOException
+    {
+        if (s==null)
+        {
+            write("null",0,4);
+            return;
+        }
+        
+        int length=s.length();
+        ensureSpareCapacity(length);
+        for (int i=0;i<length;i++)
+        {
+            char c=s.charAt(i);
+            if (c>=0x0&&c<=0x7f)
+                _buf[_size++]=(byte)c;
+            else
+            {
+                writeEncoded(s.toCharArray(),i,length-i);
+                break;
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(String s,int offset, int length)
+        throws IOException
+    {
+        ensureSpareCapacity(length);
+        for (int i=0;i<length;i++)
+        {
+            char c=s.charAt(offset+i);
+            if (c>=0&&c<=0x7f)
+                _buf[_size++]=(byte)c;
+            else
+            {
+                writeEncoded(s.toCharArray(),offset+i,length-i);
+                break;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void writeEncoded(char[] ca,int offset, int length)
+        throws IOException
+    {
+        if (_bout==null)
+        {
+            _bout = new ByteArrayOutputStream2(2*length);
+            _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1);
+        }
+        else
+            _bout.reset();
+        _writer.write(ca,offset,length);
+        _writer.flush();
+        ensureSpareCapacity(_bout.getCount());
+        System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount());
+        _size+=_bout.getCount();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void flush()
+    {}
+
+    /* ------------------------------------------------------------ */
+    public void resetWriter()
+    {
+        _size=0;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void close()
+    {}
+
+    /* ------------------------------------------------------------ */
+    public void destroy()
+    {
+        _buf=null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void ensureSpareCapacity(int n)
+        throws IOException
+    {
+        if (_size+n>_buf.length)
+        {
+            if (_fixed)
+                throw new IOException("Buffer overflow: "+_buf.length);
+            byte[] buf = new byte[(_buf.length+n)*4/3];
+            System.arraycopy(_buf,0,buf,0,_size);
+            _buf=buf;
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public byte[] getByteArray()
+    {
+        byte[] data=new byte[_size];
+        System.arraycopy(_buf,0,data,0,_size);
+        return data;
+    }
+    
+}
+    
+    
diff --git a/src/java/org/eclipse/jetty/util/ByteArrayOutputStream2.java b/src/java/org/eclipse/jetty/util/ByteArrayOutputStream2.java
new file mode 100644
index 0000000..1d10fbc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ByteArrayOutputStream2.java
@@ -0,0 +1,49 @@
+//
+//  ========================================================================
+//  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.util;
+import java.io.ByteArrayOutputStream;
+
+/* ------------------------------------------------------------ */
+/** ByteArrayOutputStream with public internals
+
+ * 
+ */
+public class ByteArrayOutputStream2 extends ByteArrayOutputStream
+{
+    public ByteArrayOutputStream2(){super();}
+    public ByteArrayOutputStream2(int size){super(size);}
+    public byte[] getBuf(){return buf;}
+    public int getCount(){return count;}
+    public void setCount(int count){this.count = count;}
+
+    public void reset(int minSize)
+    {
+        reset();
+        if (buf.length<minSize)
+        {
+            buf=new byte[minSize];
+        }
+    }
+    
+    public void writeUnchecked(int b)
+    {
+        buf[count++]=(byte)b;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/util/ConcurrentHashSet.java b/src/java/org/eclipse/jetty/util/ConcurrentHashSet.java
new file mode 100644
index 0000000..4a4c8e6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ConcurrentHashSet.java
@@ -0,0 +1,126 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>
+{
+    private final Map<E, Boolean> _map = new ConcurrentHashMap<E, Boolean>();
+    private transient Set<E> _keys = _map.keySet();
+
+    public ConcurrentHashSet()
+    {
+    }
+
+    @Override
+    public boolean add(E e)
+    {
+        return _map.put(e,Boolean.TRUE) == null;
+    }
+
+    @Override
+    public void clear()
+    {
+        _map.clear();
+    }
+
+    @Override
+    public boolean contains(Object o)
+    {
+        return _map.containsKey(o);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c)
+    {
+        return _keys.containsAll(c);
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        return o == this || _keys.equals(o);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return _keys.hashCode();
+    }
+
+    @Override
+    public boolean isEmpty()
+    {
+        return _map.isEmpty();
+    }
+
+    @Override
+    public Iterator<E> iterator()
+    {
+        return _keys.iterator();
+    }
+
+    @Override
+    public boolean remove(Object o)
+    {
+        return _map.remove(o) != null;
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c)
+    {
+        return _keys.removeAll(c);
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c)
+    {
+        return _keys.retainAll(c);
+    }
+
+    @Override
+    public int size()
+    {
+        return _map.size();
+    }
+
+    @Override
+    public Object[] toArray()
+    {
+        return _keys.toArray();
+    }
+
+    @Override
+    public <T> T[] toArray(T[] a)
+    {
+        return _keys.toArray(a);
+    }
+
+    @Override
+    public String toString()
+    {
+        return _keys.toString();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/DateCache.java b/src/java/org/eclipse/jetty/util/DateCache.java
new file mode 100644
index 0000000..42df49b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/DateCache.java
@@ -0,0 +1,311 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/* ------------------------------------------------------------ */
+/**  Date Format Cache.
+ * Computes String representations of Dates and caches
+ * the results so that subsequent requests within the same minute
+ * will be fast.
+ *
+ * Only format strings that contain either "ss" or "ss.SSS" are
+ * handled.
+ *
+ * The timezone of the date may be included as an ID with the "zzz"
+ * format string or as an offset with the "ZZZ" format string.
+ *
+ * If consecutive calls are frequently very different, then this
+ * may be a little slower than a normal DateFormat.
+ *
+ * 
+ * 
+ */
+
+public class DateCache  
+{
+    public static String DEFAULT_FORMAT="EEE MMM dd HH:mm:ss zzz yyyy";
+    private static long __hitWindow=60*60;
+    
+    private String _formatString;
+    private String _tzFormatString;
+    private SimpleDateFormat _tzFormat;
+    
+    private String _minFormatString;
+    private SimpleDateFormat _minFormat;
+
+    private String _secFormatString;
+    private String _secFormatString0;
+    private String _secFormatString1;
+
+    private long _lastMinutes = -1;
+    private long _lastSeconds = -1;
+    private int _lastMs = -1;
+    private String _lastResult = null;
+
+    private Locale _locale	= null;
+    private DateFormatSymbols	_dfs	= null;
+
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     * Make a DateCache that will use a default format. The default format
+     * generates the same results as Date.toString().
+     */
+    public DateCache()
+    {
+        this(DEFAULT_FORMAT);
+        getFormat().setTimeZone(TimeZone.getDefault());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     * Make a DateCache that will use the given format
+     */
+    public DateCache(String format)
+    {
+        _formatString=format;
+        setTimeZone(TimeZone.getDefault());
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    public DateCache(String format,Locale l)
+    {
+        _formatString=format;
+        _locale = l;
+        setTimeZone(TimeZone.getDefault());       
+    }
+    
+    /* ------------------------------------------------------------ */
+    public DateCache(String format,DateFormatSymbols s)
+    {
+        _formatString=format;
+        _dfs = s;
+        setTimeZone(TimeZone.getDefault());
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the timezone.
+     * @param tz TimeZone
+     */
+    public synchronized void setTimeZone(TimeZone tz)
+    {
+        setTzFormatString(tz);        
+        if( _locale != null ) 
+        {
+            _tzFormat=new SimpleDateFormat(_tzFormatString,_locale);
+            _minFormat=new SimpleDateFormat(_minFormatString,_locale);
+        }
+        else if( _dfs != null ) 
+        {
+            _tzFormat=new SimpleDateFormat(_tzFormatString,_dfs);
+            _minFormat=new SimpleDateFormat(_minFormatString,_dfs);
+        }
+        else 
+        {
+            _tzFormat=new SimpleDateFormat(_tzFormatString);
+            _minFormat=new SimpleDateFormat(_minFormatString);
+        }
+        _tzFormat.setTimeZone(tz);
+        _minFormat.setTimeZone(tz);
+        _lastSeconds=-1;
+        _lastMinutes=-1;        
+    }
+
+    /* ------------------------------------------------------------ */
+    public TimeZone getTimeZone()
+    {
+        return _tzFormat.getTimeZone();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the timezone.
+     * @param timeZoneId TimeZoneId the ID of the zone as used by
+     * TimeZone.getTimeZone(id)
+     */
+    public void setTimeZoneID(String timeZoneId)
+    {
+        setTimeZone(TimeZone.getTimeZone(timeZoneId));
+    }
+    
+    /* ------------------------------------------------------------ */
+    private synchronized void setTzFormatString(final  TimeZone tz )
+    {
+        int zIndex = _formatString.indexOf( "ZZZ" );
+        if( zIndex >= 0 )
+        {
+            String ss1 = _formatString.substring( 0, zIndex );
+            String ss2 = _formatString.substring( zIndex+3 );
+            int tzOffset = tz.getRawOffset();
+            
+            StringBuilder sb = new StringBuilder(_formatString.length()+10);
+            sb.append(ss1);
+            sb.append("'");
+            if( tzOffset >= 0 )
+                sb.append( '+' );
+            else
+            {
+                tzOffset = -tzOffset;
+                sb.append( '-' );
+            }
+            
+            int raw = tzOffset / (1000*60);		// Convert to seconds
+            int hr = raw / 60;
+            int min = raw % 60;
+            
+            if( hr < 10 )
+                sb.append( '0' );
+            sb.append( hr );
+            if( min < 10 )
+                sb.append( '0' );
+            sb.append( min );
+            sb.append( '\'' );
+            
+            sb.append(ss2);
+            _tzFormatString=sb.toString();            
+        }
+        else
+            _tzFormatString=_formatString;
+        setMinFormatString();
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    private void setMinFormatString()
+    {
+        int i = _tzFormatString.indexOf("ss.SSS");
+        int l = 6;
+        if (i>=0)
+            throw new IllegalStateException("ms not supported");
+        i = _tzFormatString.indexOf("ss");
+        l=2;
+        
+        // Build a formatter that formats a second format string
+        String ss1=_tzFormatString.substring(0,i);
+        String ss2=_tzFormatString.substring(i+l);
+        _minFormatString =ss1+"'ss'"+ss2;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Format a date according to our stored formatter.
+     * @param inDate 
+     * @return Formatted date
+     */
+    public synchronized String format(Date inDate)
+    {
+        return format(inDate.getTime());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Format a date according to our stored formatter.
+     * @param inDate 
+     * @return Formatted date
+     */
+    public synchronized String format(long inDate)
+    {
+        long seconds = inDate / 1000;
+
+        // Is it not suitable to cache?
+        if (seconds<_lastSeconds ||
+            _lastSeconds>0 && seconds>_lastSeconds+__hitWindow)
+        {
+            // It's a cache miss
+            Date d = new Date(inDate);
+            return _tzFormat.format(d);
+            
+        }
+                                          
+        // Check if we are in the same second
+        // and don't care about millis
+        if (_lastSeconds==seconds )
+            return _lastResult;
+
+        Date d = new Date(inDate);
+        
+        // Check if we need a new format string
+        long minutes = seconds/60;
+        if (_lastMinutes != minutes)
+        {
+            _lastMinutes = minutes;
+            _secFormatString=_minFormat.format(d);
+
+            int i=_secFormatString.indexOf("ss");
+            int l=2;
+            _secFormatString0=_secFormatString.substring(0,i);
+            _secFormatString1=_secFormatString.substring(i+l);
+        }
+
+        // Always format if we get here
+        _lastSeconds = seconds;
+        StringBuilder sb=new StringBuilder(_secFormatString.length());
+        sb.append(_secFormatString0);
+        int s=(int)(seconds%60);
+        if (s<10)
+            sb.append('0');
+        sb.append(s);
+        sb.append(_secFormatString1);
+        _lastResult=sb.toString();
+
+                
+        return _lastResult;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Format to string buffer. 
+     * @param inDate Date the format
+     * @param buffer StringBuilder
+     */
+    public void format(long inDate, StringBuilder buffer)
+    {
+        buffer.append(format(inDate));
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the format.
+     */
+    public SimpleDateFormat getFormat()
+    {
+        return _minFormat;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getFormatString()
+    {
+        return _formatString;
+    }    
+
+    /* ------------------------------------------------------------ */
+    public String now()
+    {
+        long now=System.currentTimeMillis();
+        _lastMs=(int)(now%1000);
+        return format(now);
+    }
+
+    /* ------------------------------------------------------------ */
+    public int lastMs()
+    {
+        return _lastMs;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/HostMap.java b/src/java/org/eclipse/jetty/util/HostMap.java
new file mode 100644
index 0000000..23e10bb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/HostMap.java
@@ -0,0 +1,108 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/* ------------------------------------------------------------ */
+/**
+ */
+@SuppressWarnings("serial")
+public class HostMap<TYPE> extends HashMap<String, TYPE>
+{
+
+    /* --------------------------------------------------------------- */
+    /** Construct empty HostMap.
+     */
+    public HostMap()
+    {
+        super(11);
+    }
+   
+    /* --------------------------------------------------------------- */
+    /** Construct empty HostMap.
+     * 
+     * @param capacity initial capacity
+     */
+    public HostMap(int capacity)
+    {
+        super (capacity);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public TYPE put(String host, TYPE object)
+        throws IllegalArgumentException
+    {
+        return super.put(host, object);
+    }
+        
+    /* ------------------------------------------------------------ */
+    /**
+     * @see java.util.HashMap#get(java.lang.Object)
+     */
+    @Override
+    public TYPE get(Object key)
+    {
+        return super.get(key);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve a lazy list of map entries associated with specified
+     * hostname by taking into account the domain suffix matches.
+     * 
+     * @param host hostname
+     * @return lazy list of map entries
+     */
+    public Object getLazyMatches(String host)
+    {
+        if (host == null)
+            return LazyList.getList(super.entrySet());
+        
+        int idx = 0;
+        String domain = host.trim();
+        HashSet<String> domains = new HashSet<String>();
+        do {
+            domains.add(domain);
+            if ((idx = domain.indexOf('.')) > 0)
+            {
+                domain = domain.substring(idx+1);
+            }
+        } while (idx > 0);
+        
+        Object entries = null;
+        for(Map.Entry<String, TYPE> entry: super.entrySet())
+        {
+            if (domains.contains(entry.getKey()))
+            {
+                entries = LazyList.add(entries,entry);
+            }
+        }
+       
+        return entries;        
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/IO.java b/src/java/org/eclipse/jetty/util/IO.java
new file mode 100644
index 0000000..bc253bc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/IO.java
@@ -0,0 +1,556 @@
+//
+//  ========================================================================
+//  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.util;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+/* ======================================================================== */
+/** IO Utilities.
+ * Provides stream handling utilities in
+ * singleton Threadpool implementation accessed by static members.
+ */
+public class IO 
+{
+    private static final Logger LOG = Log.getLogger(IO.class);
+    
+    /* ------------------------------------------------------------------- */
+    public final static String
+        CRLF      = "\015\012";
+
+    /* ------------------------------------------------------------------- */
+    public final static byte[]
+        CRLF_BYTES    = {(byte)'\015',(byte)'\012'};
+
+    /* ------------------------------------------------------------------- */
+    public static int bufferSize = 64*1024;
+    
+    /* ------------------------------------------------------------------- */
+    // TODO get rid of this singleton!
+    private static class Singleton {
+        static final QueuedThreadPool __pool=new QueuedThreadPool();
+        static
+        {
+            try{__pool.start();}
+            catch(Exception e){LOG.warn(e); System.exit(1);}
+        }
+    }
+
+    /* ------------------------------------------------------------------- */
+    static class Job implements Runnable
+    {
+        InputStream in;
+        OutputStream out;
+        Reader read;
+        Writer write;
+
+        Job(InputStream in,OutputStream out)
+        {
+            this.in=in;
+            this.out=out;
+            this.read=null;
+            this.write=null;
+        }
+        Job(Reader read,Writer write)
+        {
+            this.in=null;
+            this.out=null;
+            this.read=read;
+            this.write=write;
+        }
+        
+        /* ------------------------------------------------------------ */
+        /* 
+         * @see java.lang.Runnable#run()
+         */
+        public void run()
+        {
+            try {
+                if (in!=null)
+                    copy(in,out,-1);
+                else
+                    copy(read,write,-1);
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+                try{
+                    if (out!=null)
+                        out.close();
+                    if (write!=null)
+                        write.close();
+                }
+                catch(IOException e2)
+                {
+                    LOG.ignore(e2);
+                }
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Stream in to Stream out until EOF or exception.
+     * in own thread
+     */
+    public static void copyThread(InputStream in, OutputStream out)
+    {
+        try{
+            Job job=new Job(in,out);
+            if (!Singleton.__pool.dispatch(job))
+                job.run();
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Stream in to Stream out until EOF or exception.
+     */
+    public static void copy(InputStream in, OutputStream out)
+         throws IOException
+    {
+        copy(in,out,-1);
+    }
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Stream in to Stream out until EOF or exception
+     * in own thread
+     */
+    public static void copyThread(Reader in, Writer out)
+    {
+        try
+        {
+            Job job=new Job(in,out);
+            if (!Singleton.__pool.dispatch(job))
+                job.run();
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Reader to Writer out until EOF or exception.
+     */
+    public static void copy(Reader in, Writer out)
+         throws IOException
+    {
+        copy(in,out,-1);
+    }
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
+     */
+    public static void copy(InputStream in,
+                            OutputStream out,
+                            long byteCount)
+         throws IOException
+    {     
+        byte buffer[] = new byte[bufferSize];
+        int len=bufferSize;
+        
+        if (byteCount>=0)
+        {
+            while (byteCount>0)
+            {
+                int max = byteCount<bufferSize?(int)byteCount:bufferSize;
+                len=in.read(buffer,0,max);
+                
+                if (len==-1)
+                    break;
+                
+                byteCount -= len;
+                out.write(buffer,0,len);
+            }
+        }
+        else
+        {
+            while (true)
+            {
+                len=in.read(buffer,0,bufferSize);
+                if (len<0 )
+                    break;
+                out.write(buffer,0,len);
+            }
+        }
+    }  
+    
+    /* ------------------------------------------------------------------- */
+    /** Copy Reader to Writer for byteCount bytes or until EOF or exception.
+     */
+    public static void copy(Reader in,
+                            Writer out,
+                            long byteCount)
+         throws IOException
+    {  
+        char buffer[] = new char[bufferSize];
+        int len=bufferSize;
+        
+        if (byteCount>=0)
+        {
+            while (byteCount>0)
+            {
+                if (byteCount<bufferSize)
+                    len=in.read(buffer,0,(int)byteCount);
+                else
+                    len=in.read(buffer,0,bufferSize);                   
+                
+                if (len==-1)
+                    break;
+                
+                byteCount -= len;
+                out.write(buffer,0,len);
+            }
+        }
+        else if (out instanceof PrintWriter)
+        {
+            PrintWriter pout=(PrintWriter)out;
+            while (!pout.checkError())
+            {
+                len=in.read(buffer,0,bufferSize);
+                if (len==-1)
+                    break;
+                out.write(buffer,0,len);
+            }
+        }
+        else
+        {
+            while (true)
+            {
+                len=in.read(buffer,0,bufferSize);
+                if (len==-1)
+                    break;
+                out.write(buffer,0,len);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Copy files or directories
+     * @param from
+     * @param to
+     * @throws IOException
+     */
+    public static void copy(File from,File to) throws IOException
+    {
+        if (from.isDirectory())
+            copyDir(from,to);
+        else
+            copyFile(from,to);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void copyDir(File from,File to) throws IOException
+    {
+        if (to.exists())
+        {
+            if (!to.isDirectory())
+                throw new IllegalArgumentException(to.toString());
+        }
+        else
+            to.mkdirs();
+        
+        File[] files = from.listFiles();
+        if (files!=null)
+        {
+            for (int i=0;i<files.length;i++)
+            {
+                String name = files[i].getName();
+                if (".".equals(name) || "..".equals(name))
+                    continue;
+                copy(files[i],new File(to,name));
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static void copyFile(File from,File to) throws IOException
+    {
+        FileInputStream in=new FileInputStream(from);
+        FileOutputStream out=new FileOutputStream(to);
+        copy(in,out);
+        in.close();
+        out.close();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Read input stream to string.
+     */
+    public static String toString(InputStream in)
+        throws IOException
+    {
+        return toString(in,null);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Read input stream to string.
+     */
+    public static String toString(InputStream in,String encoding)
+        throws IOException
+    {
+        StringWriter writer=new StringWriter();
+        InputStreamReader reader = encoding==null?new InputStreamReader(in):new InputStreamReader(in,encoding);
+        
+        copy(reader,writer);
+        return writer.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Read input stream to string.
+     */
+    public static String toString(Reader in)
+        throws IOException
+    {
+        StringWriter writer=new StringWriter();
+        copy(in,writer);
+        return writer.toString();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Delete File.
+     * This delete will recursively delete directories - BE CAREFULL
+     * @param file The file to be deleted.
+     */
+    public static boolean delete(File file)
+    {
+        if (!file.exists())
+            return false;
+        if (file.isDirectory())
+        {
+            File[] files = file.listFiles();
+            for (int i=0;files!=null && i<files.length;i++)
+                delete(files[i]);
+        }
+        return file.delete();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * closes any {@link Closeable}
+     *
+     * @param c the closeable to close
+     */
+    public static void close(Closeable c)
+    {
+        try
+        {
+            if (c != null)
+                c.close();
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+    
+    /**
+     * closes an input stream, and logs exceptions
+     *
+     * @param is the input stream to close
+     */
+    public static void close(InputStream is)
+    {
+        try
+        {
+            if (is != null)
+                is.close();
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+    /**
+     * closes a reader, and logs exceptions
+     * 
+     * @param reader the reader to close
+     */
+    public static void close(Reader reader)
+    {
+        try
+        {
+            if (reader != null)
+                reader.close();
+        } catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+    /**
+     * closes a writer, and logs exceptions
+     * 
+     * @param writer the writer to close
+     */
+    public static void close(Writer writer)
+    {
+        try
+        {
+            if (writer != null)
+                writer.close();
+        } catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static byte[] readBytes(InputStream in)
+        throws IOException
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        copy(in,bout);
+        return bout.toByteArray();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * closes an output stream, and logs exceptions
+     *
+     * @param os the output stream to close
+     */
+    public static void close(OutputStream os)
+    {
+        try
+        {
+            if (os != null)
+                os.close();
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return An outputstream to nowhere
+     */
+    public static OutputStream getNullStream()
+    {
+        return __nullStream;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return An outputstream to nowhere
+     */
+    public static InputStream getClosedStream()
+    {
+        return __closedStream;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class NullOS extends OutputStream                                    
+    {
+        @Override
+        public void close(){}
+        @Override
+        public void flush(){}
+        @Override
+        public void write(byte[]b){}
+        @Override
+        public void write(byte[]b,int i,int l){}
+        @Override
+        public void write(int b){}
+    }
+    private static NullOS __nullStream = new NullOS();
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class ClosedIS extends InputStream                                    
+    {
+        @Override
+        public int read() throws IOException
+        {
+            return -1;
+        }
+    }
+    private static ClosedIS __closedStream = new ClosedIS();
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return An writer to nowhere
+     */
+    public static Writer getNullWriter()
+    {
+        return __nullWriter;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return An writer to nowhere
+     */
+    public static PrintWriter getNullPrintWriter()
+    {
+        return __nullPrintWriter;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class NullWrite extends Writer                                    
+    {
+        @Override
+        public void close(){}
+        @Override
+        public void flush(){}
+        @Override
+        public void write(char[]b){}
+        @Override
+        public void write(char[]b,int o,int l){}
+        @Override
+        public void write(int b){}
+        @Override
+        public void write(String s){}
+        @Override
+        public void write(String s,int o,int l){}
+    }
+    private static NullWrite __nullWriter = new NullWrite();
+    private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/java/org/eclipse/jetty/util/IPAddressMap.java b/src/java/org/eclipse/jetty/util/IPAddressMap.java
new file mode 100644
index 0000000..7cbbcab
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/IPAddressMap.java
@@ -0,0 +1,364 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Internet address map to object
+ * <p>
+ * Internet addresses may be specified as absolute address or as a combination of 
+ * four octet wildcard specifications (a.b.c.d) that are defined as follows.
+ * </p>
+ * <pre>
+ * nnn - an absolute value (0-255)
+ * mmm-nnn - an inclusive range of absolute values, 
+ *           with following shorthand notations:
+ *           nnn- => nnn-255
+ *           -nnn => 0-nnn
+ *           -    => 0-255
+ * a,b,... - a list of wildcard specifications
+ * </pre>
+ */
+@SuppressWarnings("serial")
+public class IPAddressMap<TYPE> extends HashMap<String, TYPE>
+{
+    private final HashMap<String,IPAddrPattern> _patterns = new HashMap<String,IPAddrPattern>();
+
+    /* --------------------------------------------------------------- */
+    /** Construct empty IPAddressMap.
+     */
+    public IPAddressMap()
+    {
+        super(11);
+    }
+   
+    /* --------------------------------------------------------------- */
+    /** Construct empty IPAddressMap.
+     * 
+     * @param capacity initial capacity
+     */
+    public IPAddressMap(int capacity)
+    {
+        super (capacity);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Insert a new internet address into map
+     * 
+     * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public TYPE put(String addrSpec, TYPE object)
+        throws IllegalArgumentException
+    {
+        if (addrSpec == null || addrSpec.trim().length() == 0)
+            throw new IllegalArgumentException("Invalid IP address pattern: "+addrSpec);
+        
+        String spec = addrSpec.trim();
+        if (_patterns.get(spec) == null)
+            _patterns.put(spec,new IPAddrPattern(spec));
+        
+        return super.put(spec, object);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the object mapped to the specified internet address literal
+     * 
+     * @see java.util.HashMap#get(java.lang.Object)
+     */
+    @Override
+    public TYPE get(Object key)
+    {
+        return super.get(key);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the first object that is associated with the specified 
+     * internet address by taking into account the wildcard specifications.
+     * 
+     * @param addr internet address
+     * @return associated object
+     */
+    public TYPE match(String addr)
+    {
+        Map.Entry<String, TYPE> entry = getMatch(addr);
+        return entry==null ? null : entry.getValue();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve the first map entry that is associated with the specified 
+     * internet address by taking into account the wildcard specifications.
+     * 
+     * @param addr internet address
+     * @return map entry associated
+     */
+    public Map.Entry<String, TYPE> getMatch(String addr)
+    {
+        if (addr != null)
+        {
+            for(Map.Entry<String, TYPE> entry: super.entrySet())
+            {
+                if (_patterns.get(entry.getKey()).match(addr))
+                {
+                    return entry;
+                }
+            }
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieve a lazy list of map entries associated with specified
+     * internet address by taking into account the wildcard specifications.
+     * 
+     * @param addr  internet address
+     * @return lazy list of map entries
+     */
+    public Object getLazyMatches(String addr)
+    {
+        if (addr == null)
+            return LazyList.getList(super.entrySet());
+        
+        Object entries = null;
+        for(Map.Entry<String, TYPE> entry: super.entrySet())
+        {
+            if (_patterns.get(entry.getKey()).match(addr))
+            {
+                entries = LazyList.add(entries,entry);
+            }
+        }
+        return entries;        
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * IPAddrPattern
+     * 
+     * Represents internet address wildcard. 
+     * Matches the wildcard to provided internet address.
+     */
+    private static class IPAddrPattern
+    {
+        private final OctetPattern[] _octets = new OctetPattern[4];
+        /* ------------------------------------------------------------ */
+        /**
+         * Create new IPAddrPattern
+         * 
+         * @param value internet address wildcard specification
+         * @throws IllegalArgumentException if wildcard specification is invalid
+         */
+        public IPAddrPattern(String value)
+            throws IllegalArgumentException
+        {
+            if (value == null || value.trim().length() == 0)
+                throw new IllegalArgumentException("Invalid IP address pattern: "+value);
+                
+            try
+            {
+                StringTokenizer parts = new StringTokenizer(value, ".");
+                
+                String part;
+                for (int idx=0; idx<4; idx++)
+                {
+                    part = parts.hasMoreTokens() ? parts.nextToken().trim() : "0-255";
+                    
+                    int len = part.length();
+                    if (len == 0 && parts.hasMoreTokens())
+                        throw new IllegalArgumentException("Invalid IP address pattern: "+value);
+                    
+                    _octets[idx] = new OctetPattern(len==0 ? "0-255" : part);
+                }
+            }
+            catch (IllegalArgumentException ex)
+            {
+                throw new IllegalArgumentException("Invalid IP address pattern: "+value, ex);
+            }
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * Match the specified internet address against the wildcard
+         * 
+         * @param value internet address
+         * @return true if specified internet address matches wildcard specification
+         * 
+         * @throws IllegalArgumentException if specified internet address is invalid
+         */
+        public boolean match(String value)
+            throws IllegalArgumentException
+        {
+            if (value == null || value.trim().length() == 0)
+                throw new IllegalArgumentException("Invalid IP address: "+value);
+            
+            try
+            {
+                StringTokenizer parts = new StringTokenizer(value, ".");
+                
+                boolean result = true;
+                for (int idx=0; idx<4; idx++)
+                {
+                    if (!parts.hasMoreTokens())
+                        throw new IllegalArgumentException("Invalid IP address: "+value);
+                        
+                    if (!(result &= _octets[idx].match(parts.nextToken())))
+                        break;
+                }
+                return result;
+            }
+            catch (IllegalArgumentException ex)
+            {
+                throw new IllegalArgumentException("Invalid IP address: "+value, ex);
+            }
+        }
+    }
+        
+    /* ------------------------------------------------------------ */
+    /**
+     * OctetPattern
+     * 
+     * Represents a single octet wildcard.
+     * Matches the wildcard to the specified octet value.
+     */
+    private static class OctetPattern extends BitSet
+    {
+        private final BitSet _mask = new BitSet(256);
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * Create new OctetPattern
+         * 
+         * @param octetSpec octet wildcard specification
+         * @throws IllegalArgumentException if wildcard specification is invalid
+         */
+        public OctetPattern(String octetSpec)
+            throws IllegalArgumentException
+        {
+            try
+            {
+                if (octetSpec != null)
+                {
+                    String spec = octetSpec.trim();
+                    if(spec.length() == 0)
+                    {
+                        _mask.set(0,255);
+                    }
+                    else
+                    {
+                        StringTokenizer parts = new StringTokenizer(spec,",");
+                        while (parts.hasMoreTokens())
+                        {
+                            String part = parts.nextToken().trim();
+                            if (part.length() > 0)
+                            {
+                                if (part.indexOf('-') < 0)
+                                {
+                                    Integer value = Integer.valueOf(part);
+                                    _mask.set(value);
+                                }
+                                else
+                                {
+                                    int low = 0, high = 255;
+                                    
+                                    String[] bounds = part.split("-",-2);
+                                    if (bounds.length != 2)
+                                    {
+                                        throw new IllegalArgumentException("Invalid octet spec: "+octetSpec);
+                                    }
+                                    
+                                    if (bounds[0].length() > 0)
+                                    {
+                                        low = Integer.parseInt(bounds[0]);
+                                    }
+                                    if (bounds[1].length() > 0)
+                                    {
+                                        high = Integer.parseInt(bounds[1]);
+                                    }
+                                    
+                                    if (low > high)
+                                    {
+                                        throw new IllegalArgumentException("Invalid octet spec: "+octetSpec);
+                                    }
+                                    
+                                    _mask.set(low, high+1);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (NumberFormatException ex)
+            {
+                throw new IllegalArgumentException("Invalid octet spec: "+octetSpec, ex);
+            }
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * Match specified octet value against the wildcard
+         * 
+         * @param value octet value
+         * @return true if specified octet value matches the wildcard
+         * @throws IllegalArgumentException if specified octet value is invalid
+         */
+        public boolean match(String value)
+            throws IllegalArgumentException
+        {
+            if (value == null || value.trim().length() == 0)
+                throw new IllegalArgumentException("Invalid octet: "+value);
+
+            try
+            {
+                int number = Integer.parseInt(value);
+                return match(number);
+            }
+            catch (NumberFormatException ex)
+            {
+                throw new IllegalArgumentException("Invalid octet: "+value);
+            }
+        }
+        
+        /* ------------------------------------------------------------ */
+        /**
+         * Match specified octet value against the wildcard
+         * 
+         * @param number octet value
+         * @return true if specified octet value matches the wildcard
+         * @throws IllegalArgumentException if specified octet value is invalid
+         */
+        public boolean match(int number)
+            throws IllegalArgumentException
+        {
+            if (number < 0 || number > 255)
+                throw new IllegalArgumentException("Invalid octet: "+number);
+            
+            return _mask.get(number);
+        }
+    }   
+}
diff --git a/src/java/org/eclipse/jetty/util/IntrospectionUtil.java b/src/java/org/eclipse/jetty/util/IntrospectionUtil.java
new file mode 100644
index 0000000..8588675
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/IntrospectionUtil.java
@@ -0,0 +1,300 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * IntrospectionUtil
+ *
+ *
+ */
+public class IntrospectionUtil
+{
+    
+    public static boolean isJavaBeanCompliantSetter (Method method)
+    {
+        if (method == null)
+            return false;
+        
+        if (method.getReturnType() != Void.TYPE)
+            return false;
+        
+        if (!method.getName().startsWith("set"))
+            return false;
+        
+        if (method.getParameterTypes().length != 1)
+            return false;
+        
+        return true;
+    }
+    
+    public static Method findMethod (Class<?> clazz, String methodName, Class<?>[] args, boolean checkInheritance, boolean strictArgs)
+    throws NoSuchMethodException
+    {
+        if (clazz == null)
+            throw new NoSuchMethodException("No class");
+        if (methodName==null || methodName.trim().equals(""))
+            throw new NoSuchMethodException("No method name");
+        
+        Method method = null;
+        Method[] methods = clazz.getDeclaredMethods();
+        for (int i=0;i<methods.length && method==null;i++)
+        {
+            if (methods[i].getName().equals(methodName) && checkParams(methods[i].getParameterTypes(), (args==null?new Class[] {}:args), strictArgs))
+            {
+                method = methods[i];
+            }
+            
+        }
+        if (method!=null)
+        {
+            return method;
+        }
+        else if (checkInheritance)
+                return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs);
+        else
+            throw new NoSuchMethodException("No such method "+methodName+" on class "+clazz.getName());
+
+    }
+    
+    
+    
+    
+
+    public static Field findField (Class<?> clazz, String targetName, Class<?> targetType, boolean checkInheritance, boolean strictType)
+    throws NoSuchFieldException
+    {
+        if (clazz == null)
+            throw new NoSuchFieldException("No class");
+        if (targetName==null)
+            throw new NoSuchFieldException("No field name");
+        
+        try
+        {
+            Field field = clazz.getDeclaredField(targetName);
+            if (strictType)
+            {
+                if (field.getType().equals(targetType))
+                    return field;
+            }
+            else
+            {
+                if (field.getType().isAssignableFrom(targetType))
+                    return field;
+            }
+            if (checkInheritance)
+            {
+                    return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), targetName, targetType, strictType);
+            }
+            else
+                throw new NoSuchFieldException("No field with name "+targetName+" in class "+clazz.getName()+" of type "+targetType);
+        }
+        catch (NoSuchFieldException e)
+        {
+            return findInheritedField(clazz.getPackage(),clazz.getSuperclass(), targetName,targetType,strictType);
+        }
+    }
+    
+    
+    
+    
+    
+    public static boolean isInheritable (Package pack, Member member)
+    {
+        if (pack==null)
+            return false;
+        if (member==null)
+            return false;
+        
+        int modifiers = member.getModifiers();
+        if (Modifier.isPublic(modifiers))
+            return true;
+        if (Modifier.isProtected(modifiers))
+            return true;
+        if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage()))
+            return true;
+       
+        return false;
+    }
+    
+   
+    
+    
+    public static boolean checkParams (Class<?>[] formalParams, Class<?>[] actualParams, boolean strict)
+    {
+        if (formalParams==null)
+            return actualParams==null;
+        if (actualParams==null)
+            return false;
+
+        if (formalParams.length!=actualParams.length)
+            return false;
+
+        if (formalParams.length==0)
+            return true; 
+        
+        int j=0;
+        if (strict)
+        {
+            while (j<formalParams.length && formalParams[j].equals(actualParams[j]))
+                j++;
+        }
+        else
+        { 
+            while ((j<formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j])))
+            {
+                j++;
+            }
+        }
+
+        if (j!=formalParams.length)
+        {
+            return false;
+        }
+
+        return true;
+    }
+    
+    
+    public static boolean isSameSignature (Method methodA, Method methodB)
+    {
+        if (methodA==null)
+            return false;
+        if (methodB==null)
+            return false;
+        
+        List<Class<?>> parameterTypesA = Arrays.asList(methodA.getParameterTypes());
+        List<Class<?>> parameterTypesB = Arrays.asList(methodB.getParameterTypes());
+       
+        if (methodA.getName().equals(methodB.getName())
+            &&
+            parameterTypesA.containsAll(parameterTypesB))
+            return true;
+        
+        return false;
+    }
+    
+    public static boolean isTypeCompatible (Class<?> formalType, Class<?> actualType, boolean strict)
+    {
+        if (formalType==null)
+            return actualType==null;
+        if (actualType==null)
+            return false;
+        
+        if (strict)
+            return formalType.equals(actualType);
+        else
+            return formalType.isAssignableFrom(actualType);
+    }
+
+    
+    
+    
+    public static boolean containsSameMethodSignature (Method method, Class<?> c, boolean checkPackage)
+    {
+        if (checkPackage)
+        {
+            if (!c.getPackage().equals(method.getDeclaringClass().getPackage()))
+                return false;
+        }
+        
+        boolean samesig = false;
+        Method[] methods = c.getDeclaredMethods();
+        for (int i=0; i<methods.length && !samesig; i++)
+        {
+            if (IntrospectionUtil.isSameSignature(method, methods[i]))
+                samesig = true;
+        }
+        return samesig;
+    }
+    
+    
+    public static boolean containsSameFieldName(Field field, Class<?> c, boolean checkPackage)
+    {
+        if (checkPackage)
+        {
+            if (!c.getPackage().equals(field.getDeclaringClass().getPackage()))
+                return false;
+        }
+        
+        boolean sameName = false;
+        Field[] fields = c.getDeclaredFields();
+        for (int i=0;i<fields.length && !sameName; i++)
+        {
+            if (fields[i].getName().equals(field.getName()))
+                sameName = true;
+        }
+        return sameName;
+    }
+    
+    
+    
+    protected static Method findInheritedMethod (Package pack, Class<?> clazz, String methodName, Class<?>[] args, boolean strictArgs)
+    throws NoSuchMethodException
+    {
+        if (clazz==null)
+            throw new NoSuchMethodException("No class");
+        if (methodName==null)
+            throw new NoSuchMethodException("No method name");
+        
+        Method method = null;
+        Method[] methods = clazz.getDeclaredMethods();
+        for (int i=0;i<methods.length && method==null;i++)
+        {
+            if (methods[i].getName().equals(methodName) 
+                    && isInheritable(pack,methods[i])
+                    && checkParams(methods[i].getParameterTypes(), args, strictArgs))
+                method = methods[i];
+        }
+        if (method!=null)
+        {
+            return method;
+        }
+        else
+            return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs);
+    }
+    
+    protected static Field findInheritedField (Package pack, Class<?> clazz, String fieldName, Class<?> fieldType, boolean strictType)
+    throws NoSuchFieldException
+    {
+        if (clazz==null)
+            throw new NoSuchFieldException ("No class");
+        if (fieldName==null)
+            throw new NoSuchFieldException ("No field name");
+        try
+        {
+            Field field = clazz.getDeclaredField(fieldName);
+            if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType))
+                return field;
+            else
+                return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType);
+        }
+        catch (NoSuchFieldException e)
+        {
+            return findInheritedField(clazz.getPackage(), clazz.getSuperclass(),fieldName, fieldType, strictType); 
+        }
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/util/LazyList.java b/src/java/org/eclipse/jetty/util/LazyList.java
new file mode 100644
index 0000000..b657fb6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/LazyList.java
@@ -0,0 +1,483 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/* ------------------------------------------------------------ */
+/** Lazy List creation.
+ * A List helper class that attempts to avoid unnecessary List
+ * creation.   If a method needs to create a List to return, but it is
+ * expected that this will either be empty or frequently contain a
+ * single item, then using LazyList will avoid additional object
+ * creations by using {@link Collections#EMPTY_LIST} or
+ * {@link Collections#singletonList(Object)} where possible.
+ * <p>
+ * LazyList works by passing an opaque representation of the list in
+ * and out of all the LazyList methods.  This opaque object is either
+ * null for an empty list, an Object for a list with a single entry
+ * or an {@link ArrayList} for a list of items.
+ *
+ * <p><h4>Usage</h4>
+ * <pre>
+ *   Object lazylist =null;
+ *   while(loopCondition)
+ *   {
+ *     Object item = getItem();
+ *     if (item.isToBeAdded())
+ *         lazylist = LazyList.add(lazylist,item);
+ *   }
+ *   return LazyList.getList(lazylist);
+ * </pre>
+ *
+ * An ArrayList of default size is used as the initial LazyList.
+ *
+ * @see java.util.List
+ */
+public class LazyList
+    implements Cloneable, Serializable
+{
+    private static final String[] __EMTPY_STRING_ARRAY = new String[0];
+    
+    /* ------------------------------------------------------------ */
+    private LazyList()
+    {}
+    
+    /* ------------------------------------------------------------ */
+    /** Add an item to a LazyList 
+     * @param list The list to add to or null if none yet created.
+     * @param item The item to add.
+     * @return The lazylist created or added to.
+     */
+    @SuppressWarnings("unchecked")
+    public static Object add(Object list, Object item)
+    {
+        if (list==null)
+        {
+            if (item instanceof List || item==null)
+            {
+                List<Object> l = new ArrayList<Object>();
+                l.add(item);
+                return l;
+            }
+
+            return item;
+        }
+
+        if (list instanceof List)
+        {
+            ((List<Object>)list).add(item);
+            return list;
+        }
+
+        List<Object> l=new ArrayList<Object>();
+        l.add(list);
+        l.add(item);
+        return l;    
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add an item to a LazyList 
+     * @param list The list to add to or null if none yet created.
+     * @param index The index to add the item at.
+     * @param item The item to add.
+     * @return The lazylist created or added to.
+     */
+    @SuppressWarnings("unchecked")
+    public static Object add(Object list, int index, Object item)
+    {
+        if (list==null)
+        {
+            if (index>0 || item instanceof List || item==null)
+            {
+                List<Object> l = new ArrayList<Object>();
+                l.add(index,item);
+                return l;
+            }
+            return item;
+        }
+
+        if (list instanceof List)
+        {
+            ((List<Object>)list).add(index,item);
+            return list;
+        }
+
+        List<Object> l=new ArrayList<Object>();
+        l.add(list);
+        l.add(index,item);
+        return l;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add the contents of a Collection to a LazyList
+     * @param list The list to add to or null if none yet created.
+     * @param collection The Collection whose contents should be added.
+     * @return The lazylist created or added to.
+     */
+    public static Object addCollection(Object list, Collection<?> collection)
+    {
+        Iterator<?> i=collection.iterator();
+        while(i.hasNext())
+            list=LazyList.add(list,i.next());
+        return list;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add the contents of an array to a LazyList
+     * @param list The list to add to or null if none yet created.
+     * @param array The array whose contents should be added.
+     * @return The lazylist created or added to.
+     */
+    public static Object addArray(Object list, Object[] array)
+    {
+        for(int i=0;array!=null && i<array.length;i++)
+            list=LazyList.add(list,array[i]);
+        return list;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Ensure the capacity of the underlying list.
+     * 
+     */
+    public static Object ensureSize(Object list, int initialSize)
+    {
+        if (list==null)
+            return new ArrayList<Object>(initialSize);
+        if (list instanceof ArrayList)
+        {
+            ArrayList<?> ol=(ArrayList<?>)list;
+            if (ol.size()>initialSize)
+                return ol;
+            ArrayList<Object> nl = new ArrayList<Object>(initialSize);
+            nl.addAll(ol);
+            return nl;
+        }
+        List<Object> l= new ArrayList<Object>(initialSize);
+        l.add(list);
+        return l;    
+    }
+
+    /* ------------------------------------------------------------ */
+    public static Object remove(Object list, Object o)
+    {
+        if (list==null)
+            return null;
+
+        if (list instanceof List)
+        {
+            List<?> l = (List<?>)list;
+            l.remove(o);
+            if (l.size()==0)
+                return null;
+            return list;
+        }
+
+        if (list.equals(o))
+            return null;
+        return list;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static Object remove(Object list, int i)
+    {
+        if (list==null)
+            return null;
+
+        if (list instanceof List)
+        {
+            List<?> l = (List<?>)list;
+            l.remove(i);
+            if (l.size()==0)
+                return null;
+            return list;
+        }
+
+        if (i==0)
+            return null;
+        return list;
+    }
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Get the real List from a LazyList.
+     * 
+     * @param list A LazyList returned from LazyList.add(Object)
+     * @return The List of added items, which may be an EMPTY_LIST
+     * or a SingletonList.
+     */
+    public static<E> List<E> getList(Object list)
+    {
+        return getList(list,false);
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /** Get the real List from a LazyList.
+     * 
+     * @param list A LazyList returned from LazyList.add(Object) or null
+     * @param nullForEmpty If true, null is returned instead of an
+     * empty list.
+     * @return The List of added items, which may be null, an EMPTY_LIST
+     * or a SingletonList.
+     */
+    @SuppressWarnings("unchecked")
+    public static<E> List<E> getList(Object list, boolean nullForEmpty)
+    {
+        if (list==null)
+        {
+            if (nullForEmpty)
+                return null;
+            return Collections.emptyList();
+        }
+        if (list instanceof List)
+            return (List<E>)list;
+        
+        return (List<E>)Collections.singletonList(list);
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    public static String[] toStringArray(Object list)
+    {
+        if (list==null)
+            return __EMTPY_STRING_ARRAY;
+        
+        if (list instanceof List)
+        {
+            List<?> l = (List<?>)list;
+            String[] a = new String[l.size()];
+            for (int i=l.size();i-->0;)
+            {
+                Object o=l.get(i);
+                if (o!=null)
+                    a[i]=o.toString();
+            }
+            return a;
+        }
+        
+        return new String[] {list.toString()};
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convert a lazylist to an array
+     * @param list The list to convert
+     * @param clazz The class of the array, which may be a primitive type
+     * @return array of the lazylist entries passed in
+     */
+    public static Object toArray(Object list,Class<?> clazz)
+    {
+        if (list==null)
+            return Array.newInstance(clazz,0);
+        
+        if (list instanceof List)
+        {
+            List<?> l = (List<?>)list;
+            if (clazz.isPrimitive())
+            {
+                Object a = Array.newInstance(clazz,l.size());
+                for (int i=0;i<l.size();i++)
+                    Array.set(a,i,l.get(i));
+                return a;
+            }
+            return l.toArray((Object[])Array.newInstance(clazz,l.size()));
+            
+        }
+        
+        Object a = Array.newInstance(clazz,1);
+        Array.set(a,0,list);
+        return a;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** The size of a lazy List 
+     * @param list  A LazyList returned from LazyList.add(Object) or null
+     * @return the size of the list.
+     */
+    public static int size(Object list)
+    {
+        if (list==null)
+            return 0;
+        if (list instanceof List)
+            return ((List<?>)list).size();
+        return 1;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get item from the list 
+     * @param list  A LazyList returned from LazyList.add(Object) or null
+     * @param i int index
+     * @return the item from the list.
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> E get(Object list, int i)
+    {
+        if (list==null)
+            throw new IndexOutOfBoundsException();
+       
+        if (list instanceof List)
+            return (E)((List<?>)list).get(i);
+
+        if (i==0)
+            return (E)list;
+        
+        throw new IndexOutOfBoundsException();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static boolean contains(Object list,Object item)
+    {
+        if (list==null)
+            return false;
+        
+        if (list instanceof List)
+            return ((List<?>)list).contains(item);
+
+        return list.equals(item);
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    public static Object clone(Object list)
+    {
+        if (list==null)
+            return null;
+        if (list instanceof List)
+            return new ArrayList<Object>((List<?>)list);
+        return list;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static String toString(Object list)
+    {
+        if (list==null)
+            return "[]";
+        if (list instanceof List)
+            return list.toString();
+        return "["+list+"]";
+    }
+
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    public static<E> Iterator<E> iterator(Object list)
+    {
+        if (list==null)
+        {
+            List<E> empty=Collections.emptyList();
+            return empty.iterator();
+        }
+        if (list instanceof List)
+        {
+            return ((List<E>)list).iterator();
+        }
+        List<E> l=getList(list);
+        return l.iterator();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("unchecked")
+    public static<E> ListIterator<E> listIterator(Object list)
+    {
+        if (list==null)
+        {
+            List<E> empty=Collections.emptyList();
+            return empty.listIterator();
+        }
+        if (list instanceof List)
+            return ((List<E>)list).listIterator();
+
+        List<E> l=getList(list);
+        return l.listIterator();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param array Any array of object
+     * @return A new <i>modifiable</i> list initialised with the elements from <code>array</code>.
+     */
+    public static<E> List<E> array2List(E[] array)
+    {	
+        if (array==null || array.length==0)
+            return new ArrayList<E>();
+        return new ArrayList<E>(Arrays.asList(array));
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add element to an array
+     * @param array The array to add to (or null)
+     * @param item The item to add
+     * @param type The type of the array (in case of null array)
+     * @return new array with contents of array plus item
+     */
+    public static<T> T[] addToArray(T[] array, T item, Class<?> type)
+    {
+        if (array==null)
+        {
+            if (type==null && item!=null)
+                type= item.getClass();
+            @SuppressWarnings("unchecked")
+            T[] na = (T[])Array.newInstance(type, 1);
+            na[0]=item;
+            return na;
+        }
+        else
+        {
+            // TODO: Replace with Arrays.copyOf(T[] original, int newLength) from Java 1.6+
+            Class<?> c = array.getClass().getComponentType();
+            @SuppressWarnings("unchecked")
+            T[] na = (T[])Array.newInstance(c, Array.getLength(array)+1);
+            System.arraycopy(array, 0, na, 0, array.length);
+            na[array.length]=item;
+            return na;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static<T> T[] removeFromArray(T[] array, Object item)
+    {
+        if (item==null || array==null)
+            return array;
+        for (int i=array.length;i-->0;)
+        {
+            if (item.equals(array[i]))
+            {
+                Class<?> c = array==null?item.getClass():array.getClass().getComponentType();
+                @SuppressWarnings("unchecked")
+                T[] na = (T[])Array.newInstance(c, Array.getLength(array)-1);
+                if (i>0)
+                    System.arraycopy(array, 0, na, 0, i);
+                if (i+1<array.length)
+                    System.arraycopy(array, i+1, na, i, array.length-(i+1));
+                return na;
+            }
+        }
+        return array;
+    }
+    
+}
+
diff --git a/src/java/org/eclipse/jetty/util/Loader.java b/src/java/org/eclipse/jetty/util/Loader.java
new file mode 100644
index 0000000..fed2968
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Loader.java
@@ -0,0 +1,193 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+/* ------------------------------------------------------------ */
+/** ClassLoader Helper.
+ * This helper class allows classes to be loaded either from the
+ * Thread's ContextClassLoader, the classloader of the derived class
+ * or the system ClassLoader.
+ *
+ * <B>Usage:</B><PRE>
+ * public class MyClass {
+ *     void myMethod() {
+ *          ...
+ *          Class c=Loader.loadClass(this.getClass(),classname);
+ *          ...
+ *     }
+ * </PRE>          
+ * 
+ */
+public class Loader
+{
+    /* ------------------------------------------------------------ */
+    public static URL getResource(Class<?> loadClass,String name, boolean checkParents)
+    {
+        URL url =null;
+        ClassLoader loader=Thread.currentThread().getContextClassLoader();
+        while (url==null && loader!=null )
+        {
+            url=loader.getResource(name); 
+            loader=(url==null&&checkParents)?loader.getParent():null;
+        }      
+        
+        loader=loadClass==null?null:loadClass.getClassLoader();
+        while (url==null && loader!=null )
+        {
+            url=loader.getResource(name); 
+            loader=(url==null&&checkParents)?loader.getParent():null;
+        }       
+
+        if (url==null)
+        {
+            url=ClassLoader.getSystemResource(name);
+        }   
+
+        return url;
+    }
+
+    /* ------------------------------------------------------------ */
+    @SuppressWarnings("rawtypes")
+    public static Class loadClass(Class loadClass,String name)
+        throws ClassNotFoundException
+    {
+        return loadClass(loadClass,name,false);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Load a class.
+     * 
+     * @param loadClass
+     * @param name
+     * @param checkParents If true, try loading directly from parent classloaders.
+     * @return Class
+     * @throws ClassNotFoundException
+     */
+    @SuppressWarnings("rawtypes")
+    public static Class loadClass(Class loadClass,String name,boolean checkParents)
+        throws ClassNotFoundException
+    {
+        ClassNotFoundException ex=null;
+        Class<?> c =null;
+        ClassLoader loader=Thread.currentThread().getContextClassLoader();
+        while (c==null && loader!=null )
+        {
+            try { c=loader.loadClass(name); }
+            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
+            loader=(c==null&&checkParents)?loader.getParent():null;
+        }      
+        
+        loader=loadClass==null?null:loadClass.getClassLoader();
+        while (c==null && loader!=null )
+        {
+            try { c=loader.loadClass(name); }
+            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
+            loader=(c==null&&checkParents)?loader.getParent():null;
+        }       
+
+        if (c==null)
+        {
+            try { c=Class.forName(name); }
+            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
+        }   
+
+        if (c!=null)
+            return c;
+        throw ex;
+    }
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    public static ResourceBundle getResourceBundle(Class<?> loadClass,String name,boolean checkParents, Locale locale)
+        throws MissingResourceException
+    {
+        MissingResourceException ex=null;
+        ResourceBundle bundle =null;
+        ClassLoader loader=Thread.currentThread().getContextClassLoader();
+        while (bundle==null && loader!=null )
+        {
+            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
+            catch (MissingResourceException e) {if(ex==null)ex=e;}
+            loader=(bundle==null&&checkParents)?loader.getParent():null;
+        }      
+        
+        loader=loadClass==null?null:loadClass.getClassLoader();
+        while (bundle==null && loader!=null )
+        {
+            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
+            catch (MissingResourceException e) {if(ex==null)ex=e;}
+            loader=(bundle==null&&checkParents)?loader.getParent():null;
+        }       
+
+        if (bundle==null)
+        {
+            try { bundle=ResourceBundle.getBundle(name, locale); }
+            catch (MissingResourceException e) {if(ex==null)ex=e;}
+        }   
+
+        if (bundle!=null)
+            return bundle;
+        throw ex;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Generate the classpath (as a string) of all classloaders
+     * above the given classloader.
+     * 
+     * This is primarily used for jasper.
+     * @return the system class path
+     */
+    public static String getClassPath(ClassLoader loader) throws Exception
+    {
+        StringBuilder classpath=new StringBuilder();
+        while (loader != null && (loader instanceof URLClassLoader))
+        {
+            URL[] urls = ((URLClassLoader)loader).getURLs();
+            if (urls != null)
+            {     
+                for (int i=0;i<urls.length;i++)
+                {
+                    Resource resource = Resource.newResource(urls[i]);
+                    File file=resource.getFile();
+                    if (file!=null && file.exists())
+                    {
+                        if (classpath.length()>0)
+                            classpath.append(File.pathSeparatorChar);
+                        classpath.append(file.getAbsolutePath());
+                    }
+                }
+            }
+            loader = loader.getParent();
+        }
+        return classpath.toString();
+    }
+}
+
diff --git a/src/java/org/eclipse/jetty/util/MultiException.java b/src/java/org/eclipse/jetty/util/MultiException.java
new file mode 100644
index 0000000..eaac800
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/MultiException.java
@@ -0,0 +1,185 @@
+//
+//  ========================================================================
+//  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.util;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.List;
+
+
+/* ------------------------------------------------------------ */
+/** Wraps multiple exceptions.
+ *
+ * Allows multiple exceptions to be thrown as a single exception.
+ *
+ * 
+ */
+@SuppressWarnings("serial")
+public class MultiException extends Exception
+{
+    private Object nested;
+
+    /* ------------------------------------------------------------ */
+    public MultiException()
+    {
+        super("Multiple exceptions");
+    }
+
+    /* ------------------------------------------------------------ */
+    public void add(Throwable e)
+    {
+        if (e instanceof MultiException)
+        {
+            MultiException me = (MultiException)e;
+            for (int i=0;i<LazyList.size(me.nested);i++)
+                nested=LazyList.add(nested,LazyList.get(me.nested,i));
+        }
+        else
+            nested=LazyList.add(nested,e);
+    }
+
+    /* ------------------------------------------------------------ */
+    public int size()
+    {
+        return LazyList.size(nested);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public List<Throwable> getThrowables()
+    {
+        return LazyList.getList(nested);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Throwable getThrowable(int i)
+    {
+        return (Throwable) LazyList.get(nested,i);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Throw a multiexception.
+     * If this multi exception is empty then no action is taken. If it
+     * contains a single exception that is thrown, otherwise the this
+     * multi exception is thrown. 
+     * @exception Exception 
+     */
+    public void ifExceptionThrow()
+        throws Exception
+    {
+        switch (LazyList.size(nested))
+        {
+          case 0:
+              break;
+          case 1:
+              Throwable th=(Throwable)LazyList.get(nested,0);
+              if (th instanceof Error)
+                  throw (Error)th;
+              if (th instanceof Exception)
+                  throw (Exception)th;
+          default:
+              throw this;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Throw a Runtime exception.
+     * If this multi exception is empty then no action is taken. If it
+     * contains a single error or runtime exception that is thrown, otherwise the this
+     * multi exception is thrown, wrapped in a runtime exception. 
+     * @exception Error If this exception contains exactly 1 {@link Error} 
+     * @exception RuntimeException If this exception contains 1 {@link Throwable} but it is not an error,
+     *                             or it contains more than 1 {@link Throwable} of any type.
+     */
+    public void ifExceptionThrowRuntime()
+        throws Error
+    {
+        switch (LazyList.size(nested))
+        {
+          case 0:
+              break;
+          case 1:
+              Throwable th=(Throwable)LazyList.get(nested,0);
+              if (th instanceof Error)
+                  throw (Error)th;
+              else if (th instanceof RuntimeException)
+                  throw (RuntimeException)th;
+              else
+                  throw new RuntimeException(th);
+          default:
+              throw new RuntimeException(this);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Throw a multiexception.
+     * If this multi exception is empty then no action is taken. If it
+     * contains a any exceptions then this
+     * multi exception is thrown. 
+     */
+    public void ifExceptionThrowMulti()
+        throws MultiException
+    {
+        if (LazyList.size(nested)>0)
+            throw this;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        if (LazyList.size(nested)>0)
+            return MultiException.class.getSimpleName()+
+                LazyList.getList(nested);
+        return MultiException.class.getSimpleName()+"[]";
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void printStackTrace()
+    {
+        super.printStackTrace();
+        for (int i=0;i<LazyList.size(nested);i++)
+            ((Throwable)LazyList.get(nested,i)).printStackTrace();
+    }
+   
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
+     */
+    @Override
+    public void printStackTrace(PrintStream out)
+    {
+        super.printStackTrace(out);
+        for (int i=0;i<LazyList.size(nested);i++)
+            ((Throwable)LazyList.get(nested,i)).printStackTrace(out);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
+     */
+    @Override
+    public void printStackTrace(PrintWriter out)
+    {
+        super.printStackTrace(out);
+        for (int i=0;i<LazyList.size(nested);i++)
+            ((Throwable)LazyList.get(nested,i)).printStackTrace(out);
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/MultiMap.java b/src/java/org/eclipse/jetty/util/MultiMap.java
new file mode 100644
index 0000000..54e4e53
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/MultiMap.java
@@ -0,0 +1,415 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/* ------------------------------------------------------------ */
+/** A multi valued Map.
+ * This Map specializes HashMap and provides methods
+ * that operate on multi valued items. 
+ * <P>
+ * Implemented as a map of LazyList values
+ * @param <K> The key type of the map.
+ *
+ * @see LazyList
+ * 
+ */
+public class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable
+{
+    private static final long serialVersionUID = -6878723138353851005L;
+    Map<K,Object> _map;
+    ConcurrentMap<K, Object> _cmap;
+
+    public MultiMap()
+    {
+        _map=new HashMap<K, Object>();
+    }
+    
+    public MultiMap(Map<K,Object> map)
+    {
+        if (map instanceof ConcurrentMap)
+            _map=_cmap=new ConcurrentHashMap<K, Object>(map);
+        else
+            _map=new HashMap<K, Object>(map);
+    }
+    
+    public MultiMap(MultiMap<K> map)
+    {
+        if (map._cmap!=null)
+            _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap);
+        else
+            _map=new HashMap<K,Object>(map._map);
+    }
+    
+    public MultiMap(int capacity)
+    {
+        _map=new HashMap<K, Object>(capacity);
+    }
+    
+    public MultiMap(boolean concurrent)
+    {
+        if (concurrent)
+            _map=_cmap=new ConcurrentHashMap<K, Object>();
+        else
+            _map=new HashMap<K, Object>();
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /** Get multiple values.
+     * Single valued entries are converted to singleton lists.
+     * @param name The entry key. 
+     * @return Unmodifieable List of values.
+     */
+    public List getValues(Object name)
+    {
+        return LazyList.getList(_map.get(name),true);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get a value from a multiple value.
+     * If the value is not a multivalue, then index 0 retrieves the
+     * value or null.
+     * @param name The entry key.
+     * @param i Index of element to get.
+     * @return Unmodifieable List of values.
+     */
+    public Object getValue(Object name,int i)
+    {
+        Object l=_map.get(name);
+        if (i==0 && LazyList.size(l)==0)
+            return null;
+        return LazyList.get(l,i);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Get value as String.
+     * Single valued items are converted to a String with the toString()
+     * Object method. Multi valued entries are converted to a comma separated
+     * List.  No quoting of commas within values is performed.
+     * @param name The entry key. 
+     * @return String value.
+     */
+    public String getString(Object name)
+    {
+        Object l=_map.get(name);
+        switch(LazyList.size(l))
+        {
+          case 0:
+              return null;
+          case 1:
+              Object o=LazyList.get(l,0);
+              return o==null?null:o.toString();
+          default:
+          {
+              StringBuilder values=new StringBuilder(128);
+              for (int i=0; i<LazyList.size(l); i++)              
+              {
+                  Object e=LazyList.get(l,i);
+                  if (e!=null)
+                  {
+                      if (values.length()>0)
+                          values.append(',');
+                      values.append(e.toString());
+                  }
+              }   
+              return values.toString();
+          }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Object get(Object name) 
+    {
+        Object l=_map.get(name);
+        switch(LazyList.size(l))
+        {
+          case 0:
+              return null;
+          case 1:
+              Object o=LazyList.get(l,0);
+              return o;
+          default:
+              return LazyList.getList(l,true);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Put and entry into the map.
+     * @param name The entry key. 
+     * @param value The entry value.
+     * @return The previous value or null.
+     */
+    public Object put(K name, Object value) 
+    {
+        return _map.put(name,LazyList.add(null,value));
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Put multi valued entry.
+     * @param name The entry key. 
+     * @param values The List of multiple values.
+     * @return The previous value or null.
+     */
+    public Object putValues(K name, List<? extends Object> values) 
+    {
+        return _map.put(name,values);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Put multi valued entry.
+     * @param name The entry key. 
+     * @param values The String array of multiple values.
+     * @return The previous value or null.
+     */
+    public Object putValues(K name, String... values) 
+    {
+        Object list=null;
+        for (int i=0;i<values.length;i++)
+            list=LazyList.add(list,values[i]);
+        return _map.put(name,list);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Add value to multi valued entry.
+     * If the entry is single valued, it is converted to the first
+     * value of a multi valued entry.
+     * @param name The entry key. 
+     * @param value The entry value.
+     */
+    public void add(K name, Object value) 
+    {
+        Object lo = _map.get(name);
+        Object ln = LazyList.add(lo,value);
+        if (lo!=ln)
+            _map.put(name,ln);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Add values to multi valued entry.
+     * If the entry is single valued, it is converted to the first
+     * value of a multi valued entry.
+     * @param name The entry key. 
+     * @param values The List of multiple values.
+     */
+    public void addValues(K name, List<? extends Object> values) 
+    {
+        Object lo = _map.get(name);
+        Object ln = LazyList.addCollection(lo,values);
+        if (lo!=ln)
+            _map.put(name,ln);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add values to multi valued entry.
+     * If the entry is single valued, it is converted to the first
+     * value of a multi valued entry.
+     * @param name The entry key. 
+     * @param values The String array of multiple values.
+     */
+    public void addValues(K name, String[] values) 
+    {
+        Object lo = _map.get(name);
+        Object ln = LazyList.addCollection(lo,Arrays.asList(values));
+        if (lo!=ln)
+            _map.put(name,ln);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Remove value.
+     * @param name The entry key. 
+     * @param value The entry value. 
+     * @return true if it was removed.
+     */
+    public boolean removeValue(K name,Object value)
+    {
+        Object lo = _map.get(name);
+        Object ln=lo;
+        int s=LazyList.size(lo);
+        if (s>0)
+        {
+            ln=LazyList.remove(lo,value);
+            if (ln==null)
+                _map.remove(name);
+            else
+                _map.put(name, ln);
+        }
+        return LazyList.size(ln)!=s;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Put all contents of map.
+     * @param m Map
+     */
+    public void putAll(Map<? extends K, ? extends Object> m)
+    {
+        boolean multi = (m instanceof MultiMap);
+
+        if (multi)
+        {
+            for (Map.Entry<? extends K, ? extends Object> entry : m.entrySet())
+            {
+                _map.put(entry.getKey(),LazyList.clone(entry.getValue()));
+            }
+        }
+        else
+        {
+            _map.putAll(m);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Map of String arrays
+     */
+    public Map<K,String[]> toStringArrayMap()
+    {
+        HashMap<K,String[]> map = new HashMap<K,String[]>(_map.size()*3/2)
+        {
+            public String toString()
+            {
+                StringBuilder b=new StringBuilder();
+                b.append('{');
+                for (K k:keySet())
+                {
+                    if(b.length()>1)
+                        b.append(',');
+                    b.append(k);
+                    b.append('=');
+                    b.append(Arrays.asList(get(k)));
+                }
+
+                b.append('}');
+                return b.toString();
+            }
+        };
+        
+        for(Map.Entry<K,Object> entry: _map.entrySet())
+        {
+            String[] a = LazyList.toStringArray(entry.getValue());
+            map.put(entry.getKey(),a);
+        }
+        return map;
+    }
+
+    @Override
+    public String toString()
+    {
+        return _cmap==null?_map.toString():_cmap.toString();
+    }
+    
+    public void clear()
+    {
+        _map.clear();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return _map.containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        return _map.containsValue(value);
+    }
+
+    public Set<Entry<K, Object>> entrySet()
+    {
+        return _map.entrySet();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        return _map.equals(o);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return _map.hashCode();
+    }
+
+    public boolean isEmpty()
+    {
+        return _map.isEmpty();
+    }
+
+    public Set<K> keySet()
+    {
+        return _map.keySet();
+    }
+
+    public Object remove(Object key)
+    {
+        return _map.remove(key);
+    }
+
+    public int size()
+    {
+        return _map.size();
+    }
+
+    public Collection<Object> values()
+    {
+        return _map.values();
+    }
+
+    
+    
+    public Object putIfAbsent(K key, Object value)
+    {
+        if (_cmap==null)
+            throw new UnsupportedOperationException();
+        return _cmap.putIfAbsent(key,value);
+    }
+
+    public boolean remove(Object key, Object value)
+    {
+        if (_cmap==null)
+            throw new UnsupportedOperationException();
+        return _cmap.remove(key,value);
+    }
+
+    public boolean replace(K key, Object oldValue, Object newValue)
+    {
+        if (_cmap==null)
+            throw new UnsupportedOperationException();
+        return _cmap.replace(key,oldValue,newValue);
+    }
+
+    public Object replace(K key, Object value)
+    {
+        if (_cmap==null)
+            throw new UnsupportedOperationException();
+        return _cmap.replace(key,value);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/MultiPartInputStream.java b/src/java/org/eclipse/jetty/util/MultiPartInputStream.java
new file mode 100644
index 0000000..6aae849
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/MultiPartInputStream.java
@@ -0,0 +1,851 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletException;
+import javax.servlet.http.Part;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+/**
+ * MultiPartInputStream
+ *
+ * Handle a MultiPart Mime input stream, breaking it up on the boundary into files and strings.
+ */
+public class MultiPartInputStream
+{
+    private static final Logger LOG = Log.getLogger(MultiPartInputStream.class);
+
+    public static final MultipartConfigElement  __DEFAULT_MULTIPART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
+    protected InputStream _in;
+    protected MultipartConfigElement _config;
+    protected String _contentType;
+    protected MultiMap<String> _parts;
+    protected File _tmpDir;
+    protected File _contextTmpDir;
+    protected boolean _deleteOnExit;
+    
+    
+    
+    public class MultiPart implements Part
+    {
+        protected String _name;
+        protected String _filename;
+        protected File _file;
+        protected OutputStream _out;
+        protected ByteArrayOutputStream2 _bout;
+        protected String _contentType;
+        protected MultiMap<String> _headers;
+        protected long _size = 0;
+        protected boolean _temporary = true;
+
+        public MultiPart (String name, String filename) 
+        throws IOException
+        {
+            _name = name;
+            _filename = filename;
+        }
+
+        protected void setContentType (String contentType)
+        {
+            _contentType = contentType;
+        }
+        
+        
+        protected void open() 
+        throws IOException
+        {
+            //We will either be writing to a file, if it has a filename on the content-disposition
+            //and otherwise a byte-array-input-stream, OR if we exceed the getFileSizeThreshold, we
+            //will need to change to write to a file.           
+            if (_filename != null && _filename.trim().length() > 0)
+            {
+                createFile();            
+            }
+            else
+            {
+                //Write to a buffer in memory until we discover we've exceed the 
+                //MultipartConfig fileSizeThreshold
+                _out = _bout= new ByteArrayOutputStream2();
+            }
+        }
+        
+        protected void close() 
+        throws IOException
+        {
+            _out.close();
+        }
+        
+      
+        protected void write (int b)
+        throws IOException
+        {      
+            if (MultiPartInputStream.this._config.getMaxFileSize() > 0 && _size + 1 > MultiPartInputStream.this._config.getMaxFileSize())
+                throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize");
+            
+            if (MultiPartInputStream.this._config.getFileSizeThreshold() > 0 && _size + 1 > MultiPartInputStream.this._config.getFileSizeThreshold() && _file==null)
+                createFile();
+            _out.write(b);   
+            _size ++;
+        }
+        
+        protected void write (byte[] bytes, int offset, int length) 
+        throws IOException
+        { 
+            if (MultiPartInputStream.this._config.getMaxFileSize() > 0 && _size + length > MultiPartInputStream.this._config.getMaxFileSize())
+                throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize");
+            
+            if (MultiPartInputStream.this._config.getFileSizeThreshold() > 0 && _size + length > MultiPartInputStream.this._config.getFileSizeThreshold() && _file==null)
+                createFile();
+            
+            _out.write(bytes, offset, length);
+            _size += length;
+        }
+        
+        protected void createFile ()
+        throws IOException
+        {
+            _file = File.createTempFile("MultiPart", "", MultiPartInputStream.this._tmpDir);
+            if (_deleteOnExit)
+                _file.deleteOnExit();
+            FileOutputStream fos = new FileOutputStream(_file);
+            BufferedOutputStream bos = new BufferedOutputStream(fos);
+            
+            if (_size > 0 && _out != null)
+            {
+                //already written some bytes, so need to copy them into the file
+                _out.flush();
+                _bout.writeTo(bos);
+                _out.close();
+                _bout = null;
+            }
+            _out = bos;
+        }
+        
+
+        
+        protected void setHeaders(MultiMap<String> headers)
+        {
+            _headers = headers;
+        }
+        
+        /** 
+         * @see javax.servlet.http.Part#getContentType()
+         */
+        public String getContentType()
+        {
+            return _contentType;
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#getHeader(java.lang.String)
+         */
+        public String getHeader(String name)
+        {
+            if (name == null)
+                return null;
+            return (String)_headers.getValue(name.toLowerCase(Locale.ENGLISH), 0);
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#getHeaderNames()
+         */
+        public Collection<String> getHeaderNames()
+        {
+            return _headers.keySet();
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#getHeaders(java.lang.String)
+         */
+        public Collection<String> getHeaders(String name)
+        {
+           return _headers.getValues(name);
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#getInputStream()
+         */
+        public InputStream getInputStream() throws IOException
+        {
+           if (_file != null)
+           {
+               //written to a file, whether temporary or not
+               return new BufferedInputStream (new FileInputStream(_file));
+           }
+           else
+           {
+               //part content is in memory
+               return new ByteArrayInputStream(_bout.getBuf(),0,_bout.size());
+           }
+        }
+
+        public byte[] getBytes()
+        {
+            if (_bout!=null)
+                return _bout.toByteArray();
+            return null;
+        }
+        
+        /** 
+         * @see javax.servlet.http.Part#getName()
+         */
+        public String getName()
+        {
+           return _name;
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#getSize()
+         */
+        public long getSize()
+        {
+            return _size;         
+        }
+
+        /** 
+         * @see javax.servlet.http.Part#write(java.lang.String)
+         */
+        public void write(String fileName) throws IOException
+        {
+            if (_file == null)
+            {
+                _temporary = false;
+                
+                //part data is only in the ByteArrayOutputStream and never been written to disk
+                _file = new File (_tmpDir, fileName);
+
+                BufferedOutputStream bos = null;
+                try
+                {
+                    bos = new BufferedOutputStream(new FileOutputStream(_file));
+                    _bout.writeTo(bos);
+                    bos.flush();
+                }
+                finally
+                {
+                    if (bos != null)
+                        bos.close();
+                    _bout = null;
+                }
+            }
+            else
+            {
+                //the part data is already written to a temporary file, just rename it
+                _temporary = false;
+                
+                File f = new File(_tmpDir, fileName);
+                if (_file.renameTo(f))
+                    _file = f;
+            }
+        }
+        
+        /** 
+         * Remove the file, whether or not Part.write() was called on it
+         * (ie no longer temporary)
+         * @see javax.servlet.http.Part#delete()
+         */
+        public void delete() throws IOException
+        {
+            if (_file != null && _file.exists())
+                _file.delete();     
+        }
+        
+        /**
+         * Only remove tmp files.
+         * 
+         * @throws IOException
+         */
+        public void cleanUp() throws IOException
+        {
+            if (_temporary && _file != null && _file.exists())
+                _file.delete();
+        }
+        
+        
+        /**
+         * Get the file, if any, the data has been written to.
+         * @return
+         */
+        public File getFile ()
+        {
+            return _file;
+        }  
+        
+        
+        /**
+         * Get the filename from the content-disposition.
+         * @return null or the filename
+         */
+        public String getContentDispositionFilename ()
+        {
+            return _filename;
+        }
+    }
+    
+    
+    
+    
+    /**
+     * @param in Request input stream 
+     * @param contentType Content-Type header
+     * @param config MultipartConfigElement 
+     * @param contextTmpDir javax.servlet.context.tempdir
+     */
+    public MultiPartInputStream (InputStream in, String contentType, MultipartConfigElement config, File contextTmpDir)
+    {
+        _in = new ReadLineInputStream(in);
+       _contentType = contentType;
+       _config = config;
+       _contextTmpDir = contextTmpDir;
+       if (_contextTmpDir == null)
+           _contextTmpDir = new File (System.getProperty("java.io.tmpdir"));
+       
+       if (_config == null)
+           _config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath());
+    }
+
+    /**
+     * Get the already parsed parts.
+     * 
+     * @return
+     */
+    public Collection<Part> getParsedParts()
+    {
+        if (_parts == null)
+            return Collections.emptyList();
+
+        Collection<Object> values = _parts.values();
+        List<Part> parts = new ArrayList<Part>();
+        for (Object o: values)
+        {
+            List<Part> asList = LazyList.getList(o, false);
+            parts.addAll(asList);
+        }
+        return parts;
+    }
+    
+    /**
+     * Delete any tmp storage for parts, and clear out the parts list.
+     * 
+     * @throws MultiException
+     */
+    public void deleteParts ()
+    throws MultiException
+    {
+        Collection<Part> parts = getParsedParts();
+        MultiException err = new MultiException();
+        for (Part p:parts)
+        {
+            try
+            {
+                ((MultiPartInputStream.MultiPart)p).cleanUp();
+            } 
+            catch(Exception e)
+            {     
+                err.add(e); 
+            }
+        }
+        _parts.clear();
+        
+        err.ifExceptionThrowMulti();
+    }
+
+   
+    /**
+     * Parse, if necessary, the multipart data and return the list of Parts.
+     * 
+     * @return
+     * @throws IOException
+     * @throws ServletException
+     */
+    public Collection<Part> getParts()
+    throws IOException, ServletException
+    {
+        parse();
+        Collection<Object> values = _parts.values();
+        List<Part> parts = new ArrayList<Part>();
+        for (Object o: values)
+        {
+            List<Part> asList = LazyList.getList(o, false);
+            parts.addAll(asList);
+        }
+        return parts;
+    }
+    
+    
+    /**
+     * Get the named Part.
+     * 
+     * @param name
+     * @return
+     * @throws IOException
+     * @throws ServletException
+     */
+    public Part getPart(String name)
+    throws IOException, ServletException
+    {
+        parse();
+        return (Part)_parts.getValue(name, 0);
+    }
+    
+    
+    /**
+     * Parse, if necessary, the multipart stream.
+     * 
+     * @throws IOException
+     * @throws ServletException
+     */
+    protected void parse ()
+    throws IOException, ServletException
+    {
+        //have we already parsed the input?
+        if (_parts != null)
+            return;
+        
+        //initialize
+        long total = 0; //keep running total of size of bytes read from input and throw an exception if exceeds MultipartConfigElement._maxRequestSize              
+        _parts = new MultiMap<String>();
+
+        //if its not a multipart request, don't parse it
+        if (_contentType == null || !_contentType.startsWith("multipart/form-data"))
+            return;
+ 
+        //sort out the location to which to write the files
+        
+        if (_config.getLocation() == null)
+            _tmpDir = _contextTmpDir;
+        else if ("".equals(_config.getLocation()))
+            _tmpDir = _contextTmpDir;
+        else
+        {
+            File f = new File (_config.getLocation());
+            if (f.isAbsolute())
+                _tmpDir = f;
+            else
+                _tmpDir = new File (_contextTmpDir, _config.getLocation());
+        }
+      
+        if (!_tmpDir.exists())
+            _tmpDir.mkdirs();
+
+        String contentTypeBoundary = "";
+        int bstart = _contentType.indexOf("boundary=");
+        if (bstart >= 0)
+        {
+            int bend = _contentType.indexOf(";", bstart);
+            bend = (bend < 0? _contentType.length(): bend);
+            contentTypeBoundary = QuotedStringTokenizer.unquote(value(_contentType.substring(bstart,bend), true).trim());
+        }
+        
+        String boundary="--"+contentTypeBoundary;
+        byte[] byteBoundary=(boundary+"--").getBytes(StringUtil.__ISO_8859_1);
+
+        // Get first boundary
+        String line = null;
+        try
+        {
+            line=((ReadLineInputStream)_in).readLine();  
+        }
+        catch (IOException e)
+        {
+            LOG.warn("Badly formatted multipart request");
+            throw e;
+        }
+
+        if (line == null)
+            throw new IOException("Missing content for multipart request");
+
+        boolean badFormatLogged = false;
+        line=line.trim();
+        while (line != null && !line.equals(boundary))
+        {
+            if (!badFormatLogged)
+            {
+                LOG.warn("Badly formatted multipart request");
+                badFormatLogged = true;
+            }
+            line=((ReadLineInputStream)_in).readLine();
+            line=(line==null?line:line.trim());
+        }
+
+        if (line == null)
+            throw new IOException("Missing initial multi part boundary");
+
+        // Read each part
+        boolean lastPart=false;
+
+        outer:while(!lastPart)
+        {
+            String contentDisposition=null;
+            String contentType=null;
+            String contentTransferEncoding=null;
+            
+            MultiMap<String> headers = new MultiMap<String>();
+            while(true)
+            {
+                line=((ReadLineInputStream)_in).readLine();
+                
+                //No more input
+                if(line==null)
+                    break outer;
+
+                // If blank line, end of part headers
+                if("".equals(line))
+                    break;
+                
+                total += line.length();
+                if (_config.getMaxRequestSize() > 0 && total > _config.getMaxRequestSize())
+                    throw new IllegalStateException ("Request exceeds maxRequestSize ("+_config.getMaxRequestSize()+")");
+
+                //get content-disposition and content-type
+                int c=line.indexOf(':',0);
+                if(c>0)
+                {
+                    String key=line.substring(0,c).trim().toLowerCase(Locale.ENGLISH);
+                    String value=line.substring(c+1,line.length()).trim();
+                    headers.put(key, value);
+                    if (key.equalsIgnoreCase("content-disposition"))
+                        contentDisposition=value;
+                    if (key.equalsIgnoreCase("content-type"))
+                        contentType = value;
+                    if(key.equals("content-transfer-encoding"))
+                        contentTransferEncoding=value;
+
+                }
+            }
+
+            // Extract content-disposition
+            boolean form_data=false;
+            if(contentDisposition==null)
+            {
+                throw new IOException("Missing content-disposition");
+            }
+
+            QuotedStringTokenizer tok=new QuotedStringTokenizer(contentDisposition,";", false, true);
+            String name=null;
+            String filename=null;
+            while(tok.hasMoreTokens())
+            {
+                String t=tok.nextToken().trim();
+                String tl=t.toLowerCase(Locale.ENGLISH);
+                if(t.startsWith("form-data"))
+                    form_data=true;
+                else if(tl.startsWith("name="))
+                    name=value(t, true);
+                else if(tl.startsWith("filename="))
+                    filename=filenameValue(t);
+            }
+
+            // Check disposition
+            if(!form_data)
+            {
+                continue;
+            }
+            //It is valid for reset and submit buttons to have an empty name.
+            //If no name is supplied, the browser skips sending the info for that field.
+            //However, if you supply the empty string as the name, the browser sends the
+            //field, with name as the empty string. So, only continue this loop if we
+            //have not yet seen a name field.
+            if(name==null)
+            {
+                continue;
+            }
+
+            //Have a new Part
+            MultiPart part = new MultiPart(name, filename);
+            part.setHeaders(headers);
+            part.setContentType(contentType);
+            _parts.add(name, part);
+            part.open();
+            
+            InputStream partInput = null;
+            if ("base64".equalsIgnoreCase(contentTransferEncoding))
+            {
+                partInput = new Base64InputStream((ReadLineInputStream)_in);
+            }
+            else if ("quoted-printable".equalsIgnoreCase(contentTransferEncoding))
+            {
+                partInput = new FilterInputStream(_in)
+                {
+                    @Override
+                    public int read() throws IOException
+                    {
+                        int c = in.read();
+                        if (c >= 0 && c == '=')
+                        {
+                            int hi = in.read();
+                            int lo = in.read();
+                            if (hi < 0 || lo < 0)
+                            {
+                                throw new IOException("Unexpected end to quoted-printable byte");
+                            }
+                            char[] chars = new char[] { (char)hi, (char)lo };
+                            c = Integer.parseInt(new String(chars),16);
+                        }
+                        return c;
+                    }
+                };
+            }
+            else
+                partInput = _in;
+            
+            try
+            { 
+                int state=-2;
+                int c;
+                boolean cr=false;
+                boolean lf=false;
+
+                // loop for all lines
+                while(true)
+                {
+                    int b=0;
+                    while((c=(state!=-2)?state:partInput.read())!=-1)
+                    {
+                        total ++;
+                        if (_config.getMaxRequestSize() > 0 && total > _config.getMaxRequestSize())
+                            throw new IllegalStateException("Request exceeds maxRequestSize ("+_config.getMaxRequestSize()+")");
+                        
+                        state=-2;
+                        
+                        // look for CR and/or LF
+                        if(c==13||c==10)
+                        {
+                            if(c==13)
+                            {
+                                partInput.mark(1);
+                                int tmp=partInput.read();
+                                if (tmp!=10)
+                                    partInput.reset();
+                                else
+                                    state=tmp;
+                            }
+                            break;
+                        }
+                        
+                        // Look for boundary
+                        if(b>=0&&b<byteBoundary.length&&c==byteBoundary[b])
+                        {
+                            b++;
+                        }
+                        else
+                        {
+                            // Got a character not part of the boundary, so we don't have the boundary marker.
+                            // Write out as many chars as we matched, then the char we're looking at.
+                            if(cr)
+                                part.write(13);
+                    
+                            if(lf)
+                                part.write(10); 
+                            
+                            cr=lf=false;
+                            if(b>0)
+                                part.write(byteBoundary,0,b);
+                              
+                            b=-1;
+                            part.write(c);
+                        }
+                    }
+                    
+                    // Check for incomplete boundary match, writing out the chars we matched along the way
+                    if((b>0&&b<byteBoundary.length-2)||(b==byteBoundary.length-1))
+                    {
+                        if(cr)
+                            part.write(13);
+
+                        if(lf)
+                            part.write(10);
+
+                        cr=lf=false;
+                        part.write(byteBoundary,0,b);
+                        b=-1;
+                    }
+                    
+                    // Boundary match. If we've run out of input or we matched the entire final boundary marker, then this is the last part.
+                    if(b>0||c==-1)
+                    {
+                       
+                        if(b==byteBoundary.length)
+                            lastPart=true;
+                        if(state==10)
+                            state=-2;
+                        break;
+                    }
+                    
+                    // handle CR LF
+                    if(cr)
+                        part.write(13); 
+
+                    if(lf)
+                        part.write(10);
+
+                    cr=(c==13);
+                    lf=(c==10||state==10);
+                    if(state==10)
+                        state=-2;
+                }
+            }
+            finally
+            {
+                part.close();
+            }
+        }
+        if (!lastPart)
+            throw new IOException("Incomplete parts");
+    }
+    
+    public void setDeleteOnExit(boolean deleteOnExit)
+    {
+        _deleteOnExit = deleteOnExit;
+    }
+
+
+    public boolean isDeleteOnExit()
+    {
+        return _deleteOnExit;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private String value(String nameEqualsValue, boolean splitAfterSpace)
+    {
+        /*
+        String value=nameEqualsValue.substring(nameEqualsValue.indexOf('=')+1).trim();
+        int i=value.indexOf(';');
+        if(i>0)
+            value=value.substring(0,i);
+        if(value.startsWith("\""))
+        {
+            value=value.substring(1,value.indexOf('"',1));
+        }
+        else if (splitAfterSpace)
+        {
+            i=value.indexOf(' ');
+            if(i>0)
+                value=value.substring(0,i);
+        }
+        return value;
+        */
+         int idx = nameEqualsValue.indexOf('=');
+         String value = nameEqualsValue.substring(idx+1).trim();
+         return QuotedStringTokenizer.unquoteOnly(value);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private String filenameValue(String nameEqualsValue)
+    {
+        int idx = nameEqualsValue.indexOf('=');
+        String value = nameEqualsValue.substring(idx+1).trim();   
+
+        if (value.matches(".??[a-z,A-Z]\\:\\\\[^\\\\].*"))
+        {
+            //incorrectly escaped IE filenames that have the whole path
+            //we just strip any leading & trailing quotes and leave it as is
+            char first=value.charAt(0);
+            if (first=='"' || first=='\'')
+                value=value.substring(1);
+            char last=value.charAt(value.length()-1);
+            if (last=='"' || last=='\'')
+                value = value.substring(0,value.length()-1);
+
+            return value;
+        }
+        else
+            //unquote the string, but allow any backslashes that don't
+            //form a valid escape sequence to remain as many browsers
+            //even on *nix systems will not escape a filename containing
+            //backslashes
+            return QuotedStringTokenizer.unquoteOnly(value, true);
+    }
+    
+    private static class Base64InputStream extends InputStream
+    {
+        ReadLineInputStream _in;
+        String _line;
+        byte[] _buffer;
+        int _pos;
+
+    
+        public Base64InputStream(ReadLineInputStream rlis)
+        {
+            _in = rlis;
+        }
+
+        @Override
+        public int read() throws IOException
+        {
+            if (_buffer==null || _pos>= _buffer.length)
+            {
+                //Any CR and LF will be consumed by the readLine() call.
+                //We need to put them back into the bytes returned from this
+                //method because the parsing of the multipart content uses them
+                //as markers to determine when we've reached the end of a part.
+                _line = _in.readLine(); 
+                if (_line==null)
+                    return -1;  //nothing left
+                if (_line.startsWith("--"))
+                    _buffer=(_line+"\r\n").getBytes(); //boundary marking end of part
+                else if (_line.length()==0)
+                    _buffer="\r\n".getBytes(); //blank line
+                else
+                {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream((4*_line.length()/3)+2);
+                    B64Code.decode(_line, baos);
+                    baos.write(13);
+                    baos.write(10);
+                    _buffer = baos.toByteArray();
+                }
+
+                _pos=0;
+            }
+            
+            return _buffer[_pos++];
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/MultiPartOutputStream.java b/src/java/org/eclipse/jetty/util/MultiPartOutputStream.java
new file mode 100644
index 0000000..195e01d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/MultiPartOutputStream.java
@@ -0,0 +1,140 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/* ================================================================ */
+/** Handle a multipart MIME response.
+ *
+ * 
+ * 
+*/
+public class MultiPartOutputStream extends FilterOutputStream
+{
+    /* ------------------------------------------------------------ */
+    private static final byte[] __CRLF={'\r','\n'};
+    private static final byte[] __DASHDASH={'-','-'};
+    
+    public static String MULTIPART_MIXED="multipart/mixed";
+    public static String MULTIPART_X_MIXED_REPLACE="multipart/x-mixed-replace";
+    
+    /* ------------------------------------------------------------ */
+    private String boundary;
+    private byte[] boundaryBytes;
+
+    /* ------------------------------------------------------------ */
+    private boolean inPart=false;    
+    
+    /* ------------------------------------------------------------ */
+    public MultiPartOutputStream(OutputStream out)
+    throws IOException
+    {
+        super(out);
+
+        boundary = "jetty"+System.identityHashCode(this)+
+        Long.toString(System.currentTimeMillis(),36);
+        boundaryBytes=boundary.getBytes(StringUtil.__ISO_8859_1);
+
+        inPart=false;
+    }
+
+    
+
+    /* ------------------------------------------------------------ */
+    /** End the current part.
+     * @exception IOException IOException
+     */
+    @Override
+    public void close()
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        out.write(__DASHDASH);
+        out.write(boundaryBytes);
+        out.write(__DASHDASH);
+        out.write(__CRLF);
+        inPart=false;
+        super.close();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getBoundary()
+    {
+        return boundary;
+    }
+
+    public OutputStream getOut() {return out;}
+    
+    /* ------------------------------------------------------------ */
+    /** Start creation of the next Content.
+     */
+    public void startPart(String contentType)
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        inPart=true;
+        out.write(__DASHDASH);
+        out.write(boundaryBytes);
+        out.write(__CRLF);
+        if (contentType != null)
+            out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
+        out.write(__CRLF);
+        out.write(__CRLF);
+    }
+        
+    /* ------------------------------------------------------------ */
+    /** Start creation of the next Content.
+     */
+    public void startPart(String contentType, String[] headers)
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        inPart=true;
+        out.write(__DASHDASH);
+        out.write(boundaryBytes);
+        out.write(__CRLF);
+        if (contentType != null)
+            out.write(("Content-Type: "+contentType).getBytes(StringUtil.__ISO_8859_1));
+        out.write(__CRLF);
+        for (int i=0;headers!=null && i<headers.length;i++)
+        {
+            out.write(headers[i].getBytes(StringUtil.__ISO_8859_1));
+            out.write(__CRLF);
+        }
+        out.write(__CRLF);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException
+    {
+        out.write(b,off,len);
+    }
+}
+
+
+
+
diff --git a/src/java/org/eclipse/jetty/util/MultiPartWriter.java b/src/java/org/eclipse/jetty/util/MultiPartWriter.java
new file mode 100644
index 0000000..753db07
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/MultiPartWriter.java
@@ -0,0 +1,138 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+
+/* ================================================================ */
+/** Handle a multipart MIME response.
+ *
+ * 
+ * 
+*/
+public class MultiPartWriter extends FilterWriter
+{
+    /* ------------------------------------------------------------ */
+    private final static String __CRLF="\015\012";
+    private final static String __DASHDASH="--";
+    
+    public static String MULTIPART_MIXED=MultiPartOutputStream.MULTIPART_MIXED;
+    public static String MULTIPART_X_MIXED_REPLACE=MultiPartOutputStream.MULTIPART_X_MIXED_REPLACE;
+    
+    /* ------------------------------------------------------------ */
+    private String boundary;
+
+    /* ------------------------------------------------------------ */
+    private boolean inPart=false;    
+    
+    /* ------------------------------------------------------------ */
+    public MultiPartWriter(Writer out)
+         throws IOException
+    {
+        super(out);
+        boundary = "jetty"+System.identityHashCode(this)+
+        Long.toString(System.currentTimeMillis(),36);
+        
+        inPart=false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** End the current part.
+     * @exception IOException IOException
+     */
+    @Override
+    public void close()
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        out.write(__DASHDASH);
+        out.write(boundary);
+        out.write(__DASHDASH);
+        out.write(__CRLF);
+        inPart=false;
+        super.close();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getBoundary()
+    {
+        return boundary;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Start creation of the next Content.
+     */
+    public void startPart(String contentType)
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        out.write(__DASHDASH);
+        out.write(boundary);
+        out.write(__CRLF);
+        out.write("Content-Type: ");
+        out.write(contentType);
+        out.write(__CRLF);
+        out.write(__CRLF);
+        inPart=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** end creation of the next Content.
+     */
+    public void endPart()
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        inPart=false;
+    }
+        
+    /* ------------------------------------------------------------ */
+    /** Start creation of the next Content.
+     */
+    public void startPart(String contentType, String[] headers)
+         throws IOException
+    {
+        if (inPart)
+            out.write(__CRLF);
+        out.write(__DASHDASH);
+        out.write(boundary);
+        out.write(__CRLF);
+        out.write("Content-Type: ");
+        out.write(contentType);
+        out.write(__CRLF);
+        for (int i=0;headers!=null && i<headers.length;i++)
+        {
+            out.write(headers[i]);
+            out.write(__CRLF);
+        }
+        out.write(__CRLF);
+        inPart=true;
+    }
+    
+}
+
+
+
+
diff --git a/src/java/org/eclipse/jetty/util/PatternMatcher.java b/src/java/org/eclipse/jetty/util/PatternMatcher.java
new file mode 100644
index 0000000..0afda65
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/PatternMatcher.java
@@ -0,0 +1,104 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public abstract class PatternMatcher
+{
+    public abstract void matched (URI uri) throws Exception;
+    
+    
+    /**
+     * Find jar names from the provided list matching a pattern.
+     * 
+     * If the pattern is null and isNullInclusive is true, then
+     * all jar names will match.
+     * 
+     * A pattern is a set of acceptable jar names. Each acceptable
+     * jar name is a regex. Each regex can be separated by either a
+     * "," or a "|". If you use a "|" this or's together the jar
+     * name patterns. This means that ordering of the matches is
+     * unimportant to you. If instead, you want to match particular
+     * jar names, and you want to match them in order, you should
+     * separate the regexs with "," instead. 
+     * 
+     * Eg "aaa-.*\\.jar|bbb-.*\\.jar"
+     * Will iterate over the jar names and match
+     * in any order.
+     * 
+     * Eg "aaa-*\\.jar,bbb-.*\\.jar"
+     * Will iterate over the jar names, matching
+     * all those starting with "aaa-" first, then "bbb-".
+     *
+     * @param pattern the pattern
+     * @param uris the uris to test the pattern against
+     * @param isNullInclusive if true, an empty pattern means all names match, if false, none match
+     * @throws Exception
+     */
+    public void match (Pattern pattern, URI[] uris, boolean isNullInclusive)
+    throws Exception
+    {
+        if (uris!=null)
+        {
+            String[] patterns = (pattern==null?null:pattern.pattern().split(","));
+
+            List<Pattern> subPatterns = new ArrayList<Pattern>();
+            for (int i=0; patterns!=null && i<patterns.length;i++)
+            {
+                subPatterns.add(Pattern.compile(patterns[i]));
+            }
+            if (subPatterns.isEmpty())
+                subPatterns.add(pattern);
+
+            if (subPatterns.isEmpty())
+            {
+                matchPatterns(null, uris, isNullInclusive);
+            }
+            else
+            {
+                //for each subpattern, iterate over all the urls, processing those that match
+                for (Pattern p : subPatterns)
+                {
+                    matchPatterns(p, uris, isNullInclusive);
+                }
+            }
+        }
+    }
+
+
+    public void matchPatterns (Pattern pattern, URI[] uris, boolean isNullInclusive)
+    throws Exception
+    {
+        for (int i=0; i<uris.length;i++)
+        {
+            URI uri = uris[i];
+            String s = uri.toString();
+            if ((pattern == null && isNullInclusive)
+                    ||
+                    (pattern!=null && pattern.matcher(s).matches()))
+            {
+                matched(uris[i]);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/QuotedStringTokenizer.java b/src/java/org/eclipse/jetty/util/QuotedStringTokenizer.java
new file mode 100644
index 0000000..dc85da1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/QuotedStringTokenizer.java
@@ -0,0 +1,603 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/* ------------------------------------------------------------ */
+/** StringTokenizer with Quoting support.
+ *
+ * This class is a copy of the java.util.StringTokenizer API and
+ * the behaviour is the same, except that single and double quoted
+ * string values are recognised.
+ * Delimiters within quotes are not considered delimiters.
+ * Quotes can be escaped with '\'.
+ *
+ * @see java.util.StringTokenizer
+ *
+ */
+public class QuotedStringTokenizer
+    extends StringTokenizer
+{
+    private final static String __delim="\t\n\r";
+    private String _string;
+    private String _delim = __delim;
+    private boolean _returnQuotes=false;
+    private boolean _returnDelimiters=false;
+    private StringBuffer _token;
+    private boolean _hasToken=false;
+    private int _i=0;
+    private int _lastStart=0;
+    private boolean _double=true;
+    private boolean _single=true;
+
+    /* ------------------------------------------------------------ */
+    public QuotedStringTokenizer(String str,
+                                 String delim,
+                                 boolean returnDelimiters,
+                                 boolean returnQuotes)
+    {
+        super("");
+        _string=str;
+        if (delim!=null)
+            _delim=delim;
+        _returnDelimiters=returnDelimiters;
+        _returnQuotes=returnQuotes;
+
+        if (_delim.indexOf('\'')>=0 ||
+            _delim.indexOf('"')>=0)
+            throw new Error("Can't use quotes as delimiters: "+_delim);
+
+        _token=new StringBuffer(_string.length()>1024?512:_string.length()/2);
+    }
+
+    /* ------------------------------------------------------------ */
+    public QuotedStringTokenizer(String str,
+                                 String delim,
+                                 boolean returnDelimiters)
+    {
+        this(str,delim,returnDelimiters,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    public QuotedStringTokenizer(String str,
+                                 String delim)
+    {
+        this(str,delim,false,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    public QuotedStringTokenizer(String str)
+    {
+        this(str,null,false,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean hasMoreTokens()
+    {
+        // Already found a token
+        if (_hasToken)
+            return true;
+
+        _lastStart=_i;
+
+        int state=0;
+        boolean escape=false;
+        while (_i<_string.length())
+        {
+            char c=_string.charAt(_i++);
+
+            switch (state)
+            {
+              case 0: // Start
+                  if(_delim.indexOf(c)>=0)
+                  {
+                      if (_returnDelimiters)
+                      {
+                          _token.append(c);
+                          return _hasToken=true;
+                      }
+                  }
+                  else if (c=='\'' && _single)
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=2;
+                  }
+                  else if (c=='\"' && _double)
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=3;
+                  }
+                  else
+                  {
+                      _token.append(c);
+                      _hasToken=true;
+                      state=1;
+                  }
+                  break;
+
+              case 1: // Token
+                  _hasToken=true;
+                  if(_delim.indexOf(c)>=0)
+                  {
+                      if (_returnDelimiters)
+                          _i--;
+                      return _hasToken;
+                  }
+                  else if (c=='\'' && _single)
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=2;
+                  }
+                  else if (c=='\"' && _double)
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=3;
+                  }
+                  else
+                  {
+                      _token.append(c);
+                  }
+                  break;
+
+              case 2: // Single Quote
+                  _hasToken=true;
+                  if (escape)
+                  {
+                      escape=false;
+                      _token.append(c);
+                  }
+                  else if (c=='\'')
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=1;
+                  }
+                  else if (c=='\\')
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      escape=true;
+                  }
+                  else
+                  {
+                      _token.append(c);
+                  }
+                  break;
+
+              case 3: // Double Quote
+                  _hasToken=true;
+                  if (escape)
+                  {
+                      escape=false;
+                      _token.append(c);
+                  }
+                  else if (c=='\"')
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      state=1;
+                  }
+                  else if (c=='\\')
+                  {
+                      if (_returnQuotes)
+                          _token.append(c);
+                      escape=true;
+                  }
+                  else
+                  {
+                      _token.append(c);
+                  }
+                  break;
+            }
+        }
+
+        return _hasToken;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String nextToken()
+        throws NoSuchElementException
+    {
+        if (!hasMoreTokens() || _token==null)
+            throw new NoSuchElementException();
+        String t=_token.toString();
+        _token.setLength(0);
+        _hasToken=false;
+        return t;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String nextToken(String delim)
+        throws NoSuchElementException
+    {
+        _delim=delim;
+        _i=_lastStart;
+        _token.setLength(0);
+        _hasToken=false;
+        return nextToken();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean hasMoreElements()
+    {
+        return hasMoreTokens();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public Object nextElement()
+        throws NoSuchElementException
+    {
+        return nextToken();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Not implemented.
+     */
+    @Override
+    public int countTokens()
+    {
+        return -1;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Quote a string.
+     * The string is quoted only if quoting is required due to
+     * embedded delimiters, quote characters or the
+     * empty string.
+     * @param s The string to quote.
+     * @param delim the delimiter to use to quote the string
+     * @return quoted string
+     */
+    public static String quoteIfNeeded(String s, String delim)
+    {
+        if (s==null)
+            return null;
+        if (s.length()==0)
+            return "\"\"";
+
+
+        for (int i=0;i<s.length();i++)
+        {
+            char c = s.charAt(i);
+            if (c=='\\' || c=='"' || c=='\'' || Character.isWhitespace(c) || delim.indexOf(c)>=0)
+            {
+                StringBuffer b=new StringBuffer(s.length()+8);
+                quote(b,s);
+                return b.toString();
+            }
+        }
+
+        return s;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Quote a string.
+     * The string is quoted only if quoting is required due to
+     * embeded delimiters, quote characters or the
+     * empty string.
+     * @param s The string to quote.
+     * @return quoted string
+     */
+    public static String quote(String s)
+    {
+        if (s==null)
+            return null;
+        if (s.length()==0)
+            return "\"\"";
+
+        StringBuffer b=new StringBuffer(s.length()+8);
+        quote(b,s);
+        return b.toString();
+
+    }
+
+    private static final char[] escapes = new char[32];
+    static
+    {
+        Arrays.fill(escapes, (char)0xFFFF);
+        escapes['\b'] = 'b';
+        escapes['\t'] = 't';
+        escapes['\n'] = 'n';
+        escapes['\f'] = 'f';
+        escapes['\r'] = 'r';
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Quote a string into an Appendable.
+     * The characters ", \, \n, \r, \t, \f and \b are escaped
+     * @param buffer The Appendable
+     * @param input The String to quote.
+     */
+    public static void quote(Appendable buffer, String input)
+    {
+        try
+        {
+            buffer.append('"');
+            for (int i = 0; i < input.length(); ++i)
+            {
+                char c = input.charAt(i);
+                if (c >= 32)
+                {
+                    if (c == '"' || c == '\\')
+                        buffer.append('\\');
+                    buffer.append(c);
+                }
+                else
+                {
+                    char escape = escapes[c];
+                    if (escape == 0xFFFF)
+                    {
+                        // Unicode escape
+                        buffer.append('\\').append('u').append('0').append('0');
+                        if (c < 0x10)
+                            buffer.append('0');
+                        buffer.append(Integer.toString(c, 16));
+                    }
+                    else
+                    {
+                        buffer.append('\\').append(escape);
+                    }
+                }
+            }
+            buffer.append('"');
+        }
+        catch (IOException x)
+        {
+            throw new RuntimeException(x);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Quote a string into a StringBuffer only if needed.
+     * Quotes are forced if any delim characters are present.
+     *
+     * @param buf The StringBuffer
+     * @param s The String to quote.
+     * @param delim String of characters that must be quoted.
+     * @return true if quoted;
+     */
+    public static boolean quoteIfNeeded(Appendable buf, String s,String delim)
+    {
+        for (int i=0;i<s.length();i++)
+        {
+            char c = s.charAt(i);
+            if (delim.indexOf(c)>=0)
+            {
+            	quote(buf,s);
+            	return true;
+            }
+        }
+
+        try
+        {
+            buf.append(s);
+            return false;
+        }
+        catch(IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public static String unquoteOnly(String s)
+    {
+        return unquoteOnly(s, false);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Unquote a string, NOT converting unicode sequences
+     * @param s The string to unquote.
+     * @param lenient if true, will leave in backslashes that aren't valid escapes
+     * @return quoted string
+     */
+    public static String unquoteOnly(String s, boolean lenient)
+    {
+        if (s==null)
+            return null;
+        if (s.length()<2)
+            return s;
+
+        char first=s.charAt(0);
+        char last=s.charAt(s.length()-1);
+        if (first!=last || (first!='"' && first!='\''))
+            return s;
+
+        StringBuilder b = new StringBuilder(s.length() - 2);
+        boolean escape=false;
+        for (int i=1;i<s.length()-1;i++)
+        {
+            char c = s.charAt(i);
+
+            if (escape)
+            {
+                escape=false;
+                if (lenient && !isValidEscaping(c))
+                {
+                    b.append('\\');
+                }
+                b.append(c);
+            }
+            else if (c=='\\')
+            {
+                escape=true;
+            }
+            else
+            {
+                b.append(c);
+            }
+        }
+
+        return b.toString(); 
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static String unquote(String s)
+    {
+        return unquote(s,false);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Unquote a string.
+     * @param s The string to unquote.
+     * @return quoted string
+     */
+    public static String unquote(String s, boolean lenient)
+    {
+        if (s==null)
+            return null;
+        if (s.length()<2)
+            return s;
+
+        char first=s.charAt(0);
+        char last=s.charAt(s.length()-1);
+        if (first!=last || (first!='"' && first!='\''))
+            return s;
+
+        StringBuilder b = new StringBuilder(s.length() - 2);
+        boolean escape=false;
+        for (int i=1;i<s.length()-1;i++)
+        {
+            char c = s.charAt(i);
+
+            if (escape)
+            {
+                escape=false;
+                switch (c)
+                {
+                    case 'n':
+                        b.append('\n');
+                        break;
+                    case 'r':
+                        b.append('\r');
+                        break;
+                    case 't':
+                        b.append('\t');
+                        break;
+                    case 'f':
+                        b.append('\f');
+                        break;
+                    case 'b':
+                        b.append('\b');
+                        break;
+                    case '\\':
+                        b.append('\\');
+                        break;
+                    case '/':
+                        b.append('/');
+                        break;
+                    case '"':
+                        b.append('"');
+                        break;
+                    case 'u':
+                        b.append((char)(
+                                (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<24)+
+                                (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<16)+
+                                (TypeUtil.convertHexDigit((byte)s.charAt(i++))<<8)+
+                                (TypeUtil.convertHexDigit((byte)s.charAt(i++)))
+                                )
+                        );
+                        break;
+                    default:
+                        if (lenient && !isValidEscaping(c))
+                        {
+                            b.append('\\');
+                        }
+                        b.append(c);
+                }
+            }
+            else if (c=='\\')
+            {
+                escape=true;
+            }
+            else
+            {
+                b.append(c);
+            }
+        }
+
+        return b.toString();
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Check that char c (which is preceded by a backslash) is a valid
+     * escape sequence.
+     * @param c
+     * @return
+     */
+    private static boolean isValidEscaping(char c)
+    {
+        return ((c == 'n') || (c == 'r') || (c == 't') || 
+                 (c == 'f') || (c == 'b') || (c == '\\') || 
+                 (c == '/') || (c == '"') || (c == 'u'));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return handle double quotes if true
+     */
+    public boolean getDouble()
+    {
+        return _double;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param d handle double quotes if true
+     */
+    public void setDouble(boolean d)
+    {
+        _double=d;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return handle single quotes if true
+     */
+    public boolean getSingle()
+    {
+        return _single;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param single handle single quotes if true
+     */
+    public void setSingle(boolean single)
+    {
+        _single=single;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ReadLineInputStream.java b/src/java/org/eclipse/jetty/util/ReadLineInputStream.java
new file mode 100644
index 0000000..be6abcc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ReadLineInputStream.java
@@ -0,0 +1,136 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * ReadLineInputStream
+ *
+ * Read from an input stream, accepting CR/LF, LF or just CR.
+ */
+public class ReadLineInputStream extends BufferedInputStream
+{
+    boolean _seenCRLF;
+    boolean _skipLF;
+    
+    public ReadLineInputStream(InputStream in)
+    {
+        super(in);
+    }
+
+    public ReadLineInputStream(InputStream in, int size)
+    {
+        super(in,size);
+    }
+    
+    public String readLine() throws IOException
+    {
+        mark(buf.length);
+                
+        while (true)
+        {
+            int b=super.read();
+            
+            if (markpos < 0)
+                throw new IOException("Buffer size exceeded: no line terminator");
+            
+            if (b==-1)
+            {
+                int m=markpos;
+                markpos=-1;
+                if (pos>m)
+                    return new String(buf,m,pos-m,StringUtil.__UTF8_CHARSET);
+
+                return null;
+            }
+            
+            if (b=='\r')
+            {
+                int p=pos;
+                
+                // if we have seen CRLF before, hungrily consume LF
+                if (_seenCRLF && pos<count)
+                {
+                    if (buf[pos]=='\n')
+                        pos+=1;
+                }
+                else
+                    _skipLF=true;
+                int m=markpos;
+                markpos=-1;
+                return new String(buf,m,p-m-1,StringUtil.__UTF8_CHARSET);
+            }
+            
+            if (b=='\n')
+            {
+                if (_skipLF)
+                {
+                    _skipLF=false;
+                    _seenCRLF=true;
+                    markpos++;
+                    continue;
+                }
+                int m=markpos;
+                markpos=-1;
+                return new String(buf,m,pos-m-1,StringUtil.__UTF8_CHARSET);
+            }
+        }
+    }
+
+    @Override
+    public synchronized int read() throws IOException
+    {
+        int b = super.read();
+        if (_skipLF)
+        {
+            _skipLF=false;
+            if (_seenCRLF && b=='\n')
+                b=super.read();
+        }
+        return b;
+    }
+
+    @Override
+    public synchronized int read(byte[] buf, int off, int len) throws IOException
+    {
+        if (_skipLF && len>0)
+        {
+            _skipLF=false;
+            if (_seenCRLF)
+            {
+                int b = super.read();
+                if (b==-1)
+                    return -1;
+                
+                if (b!='\n')
+                {
+                    buf[off]=(byte)(0xff&b);
+                    return 1+super.read(buf,off+1,len-1);
+                }
+            }
+        }
+        
+        return super.read(buf,off,len);
+    }
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/util/RolloverFileOutputStream.java b/src/java/org/eclipse/jetty/util/RolloverFileOutputStream.java
new file mode 100644
index 0000000..60f5da4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/RolloverFileOutputStream.java
@@ -0,0 +1,340 @@
+//
+//  ========================================================================
+//  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.util; 
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/** 
+ * RolloverFileOutputStream
+ * 
+ * This output stream puts content in a file that is rolled over every 24 hours.
+ * The filename must include the string "yyyy_mm_dd", which is replaced with the 
+ * actual date when creating and rolling over the file.
+ * 
+ * Old files are retained for a number of days before being deleted.
+ * 
+ * 
+ */
+public class RolloverFileOutputStream extends FilterOutputStream
+{
+    private static Timer __rollover;
+    
+    final static String YYYY_MM_DD="yyyy_mm_dd";
+    final static String ROLLOVER_FILE_DATE_FORMAT = "yyyy_MM_dd";
+    final static String ROLLOVER_FILE_BACKUP_FORMAT = "HHmmssSSS";
+    final static int ROLLOVER_FILE_RETAIN_DAYS = 31;
+
+    private RollTask _rollTask;
+    private SimpleDateFormat _fileBackupFormat;
+    private SimpleDateFormat _fileDateFormat;
+
+    private String _filename;
+    private File _file;
+    private boolean _append;
+    private int _retainDays;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filename The filename must include the string "yyyy_mm_dd", 
+     * which is replaced with the actual date when creating and rolling over the file.
+     * @throws IOException
+     */
+    public RolloverFileOutputStream(String filename)
+        throws IOException
+    {
+        this(filename,true,ROLLOVER_FILE_RETAIN_DAYS);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filename The filename must include the string "yyyy_mm_dd", 
+     * which is replaced with the actual date when creating and rolling over the file.
+     * @param append If true, existing files will be appended to.
+     * @throws IOException
+     */
+    public RolloverFileOutputStream(String filename, boolean append)
+        throws IOException
+    {
+        this(filename,append,ROLLOVER_FILE_RETAIN_DAYS);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filename The filename must include the string "yyyy_mm_dd", 
+     * which is replaced with the actual date when creating and rolling over the file.
+     * @param append If true, existing files will be appended to.
+     * @param retainDays The number of days to retain files before deleting them.  0 to retain forever.
+     * @throws IOException
+     */
+    public RolloverFileOutputStream(String filename,
+                                    boolean append,
+                                    int retainDays)
+        throws IOException
+    {
+        this(filename,append,retainDays,TimeZone.getDefault());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filename The filename must include the string "yyyy_mm_dd", 
+     * which is replaced with the actual date when creating and rolling over the file.
+     * @param append If true, existing files will be appended to.
+     * @param retainDays The number of days to retain files before deleting them. 0 to retain forever.
+     * @throws IOException
+     */
+    public RolloverFileOutputStream(String filename,
+                                    boolean append,
+                                    int retainDays,
+                                    TimeZone zone)
+        throws IOException
+    {
+
+         this(filename,append,retainDays,zone,null,null);
+    }
+     
+    /* ------------------------------------------------------------ */
+    /**
+     * @param filename The filename must include the string "yyyy_mm_dd", 
+     * which is replaced with the actual date when creating and rolling over the file.
+     * @param append If true, existing files will be appended to.
+     * @param retainDays The number of days to retain files before deleting them. 0 to retain forever.
+     * @param dateFormat The format for the date file substitution. The default is "yyyy_MM_dd". 
+     * @param backupFormat The format for the file extension of backup files. The default is "HHmmssSSS". 
+     * @throws IOException
+     */
+    public RolloverFileOutputStream(String filename,
+                                    boolean append,
+                                    int retainDays,
+                                    TimeZone zone,
+                                    String dateFormat,
+                                    String backupFormat)
+        throws IOException
+    {
+        super(null);
+
+        if (dateFormat==null)
+            dateFormat=ROLLOVER_FILE_DATE_FORMAT;
+        _fileDateFormat = new SimpleDateFormat(dateFormat);
+        
+        if (backupFormat==null)
+            backupFormat=ROLLOVER_FILE_BACKUP_FORMAT;
+        _fileBackupFormat = new SimpleDateFormat(backupFormat);
+        
+        _fileBackupFormat.setTimeZone(zone);
+        _fileDateFormat.setTimeZone(zone);
+        
+        if (filename!=null)
+        {
+            filename=filename.trim();
+            if (filename.length()==0)
+                filename=null;
+        }
+        if (filename==null)
+            throw new IllegalArgumentException("Invalid filename");
+
+        _filename=filename;
+        _append=append;
+        _retainDays=retainDays;
+        setFile();
+        
+        synchronized(RolloverFileOutputStream.class)
+        {
+            if (__rollover==null)
+                __rollover=new Timer(RolloverFileOutputStream.class.getName(),true);
+            
+            _rollTask=new RollTask();
+
+             Calendar now = Calendar.getInstance();
+             now.setTimeZone(zone);
+
+             GregorianCalendar midnight =
+                 new GregorianCalendar(now.get(Calendar.YEAR),
+                         now.get(Calendar.MONTH),
+                         now.get(Calendar.DAY_OF_MONTH),
+                         23,0);
+             midnight.setTimeZone(zone);
+             midnight.add(Calendar.HOUR,1);
+             __rollover.scheduleAtFixedRate(_rollTask,midnight.getTime(),1000L*60*60*24);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getFilename()
+    {
+        return _filename;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String getDatedFilename()
+    {
+        if (_file==null)
+            return null;
+        return _file.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int getRetainDays()
+    {
+        return _retainDays;
+    }
+
+    /* ------------------------------------------------------------ */
+    private synchronized void setFile()
+        throws IOException
+    {
+        // Check directory
+        File file = new File(_filename);
+        _filename=file.getCanonicalPath();
+        file=new File(_filename);
+        File dir= new File(file.getParent());
+        if (!dir.isDirectory() || !dir.canWrite())
+            throw new IOException("Cannot write log directory "+dir);
+            
+        Date now=new Date();
+        
+        // Is this a rollover file?
+        String filename=file.getName();
+        int i=filename.toLowerCase(Locale.ENGLISH).indexOf(YYYY_MM_DD);
+        if (i>=0)
+        {
+            file=new File(dir,
+                          filename.substring(0,i)+
+                          _fileDateFormat.format(now)+
+                          filename.substring(i+YYYY_MM_DD.length()));
+        }
+            
+        if (file.exists()&&!file.canWrite())
+            throw new IOException("Cannot write log file "+file);
+
+        // Do we need to change the output stream?
+        if (out==null || !file.equals(_file))
+        {
+            // Yep
+            _file=file;
+            if (!_append && file.exists())
+                file.renameTo(new File(file.toString()+"."+_fileBackupFormat.format(now)));
+            OutputStream oldOut=out;
+            out=new FileOutputStream(file.toString(),_append);
+            if (oldOut!=null)
+                oldOut.close();
+            //if(log.isDebugEnabled())log.debug("Opened "+_file);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void removeOldFiles()
+    {
+        if (_retainDays>0)
+        {
+            long now = System.currentTimeMillis();
+            
+            File file= new File(_filename);
+            File dir = new File(file.getParent());
+            String fn=file.getName();
+            int s=fn.toLowerCase(Locale.ENGLISH).indexOf(YYYY_MM_DD);
+            if (s<0)
+                return;
+            String prefix=fn.substring(0,s);
+            String suffix=fn.substring(s+YYYY_MM_DD.length());
+
+            String[] logList=dir.list();
+            for (int i=0;i<logList.length;i++)
+            {
+                fn = logList[i];
+                if(fn.startsWith(prefix)&&fn.indexOf(suffix,prefix.length())>=0)
+                {        
+                    File f = new File(dir,fn);
+                    long date = f.lastModified();
+                    if ( ((now-date)/(1000*60*60*24))>_retainDays)
+                        f.delete();   
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write (byte[] buf)
+            throws IOException
+     {
+            out.write (buf);
+     }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write (byte[] buf, int off, int len)
+            throws IOException
+     {
+            out.write (buf, off, len);
+     }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     */
+    @Override
+    public void close()
+        throws IOException
+    {
+        synchronized(RolloverFileOutputStream.class)
+        {
+            try{super.close();}
+            finally
+            {
+                out=null;
+                _file=null;
+            }
+
+            _rollTask.cancel(); 
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class RollTask extends TimerTask
+    {
+        @Override
+        public void run()
+        {
+            try
+            {
+                RolloverFileOutputStream.this.setFile();
+                RolloverFileOutputStream.this.removeOldFiles();
+
+            }
+            catch(IOException e)
+            {
+                // Cannot log this exception to a LOG, as RolloverFOS can be used by logging
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Scanner.java b/src/java/org/eclipse/jetty/util/Scanner.java
new file mode 100644
index 0000000..cc92ae6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Scanner.java
@@ -0,0 +1,746 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/**
+ * Scanner
+ * 
+ * Utility for scanning a directory for added, removed and changed
+ * files and reporting these events via registered Listeners.
+ *
+ */
+public class Scanner extends AbstractLifeCycle
+{
+    private static final Logger LOG = Log.getLogger(Scanner.class);
+    private static int __scannerId=0;
+    private int _scanInterval;
+    private int _scanCount = 0;
+    private final List<Listener> _listeners = new ArrayList<Listener>();
+    private final Map<String,TimeNSize> _prevScan = new HashMap<String,TimeNSize> ();
+    private final Map<String,TimeNSize> _currentScan = new HashMap<String,TimeNSize> ();
+    private FilenameFilter _filter;
+    private final List<File> _scanDirs = new ArrayList<File>();
+    private volatile boolean _running = false;
+    private boolean _reportExisting = true;
+    private boolean _reportDirs = true;
+    private Timer _timer;
+    private TimerTask _task;
+    private int _scanDepth=0;
+    
+    public enum Notification { ADDED, CHANGED, REMOVED };
+    private final Map<String,Notification> _notifications = new HashMap<String,Notification>();
+
+    static class TimeNSize
+    {
+        final long _lastModified;
+        final long _size;
+        
+        public TimeNSize(long lastModified, long size)
+        {
+            _lastModified = lastModified;
+            _size = size;
+        }
+        
+        @Override
+        public int hashCode()
+        {
+            return (int)_lastModified^(int)_size;
+        }
+        
+        @Override
+        public boolean equals(Object o)
+        {
+            if (o instanceof TimeNSize)
+            {
+                TimeNSize tns = (TimeNSize)o;
+                return tns._lastModified==_lastModified && tns._size==_size;
+            }
+            return false;
+        }
+        
+        @Override
+        public String toString()
+        {
+            return "[lm="+_lastModified+",s="+_size+"]";
+        }
+    }
+    
+    /**
+     * Listener
+     * 
+     * Marker for notifications re file changes.
+     */
+    public interface Listener
+    {
+    }
+
+    public interface ScanListener extends Listener
+    {
+        public void scan();
+    }
+    
+    public interface DiscreteListener extends Listener
+    {
+        public void fileChanged (String filename) throws Exception;
+        public void fileAdded (String filename) throws Exception;
+        public void fileRemoved (String filename) throws Exception;
+    }
+    
+    
+    public interface BulkListener extends Listener
+    {
+        public void filesChanged (List<String> filenames) throws Exception;
+    }
+
+    /**
+     * Listener that notifies when a scan has started and when it has ended.
+     */
+    public interface ScanCycleListener extends Listener
+    {
+        public void scanStarted(int cycle) throws Exception;
+        public void scanEnded(int cycle) throws Exception;
+    }
+
+    /**
+     * 
+     */
+    public Scanner ()
+    {       
+    }
+
+    /**
+     * Get the scan interval
+     * @return interval between scans in seconds
+     */
+    public int getScanInterval()
+    {
+        return _scanInterval;
+    }
+
+    /**
+     * Set the scan interval
+     * @param scanInterval pause between scans in seconds, or 0 for no scan after the initial scan.
+     */
+    public synchronized void setScanInterval(int scanInterval)
+    {
+        _scanInterval = scanInterval;
+        schedule();
+    }
+
+    /**
+     * Set the location of the directory to scan.
+     * @param dir
+     * @deprecated use setScanDirs(List dirs) instead
+     */
+    @Deprecated
+    public void setScanDir (File dir)
+    {
+        _scanDirs.clear(); 
+        _scanDirs.add(dir);
+    }
+
+    /**
+     * Get the location of the directory to scan
+     * @return the first directory (of {@link #getScanDirs()} being scanned)
+     * @deprecated use getScanDirs() instead
+     */
+    @Deprecated
+    public File getScanDir ()
+    {
+        return (_scanDirs==null?null:(File)_scanDirs.get(0));
+    }
+
+    public void setScanDirs (List<File> dirs)
+    {
+        _scanDirs.clear(); 
+        _scanDirs.addAll(dirs);
+    }
+    
+    public synchronized void addScanDir( File dir )
+    {
+        _scanDirs.add( dir );
+    }
+    
+    public List<File> getScanDirs ()
+    {
+        return Collections.unmodifiableList(_scanDirs);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param recursive True if scanning is recursive
+     * @see  #setScanDepth(int)
+     */
+    public void setRecursive (boolean recursive)
+    {
+        _scanDepth=recursive?-1:0;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if scanning is fully recursive (scandepth==-1)
+     * @see #getScanDepth()
+     */
+    public boolean getRecursive ()
+    {
+        return _scanDepth==-1;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the scanDepth.
+     * @return the scanDepth
+     */
+    public int getScanDepth()
+    {
+        return _scanDepth;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the scanDepth.
+     * @param scanDepth the scanDepth to set
+     */
+    public void setScanDepth(int scanDepth)
+    {
+        _scanDepth = scanDepth;
+    }
+
+    /**
+     * Apply a filter to files found in the scan directory.
+     * Only files matching the filter will be reported as added/changed/removed.
+     * @param filter
+     */
+    public void setFilenameFilter (FilenameFilter filter)
+    {
+        _filter = filter;
+    }
+
+    /**
+     * Get any filter applied to files in the scan dir.
+     * @return the filename filter
+     */
+    public FilenameFilter getFilenameFilter ()
+    {
+        return _filter;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Whether or not an initial scan will report all files as being
+     * added.
+     * @param reportExisting if true, all files found on initial scan will be 
+     * reported as being added, otherwise not
+     */
+    public void setReportExistingFilesOnStartup (boolean reportExisting)
+    {
+        _reportExisting = reportExisting;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getReportExistingFilesOnStartup()
+    {
+        return _reportExisting;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set if found directories should be reported.
+     * @param dirs
+     */
+    public void setReportDirs(boolean dirs)
+    {
+        _reportDirs=dirs;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean getReportDirs()
+    {
+        return _reportDirs;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Add an added/removed/changed listener
+     * @param listener
+     */
+    public synchronized void addListener (Listener listener)
+    {
+        if (listener == null)
+            return;
+        _listeners.add(listener);   
+    }
+
+
+
+    /**
+     * Remove a registered listener
+     * @param listener the Listener to be removed
+     */
+    public synchronized void removeListener (Listener listener)
+    {
+        if (listener == null)
+            return;
+        _listeners.remove(listener);    
+    }
+
+
+    /**
+     * Start the scanning action.
+     */
+    @Override
+    public synchronized void doStart()
+    {
+        if (_running)
+            return;
+
+        _running = true;
+
+        if (_reportExisting)
+        {
+            // if files exist at startup, report them
+            scan();
+            scan(); // scan twice so files reported as stable
+        }
+        else
+        {
+            //just register the list of existing files and only report changes
+            scanFiles();
+            _prevScan.putAll(_currentScan);
+        }
+        schedule();
+    }
+
+    public TimerTask newTimerTask ()
+    {
+        return new TimerTask()
+        {
+            @Override
+            public void run() { scan(); }
+        };
+    }
+
+    public Timer newTimer ()
+    {
+        return new Timer("Scanner-"+__scannerId++, true);
+    }
+    
+    public void schedule ()
+    {  
+        if (_running)
+        {
+            if (_timer!=null)
+                _timer.cancel();
+            if (_task!=null)
+                _task.cancel();
+            if (getScanInterval() > 0)
+            {
+                _timer = newTimer();
+                _task = newTimerTask();
+                _timer.schedule(_task, 1010L*getScanInterval(),1010L*getScanInterval());
+            }
+        }
+    }
+    /**
+     * Stop the scanning.
+     */
+    @Override
+    public synchronized void doStop()
+    {
+        if (_running)
+        {
+            _running = false; 
+            if (_timer!=null)
+                _timer.cancel();
+            if (_task!=null)
+                _task.cancel();
+            _task=null;
+            _timer=null;
+        }
+    }
+
+    /**
+     * Perform a pass of the scanner and report changes
+     */
+    public synchronized void scan ()
+    {
+        reportScanStart(++_scanCount);
+        scanFiles();
+        reportDifferences(_currentScan, _prevScan);
+        _prevScan.clear();
+        _prevScan.putAll(_currentScan);
+        reportScanEnd(_scanCount);
+        
+        for (Listener l : _listeners)
+        {
+            try
+            {
+                if (l instanceof ScanListener)
+                    ((ScanListener)l).scan();
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+            }
+            catch (Error e)
+            {
+                LOG.warn(e);
+            }
+        }
+    }
+
+    /**
+     * Recursively scan all files in the designated directories.
+     */
+    public synchronized void scanFiles ()
+    {
+        if (_scanDirs==null)
+            return;
+        
+        _currentScan.clear();
+        Iterator<File> itor = _scanDirs.iterator();
+        while (itor.hasNext())
+        {
+            File dir = itor.next();
+            
+            if ((dir != null) && (dir.exists()))
+                try
+                {
+                    scanFile(dir.getCanonicalFile(), _currentScan,0);
+                }
+                catch (IOException e)
+                {
+                    LOG.warn("Error scanning files.", e);
+                }
+        }
+    }
+
+
+    /**
+     * Report the adds/changes/removes to the registered listeners
+     * 
+     * @param currentScan the info from the most recent pass
+     * @param oldScan info from the previous pass
+     */
+    public synchronized void reportDifferences (Map<String,TimeNSize> currentScan, Map<String,TimeNSize> oldScan) 
+    {
+        // scan the differences and add what was found to the map of notifications:
+
+        Set<String> oldScanKeys = new HashSet<String>(oldScan.keySet());
+        
+        // Look for new and changed files
+        for (Map.Entry<String, TimeNSize> entry: currentScan.entrySet())
+        {
+            String file = entry.getKey(); 
+            if (!oldScanKeys.contains(file))
+            {
+                Notification old=_notifications.put(file,Notification.ADDED);
+                if (old!=null)
+                { 
+                    switch(old)
+                    {
+                        case REMOVED: 
+                        case CHANGED:
+                            _notifications.put(file,Notification.CHANGED);
+                    }
+                }
+            }
+            else if (!oldScan.get(file).equals(currentScan.get(file)))
+            {
+                Notification old=_notifications.put(file,Notification.CHANGED);
+                if (old!=null)
+                {
+                    switch(old)
+                    {
+                        case ADDED:
+                            _notifications.put(file,Notification.ADDED);
+                    }
+                }
+            }
+        }
+        
+        // Look for deleted files
+        for (String file : oldScan.keySet())
+        {
+            if (!currentScan.containsKey(file))
+            {
+                Notification old=_notifications.put(file,Notification.REMOVED);
+                if (old!=null)
+                {
+                    switch(old)
+                    {
+                        case ADDED:
+                            _notifications.remove(file);
+                    }
+                }
+            }
+        }
+        
+        if (LOG.isDebugEnabled())
+            LOG.debug("scanned "+_scanDirs+": "+_notifications);
+                
+        // Process notifications
+        // Only process notifications that are for stable files (ie same in old and current scan).
+        List<String> bulkChanges = new ArrayList<String>();
+        for (Iterator<Entry<String,Notification>> iter = _notifications.entrySet().iterator();iter.hasNext();)
+        {
+            Entry<String,Notification> entry=iter.next();
+            String file=entry.getKey();
+            
+            // Is the file stable?
+            if (oldScan.containsKey(file))
+            {
+                if (!oldScan.get(file).equals(currentScan.get(file)))
+                    continue;
+            }
+            else if (currentScan.containsKey(file))
+                continue;
+                            
+            // File is stable so notify
+            Notification notification=entry.getValue();
+            iter.remove();
+            bulkChanges.add(file);
+            switch(notification)
+            {
+                case ADDED:
+                    reportAddition(file);
+                    break;
+                case CHANGED:
+                    reportChange(file);
+                    break;
+                case REMOVED:
+                    reportRemoval(file);
+                    break;
+            }
+        }
+        if (!bulkChanges.isEmpty())
+            reportBulkChanges(bulkChanges);
+    }
+
+
+    /**
+     * Get last modified time on a single file or recurse if
+     * the file is a directory. 
+     * @param f file or directory
+     * @param scanInfoMap map of filenames to last modified times
+     */
+    private void scanFile (File f, Map<String,TimeNSize> scanInfoMap, int depth)
+    {
+        try
+        {
+            if (!f.exists())
+                return;
+
+            if (f.isFile() || depth>0&& _reportDirs && f.isDirectory())
+            {
+                if ((_filter == null) || ((_filter != null) && _filter.accept(f.getParentFile(), f.getName())))
+                {
+                    String name = f.getCanonicalPath();
+                    scanInfoMap.put(name, new TimeNSize(f.lastModified(),f.length()));
+                }
+            }
+            
+            // If it is a directory, scan if it is a known directory or the depth is OK.
+            if (f.isDirectory() && (depth<_scanDepth || _scanDepth==-1 || _scanDirs.contains(f)))
+            {
+                File[] files = f.listFiles();
+                if (files != null)
+                {
+                    for (int i=0;i<files.length;i++)
+                        scanFile(files[i], scanInfoMap,depth+1);
+                }
+                else
+                    LOG.warn("Error listing files in directory {}", f);
+                    
+            }
+        }
+        catch (IOException e)
+        {
+            LOG.warn("Error scanning watched files", e);
+        }
+    }
+
+    private void warn(Object listener,String filename,Throwable th)
+    {
+        LOG.warn(listener+" failed on '"+filename, th);
+    }
+
+    /**
+     * Report a file addition to the registered FileAddedListeners
+     * @param filename
+     */
+    private void reportAddition (String filename)
+    {
+        Iterator<Listener> itor = _listeners.iterator();
+        while (itor.hasNext())
+        {
+            Listener l = itor.next();
+            try
+            {
+                if (l instanceof DiscreteListener)
+                    ((DiscreteListener)l).fileAdded(filename);
+            }
+            catch (Exception e)
+            {
+                warn(l,filename,e);
+            }
+            catch (Error e)
+            {
+                warn(l,filename,e);
+            }
+        }
+    }
+
+
+    /**
+     * Report a file removal to the FileRemovedListeners
+     * @param filename
+     */
+    private void reportRemoval (String filename)
+    {
+        Iterator<Listener> itor = _listeners.iterator();
+        while (itor.hasNext())
+        {
+            Object l = itor.next();
+            try
+            {
+                if (l instanceof DiscreteListener)
+                    ((DiscreteListener)l).fileRemoved(filename);
+            }
+            catch (Exception e)
+            {
+                warn(l,filename,e);
+            }
+            catch (Error e)
+            {
+                warn(l,filename,e);
+            }
+        }
+    }
+
+
+    /**
+     * Report a file change to the FileChangedListeners
+     * @param filename
+     */
+    private void reportChange (String filename)
+    {
+        Iterator<Listener> itor = _listeners.iterator();
+        while (itor.hasNext())
+        {
+            Listener l = itor.next();
+            try
+            {
+                if (l instanceof DiscreteListener)
+                    ((DiscreteListener)l).fileChanged(filename);
+            }
+            catch (Exception e)
+            {
+                warn(l,filename,e);
+            }
+            catch (Error e)
+            {
+                warn(l,filename,e);
+            }
+        }
+    }
+    
+    private void reportBulkChanges (List<String> filenames)
+    {
+        Iterator<Listener> itor = _listeners.iterator();
+        while (itor.hasNext())
+        {
+            Listener l = itor.next();
+            try
+            {
+                if (l instanceof BulkListener)
+                    ((BulkListener)l).filesChanged(filenames);
+            }
+            catch (Exception e)
+            {
+                warn(l,filenames.toString(),e);
+            }
+            catch (Error e)
+            {
+                warn(l,filenames.toString(),e);
+            }
+        }
+    }
+    
+    /**
+     * signal any scan cycle listeners that a scan has started
+     */
+    private void reportScanStart(int cycle)
+    {
+        for (Listener listener : _listeners)
+        {
+            try
+            {
+                if (listener instanceof ScanCycleListener)
+                {
+                    ((ScanCycleListener)listener).scanStarted(cycle);
+                }
+            }
+            catch (Exception e)
+            {
+                LOG.warn(listener + " failed on scan start for cycle " + cycle, e);
+            }
+        }
+    }
+
+    /**
+     * sign
+     */
+    private void reportScanEnd(int cycle)
+    {
+        for (Listener listener : _listeners)
+        {
+            try
+            {
+                if (listener instanceof ScanCycleListener)
+                {
+                    ((ScanCycleListener)listener).scanEnded(cycle);
+                }
+            }
+            catch (Exception e)
+            {
+                LOG.warn(listener + " failed on scan end for cycle " + cycle, e);
+            }
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/StringMap.java b/src/java/org/eclipse/jetty/util/StringMap.java
new file mode 100644
index 0000000..bf84b23
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/StringMap.java
@@ -0,0 +1,695 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.Externalizable;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/* ------------------------------------------------------------ */
+/** Map implementation Optimized for Strings keys..
+ * This String Map has been optimized for mapping small sets of
+ * Strings where the most frequently accessed Strings have been put to
+ * the map first.
+ *
+ * It also has the benefit that it can look up entries by substring or
+ * sections of char and byte arrays.  This can prevent many String
+ * objects from being created just to look up in the map.
+ *
+ * This map is NOT synchronized.
+ */
+public class StringMap extends AbstractMap implements Externalizable
+{
+    public static final boolean CASE_INSENSTIVE=true;
+    protected static final int __HASH_WIDTH=17;
+    
+    /* ------------------------------------------------------------ */
+    protected int _width=__HASH_WIDTH;
+    protected Node _root=new Node();
+    protected boolean _ignoreCase=false;
+    protected NullEntry _nullEntry=null;
+    protected Object _nullValue=null;
+    protected HashSet _entrySet=new HashSet(3);
+    protected Set _umEntrySet=Collections.unmodifiableSet(_entrySet);
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     */
+    public StringMap()
+    {}
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param ignoreCase 
+     */
+    public StringMap(boolean ignoreCase)
+    {
+        this();
+        _ignoreCase=ignoreCase;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param ignoreCase 
+     * @param width Width of hash tables, larger values are faster but
+     * use more memory.
+     */
+    public StringMap(boolean ignoreCase,int width)
+    {
+        this();
+        _ignoreCase=ignoreCase;
+        _width=width;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the ignoreCase attribute.
+     * @param ic If true, the map is case insensitive for keys.
+     */
+    public void setIgnoreCase(boolean ic)
+    {
+        if (_root._children!=null)
+            throw new IllegalStateException("Must be set before first put");
+        _ignoreCase=ic;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIgnoreCase()
+    {
+        return _ignoreCase;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the hash width.
+     * @param width Width of hash tables, larger values are faster but
+     * use more memory.
+     */
+    public void setWidth(int width)
+    {
+        _width=width;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getWidth()
+    {
+        return _width;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public Object put(Object key, Object value)
+    {
+        if (key==null)
+            return put(null,value);
+        return put(key.toString(),value);
+    }
+        
+    /* ------------------------------------------------------------ */
+    public Object put(String key, Object value)
+    {
+        if (key==null)
+        {
+            Object oldValue=_nullValue;
+            _nullValue=value;
+            if (_nullEntry==null)
+            {   
+                _nullEntry=new NullEntry();
+                _entrySet.add(_nullEntry);
+            }
+            return oldValue;
+        }
+        
+        Node node = _root;
+        int ni=-1;
+        Node prev = null;
+        Node parent = null;
+
+        // look for best match
+    charLoop:
+        for (int i=0;i<key.length();i++)
+        {
+            char c=key.charAt(i);
+            
+            // Advance node
+            if (ni==-1)
+            {
+                parent=node;
+                prev=null;
+                ni=0;
+                node=(node._children==null)?null:node._children[c%_width];
+            }
+            
+            // Loop through a node chain at the same level
+            while (node!=null) 
+            {
+                // If it is a matching node, goto next char
+                if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c)
+                {
+                    prev=null;
+                    ni++;
+                    if (ni==node._char.length)
+                        ni=-1;
+                    continue charLoop;
+                }
+
+                // no char match
+                // if the first char,
+                if (ni==0)
+                {
+                    // look along the chain for a char match
+                    prev=node;
+                    node=node._next;
+                }
+                else
+                {
+                    // Split the current node!
+                    node.split(this,ni);
+                    i--;
+                    ni=-1;
+                    continue charLoop;
+                }
+            }
+
+            // We have run out of nodes, so as this is a put, make one
+            node = new Node(_ignoreCase,key,i);
+
+            if (prev!=null) // add to end of chain
+                prev._next=node;
+            else if (parent!=null) // add new child
+            {
+                if (parent._children==null)
+                    parent._children=new Node[_width];
+                parent._children[c%_width]=node;
+                int oi=node._ochar[0]%_width;
+                if (node._ochar!=null && node._char[0]%_width!=oi)
+                {
+                    if (parent._children[oi]==null)
+                        parent._children[oi]=node;
+                    else
+                    {
+                        Node n=parent._children[oi];
+                        while(n._next!=null)
+                            n=n._next;
+                        n._next=node;
+                    }
+                }
+            }
+            else // this is the root.
+                _root=node;
+            break;
+        }
+        
+        // Do we have a node
+        if (node!=null)
+        {
+            // Split it if we are in the middle
+            if(ni>0)
+                node.split(this,ni);
+        
+            Object old = node._value;
+            node._key=key;
+            node._value=value;
+            _entrySet.add(node);
+            return old;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public Object get(Object key)
+    {
+        if (key==null)
+            return _nullValue;
+        if (key instanceof String)
+            return get((String)key);
+        return get(key.toString());
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Object get(String key)
+    {
+        if (key==null)
+            return _nullValue;
+        
+        Map.Entry entry = getEntry(key,0,key.length());
+        if (entry==null)
+            return null;
+        return entry.getValue();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get a map entry by substring key.
+     * @param key String containing the key
+     * @param offset Offset of the key within the String.
+     * @param length The length of the key 
+     * @return The Map.Entry for the key or null if the key is not in
+     * the map.
+     */
+    public Map.Entry getEntry(String key,int offset, int length)
+    {
+        if (key==null)
+            return _nullEntry;
+        
+        Node node = _root;
+        int ni=-1;
+
+        // look for best match
+    charLoop:
+        for (int i=0;i<length;i++)
+        {
+            char c=key.charAt(offset+i);
+
+            // Advance node
+            if (ni==-1)
+            {
+                ni=0;
+                node=(node._children==null)?null:node._children[c%_width];
+            }
+            
+            // Look through the node chain
+            while (node!=null) 
+            {
+                // If it is a matching node, goto next char
+                if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c)
+                {
+                    ni++;
+                    if (ni==node._char.length)
+                        ni=-1;
+                    continue charLoop;
+                }
+
+                // No char match, so if mid node then no match at all.
+                if (ni>0) return null;
+
+                // try next in chain
+                node=node._next;                
+            }
+            return null;
+        }
+        
+        if (ni>0) return null;
+        if (node!=null && node._key==null)
+            return null;
+        return node;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get a map entry by char array key.
+     * @param key char array containing the key
+     * @param offset Offset of the key within the array.
+     * @param length The length of the key 
+     * @return The Map.Entry for the key or null if the key is not in
+     * the map.
+     */
+    public Map.Entry getEntry(char[] key,int offset, int length)
+    {
+        if (key==null)
+            return _nullEntry;
+        
+        Node node = _root;
+        int ni=-1;
+
+        // look for best match
+    charLoop:
+        for (int i=0;i<length;i++)
+        {
+            char c=key[offset+i];
+
+            // Advance node
+            if (ni==-1)
+            {
+                ni=0;
+                node=(node._children==null)?null:node._children[c%_width];
+            }
+            
+            // While we have a node to try
+            while (node!=null) 
+            {
+                // If it is a matching node, goto next char
+                if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c)
+                {
+                    ni++;
+                    if (ni==node._char.length)
+                        ni=-1;
+                    continue charLoop;
+                }
+
+                // No char match, so if mid node then no match at all.
+                if (ni>0) return null;
+
+                // try next in chain
+                node=node._next;                
+            }
+            return null;
+        }
+        
+        if (ni>0) return null;
+        if (node!=null && node._key==null)
+            return null;
+        return node;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get a map entry by byte array key, using as much of the passed key as needed for a match.
+     * A simple 8859-1 byte to char mapping is assumed.
+     * @param key char array containing the key
+     * @param offset Offset of the key within the array.
+     * @param maxLength The length of the key 
+     * @return The Map.Entry for the key or null if the key is not in
+     * the map.
+     */
+    public Map.Entry getBestEntry(byte[] key,int offset, int maxLength)
+    {
+        if (key==null)
+            return _nullEntry;
+        
+        Node node = _root;
+        int ni=-1;
+
+        // look for best match
+    charLoop:
+        for (int i=0;i<maxLength;i++)
+        {
+            char c=(char)key[offset+i];
+
+            // Advance node
+            if (ni==-1)
+            {
+                ni=0;
+                
+                Node child = (node._children==null)?null:node._children[c%_width];
+                
+                if (child==null && i>0)
+                    return node; // This is the best match
+                node=child;           
+            }
+            
+            // While we have a node to try
+            while (node!=null) 
+            {
+                // If it is a matching node, goto next char
+                if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c)
+                {
+                    ni++;
+                    if (ni==node._char.length)
+                        ni=-1;
+                    continue charLoop;
+                }
+
+                // No char match, so if mid node then no match at all.
+                if (ni>0) return null;
+
+                // try next in chain
+                node=node._next;                
+            }
+            return null;
+        }
+        
+        if (ni>0) return null;
+        if (node!=null && node._key==null)
+            return null;
+        return node;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public Object remove(Object key)
+    {
+        if (key==null)
+            return remove(null);
+        return remove(key.toString());
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Object remove(String key)
+    {
+        if (key==null)
+        {
+            Object oldValue=_nullValue;
+            if (_nullEntry!=null)
+            {
+                _entrySet.remove(_nullEntry);   
+                _nullEntry=null;
+                _nullValue=null;
+            }
+            return oldValue;
+        }
+        
+        Node node = _root;
+        int ni=-1;
+
+        // look for best match
+    charLoop:
+        for (int i=0;i<key.length();i++)
+        {
+            char c=key.charAt(i);
+
+            // Advance node
+            if (ni==-1)
+            {
+                ni=0;
+                node=(node._children==null)?null:node._children[c%_width];
+            }
+            
+            // While we have a node to try
+            while (node!=null) 
+            {
+                // If it is a matching node, goto next char
+                if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c)
+                {
+                    ni++;
+                    if (ni==node._char.length)
+                        ni=-1;
+                    continue charLoop;
+                }
+
+                // No char match, so if mid node then no match at all.
+                if (ni>0) return null;
+
+                // try next in chain
+                node=node._next;         
+            }
+            return null;
+        }
+
+        if (ni>0) return null;
+        if (node!=null && node._key==null)
+            return null;
+        
+        Object old = node._value;
+        _entrySet.remove(node);
+        node._value=null;
+        node._key=null;
+        
+        return old; 
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public Set entrySet()
+    {
+        return _umEntrySet;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public int size()
+    {
+        return _entrySet.size();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isEmpty()
+    {
+        return _entrySet.isEmpty();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean containsKey(Object key)
+    {
+        if (key==null)
+            return _nullEntry!=null;
+        return
+            getEntry(key.toString(),0,key==null?0:key.toString().length())!=null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void clear()
+    {
+        _root=new Node();
+        _nullEntry=null;
+        _nullValue=null;
+        _entrySet.clear();
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class Node implements Map.Entry
+    {
+        char[] _char;
+        char[] _ochar;
+        Node _next;
+        Node[] _children;
+        String _key;
+        Object _value;
+        
+        Node(){}
+        
+        Node(boolean ignoreCase,String s, int offset)
+        {
+            int l=s.length()-offset;
+            _char=new char[l];
+            _ochar=new char[l];
+            for (int i=0;i<l;i++)
+            {
+                char c=s.charAt(offset+i);
+                _char[i]=c;
+                if (ignoreCase)
+                {
+                    char o=c;
+                    if (Character.isUpperCase(c))
+                        o=Character.toLowerCase(c);
+                    else if (Character.isLowerCase(c))
+                        o=Character.toUpperCase(c);
+                    _ochar[i]=o;
+                }
+            }
+        }
+
+        Node split(StringMap map,int offset)
+        {
+            Node split = new Node();
+            int sl=_char.length-offset;
+            
+            char[] tmp=this._char;
+            this._char=new char[offset];
+            split._char = new char[sl];
+            System.arraycopy(tmp,0,this._char,0,offset);
+            System.arraycopy(tmp,offset,split._char,0,sl);
+
+            if (this._ochar!=null)
+            {
+                tmp=this._ochar;
+                this._ochar=new char[offset];
+                split._ochar = new char[sl];
+                System.arraycopy(tmp,0,this._ochar,0,offset);
+                System.arraycopy(tmp,offset,split._ochar,0,sl);
+            }
+            
+            split._key=this._key;
+            split._value=this._value;
+            this._key=null;
+            this._value=null;
+            if (map._entrySet.remove(this))
+                map._entrySet.add(split);
+
+            split._children=this._children;            
+            this._children=new Node[map._width];
+            this._children[split._char[0]%map._width]=split;
+            if (split._ochar!=null && this._children[split._ochar[0]%map._width]!=split)
+                this._children[split._ochar[0]%map._width]=split;
+
+            return split;
+        }
+        
+        public Object getKey(){return _key;}
+        public Object getValue(){return _value;}
+        public Object setValue(Object o){Object old=_value;_value=o;return old;}
+        @Override
+        public String toString()
+        {
+            StringBuilder buf=new StringBuilder();
+            toString(buf);
+            return buf.toString();
+        }
+
+        private void toString(StringBuilder buf)
+        {
+            buf.append("{[");
+            if (_char==null)
+                buf.append('-');
+            else
+                for (int i=0;i<_char.length;i++)
+                    buf.append(_char[i]);
+            buf.append(':');
+            buf.append(_key);
+            buf.append('=');
+            buf.append(_value);
+            buf.append(']');
+            if (_children!=null)
+            {
+                for (int i=0;i<_children.length;i++)
+                {
+                    buf.append('|');
+                    if (_children[i]!=null)
+                        _children[i].toString(buf);
+                    else
+                        buf.append("-");
+                }
+            }
+            buf.append('}');
+            if (_next!=null)
+            {
+                buf.append(",\n");
+                _next.toString(buf);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class NullEntry implements Map.Entry
+    {
+        public Object getKey(){return null;}
+        public Object getValue(){return _nullValue;}
+        public Object setValue(Object o)
+            {Object old=_nullValue;_nullValue=o;return old;}
+        @Override
+        public String toString(){return "[:null="+_nullValue+"]";}
+    }
+
+    /* ------------------------------------------------------------ */
+    public void writeExternal(java.io.ObjectOutput out)
+        throws java.io.IOException
+    {
+        HashMap map = new HashMap(this);
+        out.writeBoolean(_ignoreCase);
+        out.writeObject(map);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void readExternal(java.io.ObjectInput in)
+        throws java.io.IOException, ClassNotFoundException
+    {
+        boolean ic=in.readBoolean();
+        HashMap map = (HashMap)in.readObject();
+        setIgnoreCase(ic);
+        this.putAll(map);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/StringUtil.java b/src/java/org/eclipse/jetty/util/StringUtil.java
new file mode 100644
index 0000000..b8147be
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/StringUtil.java
@@ -0,0 +1,504 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/** Fast String Utilities.
+ *
+ * These string utilities provide both conveniance methods and
+ * performance improvements over most standard library versions. The
+ * main aim of the optimizations is to avoid object creation unless
+ * absolutely required.
+ *
+ * 
+ */
+public class StringUtil
+{
+    private static final Logger LOG = Log.getLogger(StringUtil.class);
+    
+    public static final String ALL_INTERFACES="0.0.0.0";
+    public static final String CRLF="\015\012";
+    public static final String __LINE_SEPARATOR=
+        System.getProperty("line.separator","\n");
+       
+    public static final String __ISO_8859_1="ISO-8859-1";
+    public final static String __UTF8="UTF-8";
+    public final static String __UTF8Alt="UTF8";
+    public final static String __UTF16="UTF-16";
+    
+    public final static Charset __UTF8_CHARSET;
+    public final static Charset __ISO_8859_1_CHARSET;
+    
+    static
+    {
+        __UTF8_CHARSET=Charset.forName(__UTF8);
+        __ISO_8859_1_CHARSET=Charset.forName(__ISO_8859_1);
+    }
+    
+    private static char[] lowercases = {
+          '\000','\001','\002','\003','\004','\005','\006','\007',
+          '\010','\011','\012','\013','\014','\015','\016','\017',
+          '\020','\021','\022','\023','\024','\025','\026','\027',
+          '\030','\031','\032','\033','\034','\035','\036','\037',
+          '\040','\041','\042','\043','\044','\045','\046','\047',
+          '\050','\051','\052','\053','\054','\055','\056','\057',
+          '\060','\061','\062','\063','\064','\065','\066','\067',
+          '\070','\071','\072','\073','\074','\075','\076','\077',
+          '\100','\141','\142','\143','\144','\145','\146','\147',
+          '\150','\151','\152','\153','\154','\155','\156','\157',
+          '\160','\161','\162','\163','\164','\165','\166','\167',
+          '\170','\171','\172','\133','\134','\135','\136','\137',
+          '\140','\141','\142','\143','\144','\145','\146','\147',
+          '\150','\151','\152','\153','\154','\155','\156','\157',
+          '\160','\161','\162','\163','\164','\165','\166','\167',
+          '\170','\171','\172','\173','\174','\175','\176','\177' };
+
+    /* ------------------------------------------------------------ */
+    /**
+     * fast lower case conversion. Only works on ascii (not unicode)
+     * @param s the string to convert
+     * @return a lower case version of s
+     */
+    public static String asciiToLowerCase(String s)
+    {
+        char[] c = null;
+        int i=s.length();
+
+        // look for first conversion
+        while (i-->0)
+        {
+            char c1=s.charAt(i);
+            if (c1<=127)
+            {
+                char c2=lowercases[c1];
+                if (c1!=c2)
+                {
+                    c=s.toCharArray();
+                    c[i]=c2;
+                    break;
+                }
+            }
+        }
+
+        while (i-->0)
+        {
+            if(c[i]<=127)
+                c[i] = lowercases[c[i]];
+        }
+        
+        return c==null?s:new String(c);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public static boolean startsWithIgnoreCase(String s,String w)
+    {
+        if (w==null)
+            return true;
+        
+        if (s==null || s.length()<w.length())
+            return false;
+        
+        for (int i=0;i<w.length();i++)
+        {
+            char c1=s.charAt(i);
+            char c2=w.charAt(i);
+            if (c1!=c2)
+            {
+                if (c1<=127)
+                    c1=lowercases[c1];
+                if (c2<=127)
+                    c2=lowercases[c2];
+                if (c1!=c2)
+                    return false;
+            }
+        }
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static boolean endsWithIgnoreCase(String s,String w)
+    {
+        if (w==null)
+            return true;
+
+        if (s==null)
+            return false;
+            
+        int sl=s.length();
+        int wl=w.length();
+        
+        if (sl<wl)
+            return false;
+        
+        for (int i=wl;i-->0;)
+        {
+            char c1=s.charAt(--sl);
+            char c2=w.charAt(i);
+            if (c1!=c2)
+            {
+                if (c1<=127)
+                    c1=lowercases[c1];
+                if (c2<=127)
+                    c2=lowercases[c2];
+                if (c1!=c2)
+                    return false;
+            }
+        }
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * returns the next index of a character from the chars string
+     */
+    public static int indexFrom(String s,String chars)
+    {
+        for (int i=0;i<s.length();i++)
+           if (chars.indexOf(s.charAt(i))>=0)
+              return i;
+        return -1;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * replace substrings within string.
+     */
+    public static String replace(String s, String sub, String with)
+    {
+        int c=0;
+        int i=s.indexOf(sub,c);
+        if (i == -1)
+            return s;
+    
+        StringBuilder buf = new StringBuilder(s.length()+with.length());
+
+        do
+        {
+            buf.append(s.substring(c,i));
+            buf.append(with);
+            c=i+sub.length();
+        } while ((i=s.indexOf(sub,c))!=-1);
+
+        if (c<s.length())
+            buf.append(s.substring(c,s.length()));
+
+        return buf.toString();
+        
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Remove single or double quotes.
+     */
+    public static String unquote(String s)
+    {
+        return QuotedStringTokenizer.unquote(s);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Append substring to StringBuilder 
+     * @param buf StringBuilder to append to
+     * @param s String to append from
+     * @param offset The offset of the substring
+     * @param length The length of the substring
+     */
+    public static void append(StringBuilder buf,
+                              String s,
+                              int offset,
+                              int length)
+    {
+        synchronized(buf)
+        {
+            int end=offset+length;
+            for (int i=offset; i<end;i++)
+            {
+                if (i>=s.length())
+                    break;
+                buf.append(s.charAt(i));
+            }
+        }
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * append hex digit
+     * 
+     */
+    public static void append(StringBuilder buf,byte b,int base)
+    {
+        int bi=0xff&b;
+        int c='0'+(bi/base)%base;
+        if (c>'9')
+            c= 'a'+(c-'0'-10);
+        buf.append((char)c);
+        c='0'+bi%base;
+        if (c>'9')
+            c= 'a'+(c-'0'-10);
+        buf.append((char)c);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void append2digits(StringBuffer buf,int i)
+    {
+        if (i<100)
+        {
+            buf.append((char)(i/10+'0'));
+            buf.append((char)(i%10+'0'));
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static void append2digits(StringBuilder buf,int i)
+    {
+        if (i<100)
+        {
+            buf.append((char)(i/10+'0'));
+            buf.append((char)(i%10+'0'));
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Return a non null string.
+     * @param s String
+     * @return The string passed in or empty string if it is null. 
+     */
+    public static String nonNull(String s)
+    {
+        if (s==null)
+            return "";
+        return s;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static boolean equals(String s,char[] buf, int offset, int length)
+    {
+        if (s.length()!=length)
+            return false;
+        for (int i=0;i<length;i++)
+            if (buf[offset+i]!=s.charAt(i))
+                return false;
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String toUTF8String(byte[] b,int offset,int length)
+    {
+        try
+        {
+            return new String(b,offset,length,__UTF8);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String toString(byte[] b,int offset,int length,String charset)
+    {
+        try
+        {
+            return new String(b,offset,length,charset);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public static boolean isUTF8(String charset)
+    {
+        return __UTF8.equalsIgnoreCase(charset)||__UTF8Alt.equalsIgnoreCase(charset);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public static String printable(String name)
+    {
+        if (name==null)
+            return null;
+        StringBuilder buf = new StringBuilder(name.length());
+        for (int i=0;i<name.length();i++)
+        {
+            char c=name.charAt(i);
+            if (!Character.isISOControl(c))
+                buf.append(c);
+        }
+        return buf.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static String printable(byte[] b)
+    {
+        StringBuilder buf = new StringBuilder();
+        for (int i=0;i<b.length;i++)
+        {
+            char c=(char)b[i];
+            if (Character.isWhitespace(c)|| c>' ' && c<0x7f)
+                buf.append(c);
+            else 
+            {
+                buf.append("0x");
+                TypeUtil.toHex(b[i],buf);
+            }
+        }
+        return buf.toString();
+    }
+    
+    public static byte[] getBytes(String s)
+    {
+        try
+        {
+            return s.getBytes(__ISO_8859_1);
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+            return s.getBytes();
+        }
+    }
+    
+    public static byte[] getBytes(String s,String charset)
+    {
+        try
+        {
+            return s.getBytes(charset);
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+            return s.getBytes();
+        }
+    }
+    
+    
+    
+    /**
+     * Converts a binary SID to a string SID
+     * 
+     * http://en.wikipedia.org/wiki/Security_Identifier
+     * 
+     * S-1-IdentifierAuthority-SubAuthority1-SubAuthority2-...-SubAuthorityn
+     */
+    public static String sidBytesToString(byte[] sidBytes)
+    {
+        StringBuilder sidString = new StringBuilder();
+        
+        // Identify this as a SID
+        sidString.append("S-");
+        
+        // Add SID revision level (expect 1 but may change someday)
+        sidString.append(Byte.toString(sidBytes[0])).append('-');
+        
+        StringBuilder tmpBuilder = new StringBuilder();
+        
+        // crunch the six bytes of issuing authority value
+        for (int i = 2; i <= 7; ++i)
+        {
+            tmpBuilder.append(Integer.toHexString(sidBytes[i] & 0xFF));
+        }
+        
+        sidString.append(Long.parseLong(tmpBuilder.toString(), 16)); // '-' is in the subauth loop
+   
+        // the number of subAuthorities we need to attach
+        int subAuthorityCount = sidBytes[1];
+
+        // attach each of the subAuthorities
+        for (int i = 0; i < subAuthorityCount; ++i)
+        {
+            int offset = i * 4;
+            tmpBuilder.setLength(0);
+            // these need to be zero padded hex and little endian
+            tmpBuilder.append(String.format("%02X%02X%02X%02X", 
+                    (sidBytes[11 + offset] & 0xFF),
+                    (sidBytes[10 + offset] & 0xFF),
+                    (sidBytes[9 + offset] & 0xFF),
+                    (sidBytes[8 + offset] & 0xFF)));  
+            sidString.append('-').append(Long.parseLong(tmpBuilder.toString(), 16));
+        }
+        
+        return sidString.toString();
+    }
+    
+    /**
+     * Converts a string SID to a binary SID
+     * 
+     * http://en.wikipedia.org/wiki/Security_Identifier
+     * 
+     * S-1-IdentifierAuthority-SubAuthority1-SubAuthority2-...-SubAuthorityn
+     */
+    public static byte[] sidStringToBytes( String sidString )
+    {
+        String[] sidTokens = sidString.split("-");
+        
+        int subAuthorityCount = sidTokens.length - 3; // S-Rev-IdAuth-
+        
+        int byteCount = 0;
+        byte[] sidBytes = new byte[1 + 1 + 6 + (4 * subAuthorityCount)];
+        
+        // the revision byte
+        sidBytes[byteCount++] = (byte)Integer.parseInt(sidTokens[1]);
+
+        // the # of sub authorities byte
+        sidBytes[byteCount++] = (byte)subAuthorityCount;
+
+        // the certAuthority
+        String hexStr = Long.toHexString(Long.parseLong(sidTokens[2]));
+        
+        while( hexStr.length() < 12) // pad to 12 characters
+        {
+            hexStr = "0" + hexStr;
+        }
+
+        // place the certAuthority 6 bytes
+        for ( int i = 0 ; i < hexStr.length(); i = i + 2)
+        {
+            sidBytes[byteCount++] = (byte)Integer.parseInt(hexStr.substring(i, i + 2),16);
+        }
+                
+        
+        for ( int i = 3; i < sidTokens.length ; ++i)
+        {
+            hexStr = Long.toHexString(Long.parseLong(sidTokens[i]));
+            
+            while( hexStr.length() < 8) // pad to 8 characters
+            {
+                hexStr = "0" + hexStr;
+            }     
+            
+            // place the inverted sub authorities, 4 bytes each
+            for ( int j = hexStr.length(); j > 0; j = j - 2)
+            {          
+                sidBytes[byteCount++] = (byte)Integer.parseInt(hexStr.substring(j-2, j),16);
+            }
+        }
+      
+        return sidBytes;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/TypeUtil.java b/src/java/org/eclipse/jetty/util/TypeUtil.java
new file mode 100644
index 0000000..0464f0a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/TypeUtil.java
@@ -0,0 +1,593 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * TYPE Utilities.
+ * Provides various static utiltiy methods for manipulating types and their
+ * string representations.
+ *
+ * @since Jetty 4.1
+ */
+public class TypeUtil
+{
+    private static final Logger LOG = Log.getLogger(TypeUtil.class);
+    public static int CR = '\015';
+    public static int LF = '\012';
+
+    /* ------------------------------------------------------------ */
+    private static final HashMap<String, Class<?>> name2Class=new HashMap<String, Class<?>>();
+    static
+    {
+        name2Class.put("boolean",java.lang.Boolean.TYPE);
+        name2Class.put("byte",java.lang.Byte.TYPE);
+        name2Class.put("char",java.lang.Character.TYPE);
+        name2Class.put("double",java.lang.Double.TYPE);
+        name2Class.put("float",java.lang.Float.TYPE);
+        name2Class.put("int",java.lang.Integer.TYPE);
+        name2Class.put("long",java.lang.Long.TYPE);
+        name2Class.put("short",java.lang.Short.TYPE);
+        name2Class.put("void",java.lang.Void.TYPE);
+
+        name2Class.put("java.lang.Boolean.TYPE",java.lang.Boolean.TYPE);
+        name2Class.put("java.lang.Byte.TYPE",java.lang.Byte.TYPE);
+        name2Class.put("java.lang.Character.TYPE",java.lang.Character.TYPE);
+        name2Class.put("java.lang.Double.TYPE",java.lang.Double.TYPE);
+        name2Class.put("java.lang.Float.TYPE",java.lang.Float.TYPE);
+        name2Class.put("java.lang.Integer.TYPE",java.lang.Integer.TYPE);
+        name2Class.put("java.lang.Long.TYPE",java.lang.Long.TYPE);
+        name2Class.put("java.lang.Short.TYPE",java.lang.Short.TYPE);
+        name2Class.put("java.lang.Void.TYPE",java.lang.Void.TYPE);
+
+        name2Class.put("java.lang.Boolean",java.lang.Boolean.class);
+        name2Class.put("java.lang.Byte",java.lang.Byte.class);
+        name2Class.put("java.lang.Character",java.lang.Character.class);
+        name2Class.put("java.lang.Double",java.lang.Double.class);
+        name2Class.put("java.lang.Float",java.lang.Float.class);
+        name2Class.put("java.lang.Integer",java.lang.Integer.class);
+        name2Class.put("java.lang.Long",java.lang.Long.class);
+        name2Class.put("java.lang.Short",java.lang.Short.class);
+
+        name2Class.put("Boolean",java.lang.Boolean.class);
+        name2Class.put("Byte",java.lang.Byte.class);
+        name2Class.put("Character",java.lang.Character.class);
+        name2Class.put("Double",java.lang.Double.class);
+        name2Class.put("Float",java.lang.Float.class);
+        name2Class.put("Integer",java.lang.Integer.class);
+        name2Class.put("Long",java.lang.Long.class);
+        name2Class.put("Short",java.lang.Short.class);
+
+        name2Class.put(null,java.lang.Void.TYPE);
+        name2Class.put("string",java.lang.String.class);
+        name2Class.put("String",java.lang.String.class);
+        name2Class.put("java.lang.String",java.lang.String.class);
+    }
+
+    /* ------------------------------------------------------------ */
+    private static final HashMap<Class<?>, String> class2Name=new HashMap<Class<?>, String>();
+    static
+    {
+        class2Name.put(java.lang.Boolean.TYPE,"boolean");
+        class2Name.put(java.lang.Byte.TYPE,"byte");
+        class2Name.put(java.lang.Character.TYPE,"char");
+        class2Name.put(java.lang.Double.TYPE,"double");
+        class2Name.put(java.lang.Float.TYPE,"float");
+        class2Name.put(java.lang.Integer.TYPE,"int");
+        class2Name.put(java.lang.Long.TYPE,"long");
+        class2Name.put(java.lang.Short.TYPE,"short");
+        class2Name.put(java.lang.Void.TYPE,"void");
+
+        class2Name.put(java.lang.Boolean.class,"java.lang.Boolean");
+        class2Name.put(java.lang.Byte.class,"java.lang.Byte");
+        class2Name.put(java.lang.Character.class,"java.lang.Character");
+        class2Name.put(java.lang.Double.class,"java.lang.Double");
+        class2Name.put(java.lang.Float.class,"java.lang.Float");
+        class2Name.put(java.lang.Integer.class,"java.lang.Integer");
+        class2Name.put(java.lang.Long.class,"java.lang.Long");
+        class2Name.put(java.lang.Short.class,"java.lang.Short");
+
+        class2Name.put(null,"void");
+        class2Name.put(java.lang.String.class,"java.lang.String");
+    }
+
+    /* ------------------------------------------------------------ */
+    private static final HashMap<Class<?>, Method> class2Value=new HashMap<Class<?>, Method>();
+    static
+    {
+        try
+        {
+            Class<?>[] s ={java.lang.String.class};
+
+            class2Value.put(java.lang.Boolean.TYPE,
+                           java.lang.Boolean.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Byte.TYPE,
+                           java.lang.Byte.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Double.TYPE,
+                           java.lang.Double.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Float.TYPE,
+                           java.lang.Float.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Integer.TYPE,
+                           java.lang.Integer.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Long.TYPE,
+                           java.lang.Long.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Short.TYPE,
+                           java.lang.Short.class.getMethod("valueOf",s));
+
+            class2Value.put(java.lang.Boolean.class,
+                           java.lang.Boolean.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Byte.class,
+                           java.lang.Byte.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Double.class,
+                           java.lang.Double.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Float.class,
+                           java.lang.Float.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Integer.class,
+                           java.lang.Integer.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Long.class,
+                           java.lang.Long.class.getMethod("valueOf",s));
+            class2Value.put(java.lang.Short.class,
+                           java.lang.Short.class.getMethod("valueOf",s));
+        }
+        catch(Exception e)
+        {
+            throw new Error(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Array to List.
+     * <p>
+     * Works like {@link Arrays#asList(Object...)}, but handles null arrays.
+     * @return a list backed by the array.
+     */
+    public static <T> List<T> asList(T[] a) 
+    {
+        if (a==null)
+            return Collections.emptyList();
+        return Arrays.asList(a);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Class from a canonical name for a type.
+     * @param name A class or type name.
+     * @return A class , which may be a primitive TYPE field..
+     */
+    public static Class<?> fromName(String name)
+    {
+        return name2Class.get(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Canonical name for a type.
+     * @param type A class , which may be a primitive TYPE field.
+     * @return Canonical name.
+     */
+    public static String toName(Class<?> type)
+    {
+        return class2Name.get(type);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convert String value to instance.
+     * @param type The class of the instance, which may be a primitive TYPE field.
+     * @param value The value as a string.
+     * @return The value as an Object.
+     */
+    public static Object valueOf(Class<?> type, String value)
+    {
+        try
+        {
+            if (type.equals(java.lang.String.class))
+                return value;
+
+            Method m = class2Value.get(type);
+            if (m!=null)
+                return m.invoke(null, value);
+
+            if (type.equals(java.lang.Character.TYPE) ||
+                type.equals(java.lang.Character.class))
+                return new Character(value.charAt(0));
+
+            Constructor<?> c = type.getConstructor(java.lang.String.class);
+            return c.newInstance(value);
+        }
+        catch(NoSuchMethodException e)
+        {
+            // LogSupport.ignore(log,e);
+        }
+        catch(IllegalAccessException e)
+        {
+            // LogSupport.ignore(log,e);
+        }
+        catch(InstantiationException e)
+        {
+            // LogSupport.ignore(log,e);
+        }
+        catch(InvocationTargetException e)
+        {
+            if (e.getTargetException() instanceof Error)
+                throw (Error)(e.getTargetException());
+            // LogSupport.ignore(log,e);
+        }
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convert String value to instance.
+     * @param type classname or type (eg int)
+     * @param value The value as a string.
+     * @return The value as an Object.
+     */
+    public static Object valueOf(String type, String value)
+    {
+        return valueOf(fromName(type),value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse an int from a substring.
+     * Negative numbers are not handled.
+     * @param s String
+     * @param offset Offset within string
+     * @param length Length of integer or -1 for remainder of string
+     * @param base base of the integer
+     * @return the parsed integer
+     * @throws NumberFormatException if the string cannot be parsed
+     */
+    public static int parseInt(String s, int offset, int length, int base)
+        throws NumberFormatException
+    {
+        int value=0;
+
+        if (length<0)
+            length=s.length()-offset;
+
+        for (int i=0;i<length;i++)
+        {
+            char c=s.charAt(offset+i);
+
+            int digit=convertHexDigit((int)c);
+            if (digit<0 || digit>=base)
+                throw new NumberFormatException(s.substring(offset,offset+length));
+            value=value*base+digit;
+        }
+        return value;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse an int from a byte array of ascii characters.
+     * Negative numbers are not handled.
+     * @param b byte array
+     * @param offset Offset within string
+     * @param length Length of integer or -1 for remainder of string
+     * @param base base of the integer
+     * @return the parsed integer
+     * @throws NumberFormatException if the array cannot be parsed into an integer
+     */
+    public static int parseInt(byte[] b, int offset, int length, int base)
+        throws NumberFormatException
+    {
+        int value=0;
+
+        if (length<0)
+            length=b.length-offset;
+
+        for (int i=0;i<length;i++)
+        {
+            char c=(char)(0xff&b[offset+i]);
+
+            int digit=c-'0';
+            if (digit<0 || digit>=base || digit>=10)
+            {
+                digit=10+c-'A';
+                if (digit<10 || digit>=base)
+                    digit=10+c-'a';
+            }
+            if (digit<0 || digit>=base)
+                throw new NumberFormatException(new String(b,offset,length));
+            value=value*base+digit;
+        }
+        return value;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static byte[] parseBytes(String s, int base)
+    {
+        byte[] bytes=new byte[s.length()/2];
+        for (int i=0;i<s.length();i+=2)
+            bytes[i/2]=(byte)TypeUtil.parseInt(s,i,2,base);
+        return bytes;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String toString(byte[] bytes, int base)
+    {
+        StringBuilder buf = new StringBuilder();
+        for (byte b : bytes)
+        {
+            int bi=0xff&b;
+            int c='0'+(bi/base)%base;
+            if (c>'9')
+                c= 'a'+(c-'0'-10);
+            buf.append((char)c);
+            c='0'+bi%base;
+            if (c>'9')
+                c= 'a'+(c-'0'-10);
+            buf.append((char)c);
+        }
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param c An ASCII encoded character 0-9 a-f A-F
+     * @return The byte value of the character 0-16.
+     */
+    public static byte convertHexDigit( byte c )
+    {
+        byte b = (byte)((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
+        if (b<0 || b>15)
+            throw new IllegalArgumentException("!hex "+c);
+        return b;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param c An ASCII encoded character 0-9 a-f A-F
+     * @return The byte value of the character 0-16.
+     */
+    public static int convertHexDigit( int c )
+    {
+        int d= ((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
+        if (d<0 || d>15)
+            throw new NumberFormatException("!hex "+c);
+        return d;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void toHex(byte b,Appendable buf)
+    {
+        try
+        {
+            int d=0xf&((0xF0&b)>>4);
+            buf.append((char)((d>9?('A'-10):'0')+d));
+            d=0xf&b;
+            buf.append((char)((d>9?('A'-10):'0')+d));
+        }
+        catch(IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void toHex(int value,Appendable buf) throws IOException
+    {
+        int d=0xf&((0xF0000000&value)>>28);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x0F000000&value)>>24);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x00F00000&value)>>20);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x000F0000&value)>>16);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x0000F000&value)>>12);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x00000F00&value)>>8);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&((0x000000F0&value)>>4);
+        buf.append((char)((d>9?('A'-10):'0')+d));
+        d=0xf&value;
+        buf.append((char)((d>9?('A'-10):'0')+d));
+    
+        Integer.toString(0,36);
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    public static void toHex(long value,Appendable buf) throws IOException
+    {
+        toHex((int)(value>>32),buf);
+        toHex((int)value,buf);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String toHexString(byte b)
+    {
+        return toHexString(new byte[]{b}, 0, 1);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static String toHexString(byte[] b)
+    {
+        return toHexString(b, 0, b.length);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String toHexString(byte[] b,int offset,int length)
+    {
+        StringBuilder buf = new StringBuilder();
+        for (int i=offset;i<offset+length;i++)
+        {
+            int bi=0xff&b[i];
+            int c='0'+(bi/16)%16;
+            if (c>'9')
+                c= 'A'+(c-'0'-10);
+            buf.append((char)c);
+            c='0'+bi%16;
+            if (c>'9')
+                c= 'a'+(c-'0'-10);
+            buf.append((char)c);
+        }
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    public static byte[] fromHexString(String s)
+    {
+        if (s.length()%2!=0)
+            throw new IllegalArgumentException(s);
+        byte[] array = new byte[s.length()/2];
+        for (int i=0;i<array.length;i++)
+        {
+            int b = Integer.parseInt(s.substring(i*2,i*2+2),16);
+            array[i]=(byte)(0xff&b);
+        }
+        return array;
+    }
+
+
+    public static void dump(Class<?> c)
+    {
+        System.err.println("Dump: "+c);
+        dump(c.getClassLoader());
+    }
+
+    public static void dump(ClassLoader cl)
+    {
+        System.err.println("Dump Loaders:");
+        while(cl!=null)
+        {
+            System.err.println("  loader "+cl);
+            cl = cl.getParent();
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @deprecated
+     */
+    public static byte[] readLine(InputStream in) throws IOException
+    {
+        byte[] buf = new byte[256];
+
+        int i=0;
+        int loops=0;
+        int ch=0;
+
+        while (true)
+        {
+            ch=in.read();
+            if (ch<0)
+                break;
+            loops++;
+
+            // skip a leading LF's
+            if (loops==1 && ch==LF)
+                continue;
+
+            if (ch==CR || ch==LF)
+                break;
+
+            if (i>=buf.length)
+            {
+                byte[] old_buf=buf;
+                buf=new byte[old_buf.length+256];
+                System.arraycopy(old_buf, 0, buf, 0, old_buf.length);
+            }
+            buf[i++]=(byte)ch;
+        }
+
+        if (ch==-1 && i==0)
+            return null;
+
+        // skip a trailing LF if it exists
+        if (ch==CR && in.available()>=1 && in.markSupported())
+        {
+            in.mark(1);
+            ch=in.read();
+            if (ch!=LF)
+                in.reset();
+        }
+
+        byte[] old_buf=buf;
+        buf=new byte[i];
+        System.arraycopy(old_buf, 0, buf, 0, i);
+
+        return buf;
+    }
+
+    public static URL jarFor(String className)
+    {
+        try
+        {
+            className=className.replace('.','/')+".class";
+            // hack to discover jstl libraries
+            URL url = Loader.getResource(null,className,false);
+            String s=url.toString();
+            if (s.startsWith("jar:file:"))
+                return new URL(s.substring(4,s.indexOf("!/")));
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+        }
+        return null;
+    }
+    
+    public static Object call(Class<?> oClass, String method, Object obj, Object[] arg) 
+       throws InvocationTargetException, NoSuchMethodException
+    {
+        // Lets just try all methods for now
+        Method[] methods = oClass.getMethods();
+        for (int c = 0; methods != null && c < methods.length; c++)
+        {
+            if (!methods[c].getName().equals(method))
+                continue;
+            if (methods[c].getParameterTypes().length != arg.length)
+                continue;
+            if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null))
+                continue;
+            if ((obj == null) && methods[c].getDeclaringClass() != oClass)
+                continue;
+
+            try
+            {
+                return methods[c].invoke(obj,arg);
+            }
+            catch (IllegalAccessException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (IllegalArgumentException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+
+        throw new NoSuchMethodException(method);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/URIUtil.java b/src/java/org/eclipse/jetty/util/URIUtil.java
new file mode 100644
index 0000000..490f5db
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/URIUtil.java
@@ -0,0 +1,692 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+
+import org.eclipse.jetty.util.log.Log;
+
+
+
+/* ------------------------------------------------------------ */
+/** URI Holder.
+ * This class assists with the decoding and encoding or HTTP URI's.
+ * It differs from the java.net.URL class as it does not provide
+ * communications ability, but it does assist with query string
+ * formatting.
+ * <P>UTF-8 encoding is used by default for % encoded characters. This
+ * may be overridden with the org.eclipse.jetty.util.URI.charset system property.
+ * @see UrlEncoded
+ * 
+ */
+public class URIUtil
+    implements Cloneable
+{
+    public static final String SLASH="/";
+    public static final String HTTP="http";
+    public static final String HTTP_COLON="http:";
+    public static final String HTTPS="https";
+    public static final String HTTPS_COLON="https:";
+
+    // Use UTF-8 as per http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
+    public static final String __CHARSET=System.getProperty("org.eclipse.jetty.util.URI.charset",StringUtil.__UTF8);
+    
+    private URIUtil()
+    {}
+    
+    /* ------------------------------------------------------------ */
+    /** Encode a URI path.
+     * This is the same encoding offered by URLEncoder, except that
+     * the '/' character is not encoded.
+     * @param path The path the encode
+     * @return The encoded path
+     */
+    public static String encodePath(String path)
+    {
+        if (path==null || path.length()==0)
+            return path;
+        
+        StringBuilder buf = encodePath(null,path);
+        return buf==null?path:buf.toString();
+    }
+        
+    /* ------------------------------------------------------------ */
+    /** Encode a URI path.
+     * @param path The path the encode
+     * @param buf StringBuilder to encode path into (or null)
+     * @return The StringBuilder or null if no substitutions required.
+     */
+    public static StringBuilder encodePath(StringBuilder buf, String path)
+    {
+        byte[] bytes=null;
+        if (buf==null)
+        {
+        loop:
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                switch(c)
+                {
+                    case '%':
+                    case '?':
+                    case ';':
+                    case '#':
+                    case '\'':
+                    case '"':
+                    case '<':
+                    case '>':
+                    case ' ':
+                        buf=new StringBuilder(path.length()*2);
+                        break loop;
+                    default:
+                        if (c>127)
+                        {
+                            try
+                            {
+                                bytes=path.getBytes(URIUtil.__CHARSET);
+                            }
+                            catch (UnsupportedEncodingException e)
+                            {
+                                throw new IllegalStateException(e);
+                            }
+                            buf=new StringBuilder(path.length()*2);
+                            break loop;
+                        }
+                       
+                }
+            }
+            if (buf==null)
+                return null;
+        }
+        
+        synchronized(buf)
+        {
+            if (bytes!=null)
+            {
+                for (int i=0;i<bytes.length;i++)
+                {
+                    byte c=bytes[i];       
+                    switch(c)
+                    {
+                      case '%':
+                          buf.append("%25");
+                          continue;
+                      case '?':
+                          buf.append("%3F");
+                          continue;
+                      case ';':
+                          buf.append("%3B");
+                          continue;
+                      case '#':
+                          buf.append("%23");
+                          continue;
+                      case '"':
+                          buf.append("%22");
+                          continue;
+                      case '\'':
+                          buf.append("%27");
+                          continue;
+                      case '<':
+                          buf.append("%3C");
+                          continue;
+                      case '>':
+                          buf.append("%3E");
+                          continue;
+                      case ' ':
+                          buf.append("%20");
+                          continue;
+                      default:
+                          if (c<0)
+                          {
+                              buf.append('%');
+                              TypeUtil.toHex(c,buf);
+                          }
+                          else
+                              buf.append((char)c);
+                          continue;
+                    }
+                }
+                
+            }
+            else
+            {
+                for (int i=0;i<path.length();i++)
+                {
+                    char c=path.charAt(i);       
+                    switch(c)
+                    {
+                        case '%':
+                            buf.append("%25");
+                            continue;
+                        case '?':
+                            buf.append("%3F");
+                            continue;
+                        case ';':
+                            buf.append("%3B");
+                            continue;
+                        case '#':
+                            buf.append("%23");
+                            continue;
+                        case '"':
+                            buf.append("%22");
+                            continue;
+                        case '\'':
+                            buf.append("%27");
+                            continue;
+                        case '<':
+                            buf.append("%3C");
+                            continue;
+                        case '>':
+                            buf.append("%3E");
+                            continue;
+                        case ' ':
+                            buf.append("%20");
+                            continue;
+                        default:
+                            buf.append(c);
+                            continue;
+                    }
+                }
+            }
+        }
+
+        return buf;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Encode a URI path.
+     * @param path The path the encode
+     * @param buf StringBuilder to encode path into (or null)
+     * @param encode String of characters to encode. % is always encoded.
+     * @return The StringBuilder or null if no substitutions required.
+     */
+    public static StringBuilder encodeString(StringBuilder buf,
+                                             String path,
+                                             String encode)
+    {
+        if (buf==null)
+        {
+        loop:
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                if (c=='%' || encode.indexOf(c)>=0)
+                {    
+                    buf=new StringBuilder(path.length()<<1);
+                    break loop;
+                }
+            }
+            if (buf==null)
+                return null;
+        }
+        
+        synchronized(buf)
+        {
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                if (c=='%' || encode.indexOf(c)>=0)
+                {
+                    buf.append('%');
+                    StringUtil.append(buf,(byte)(0xff&c),16);
+                }
+                else
+                    buf.append(c);
+            }
+        }
+
+        return buf;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* Decode a URI path and strip parameters
+     * @param path The path the encode
+     * @param buf StringBuilder to encode path into
+     */
+    public static String decodePath(String path)
+    {
+        if (path==null)
+            return null;
+        // Array to hold all converted characters
+        char[] chars=null;
+        int n=0;
+        // Array to hold a sequence of %encodings
+        byte[] bytes=null;
+        int b=0;
+        
+        int len=path.length();
+        
+        for (int i=0;i<len;i++)
+        {
+            char c = path.charAt(i);
+
+            if (c=='%' && (i+2)<len)
+            {
+                if (chars==null)
+                {
+                    chars=new char[len];
+                    bytes=new byte[len];
+                    path.getChars(0,i,chars,0);
+                }
+                bytes[b++]=(byte)(0xff&TypeUtil.parseInt(path,i+1,2,16));
+                i+=2;
+                continue;
+            }
+            else if (c==';')
+            {
+                if (chars==null)
+                {
+                    chars=new char[len];
+                    path.getChars(0,i,chars,0);
+                    n=i;
+                }
+                break;
+            }
+            else if (bytes==null)
+            {
+                n++;
+                continue;
+            }
+            
+            // Do we have some bytes to convert?
+            if (b>0)
+            {
+                // convert series of bytes and add to chars
+                String s;
+                try
+                {
+                    s=new String(bytes,0,b,__CHARSET);
+                }
+                catch (UnsupportedEncodingException e)
+                {       
+                    s=new String(bytes,0,b);
+                }
+                s.getChars(0,s.length(),chars,n);
+                n+=s.length();
+                b=0;
+            }
+            
+            chars[n++]=c;
+        }
+
+        if (chars==null)
+            return path;
+
+        // if we have a remaining sequence of bytes
+        if (b>0)
+        {
+            // convert series of bytes and add to chars
+            String s;
+            try
+            {
+                s=new String(bytes,0,b,__CHARSET);
+            }
+            catch (UnsupportedEncodingException e)
+            {       
+                s=new String(bytes,0,b);
+            }
+            s.getChars(0,s.length(),chars,n);
+            n+=s.length();
+        }
+        
+        return new String(chars,0,n);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* Decode a URI path and strip parameters.
+     * @param path The path the encode
+     * @param buf StringBuilder to encode path into
+     */
+    public static String decodePath(byte[] buf, int offset, int length)
+    {
+        byte[] bytes=null;
+        int n=0;
+        
+        for (int i=0;i<length;i++)
+        {
+            byte b = buf[i + offset];
+            
+            if (b=='%' && (i+2)<length)
+            {
+                b=(byte)(0xff&TypeUtil.parseInt(buf,i+offset+1,2,16));
+                i+=2;
+            }
+            else if (b==';')
+            {
+                length=i;
+                break;
+            }
+            else if (bytes==null)
+            {
+                n++;
+                continue;
+            }
+            
+            if (bytes==null)
+            {
+                bytes=new byte[length];
+                for (int j=0;j<n;j++)
+                    bytes[j]=buf[j + offset];
+            }
+            
+            bytes[n++]=b;
+        }
+
+        if (bytes==null)
+            return StringUtil.toString(buf,offset,length,__CHARSET);
+        return StringUtil.toString(bytes,0,n,__CHARSET);
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /** Add two URI path segments.
+     * Handles null and empty paths, path and query params (eg ?a=b or
+     * ;JSESSIONID=xxx) and avoids duplicate '/'
+     * @param p1 URI path segment (should be encoded)
+     * @param p2 URI path segment (should be encoded)
+     * @return Legally combined path segments.
+     */
+    public static String addPaths(String p1, String p2)
+    {
+        if (p1==null || p1.length()==0)
+        {
+            if (p1!=null && p2==null)
+                return p1;
+            return p2;
+        }
+        if (p2==null || p2.length()==0)
+            return p1;
+        
+        int split=p1.indexOf(';');
+        if (split<0)
+            split=p1.indexOf('?');
+        if (split==0)
+            return p2+p1;
+        if (split<0)
+            split=p1.length();
+
+        StringBuilder buf = new StringBuilder(p1.length()+p2.length()+2);
+        buf.append(p1);
+        
+        if (buf.charAt(split-1)=='/')
+        {
+            if (p2.startsWith(URIUtil.SLASH))
+            {
+                buf.deleteCharAt(split-1);
+                buf.insert(split-1,p2);
+            }
+            else
+                buf.insert(split,p2);
+        }
+        else
+        {
+            if (p2.startsWith(URIUtil.SLASH))
+                buf.insert(split,p2);
+            else
+            {
+                buf.insert(split,'/');
+                buf.insert(split+1,p2);
+            }
+        }
+
+        return buf.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Return the parent Path.
+     * Treat a URI like a directory path and return the parent directory.
+     */
+    public static String parentPath(String p)
+    {
+        if (p==null || URIUtil.SLASH.equals(p))
+            return null;
+        int slash=p.lastIndexOf('/',p.length()-2);
+        if (slash>=0)
+            return p.substring(0,slash+1);
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convert a path to a cananonical form.
+     * All instances of "." and ".." are factored out.  Null is returned
+     * if the path tries to .. above its root.
+     * @param path 
+     * @return path or null.
+     */
+    public static String canonicalPath(String path)
+    {
+        if (path==null || path.length()==0)
+            return path;
+
+        int end=path.length();
+        int start = path.lastIndexOf('/', end);
+
+    search:
+        while (end>0)
+        {
+            switch(end-start)
+            {
+              case 2: // possible single dot
+                  if (path.charAt(start+1)!='.')
+                      break;
+                  break search;
+              case 3: // possible double dot
+                  if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.')
+                      break;
+                  break search;
+            }
+            
+            end=start;
+            start=path.lastIndexOf('/',end-1);
+        }
+
+        // If we have checked the entire string
+        if (start>=end)
+            return path;
+        
+        StringBuilder buf = new StringBuilder(path);
+        int delStart=-1;
+        int delEnd=-1;
+        int skip=0;
+        
+        while (end>0)
+        {
+            switch(end-start)
+            {       
+              case 2: // possible single dot
+                  if (buf.charAt(start+1)!='.')
+                  {
+                      if (skip>0 && --skip==0)
+                      {   
+                          delStart=start>=0?start:0;
+                          if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                              delStart++;
+                      }
+                      break;
+                  }
+                  
+                  if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/')
+                      break;
+                  
+                  if(delEnd<0)
+                      delEnd=end;
+                  delStart=start;
+                  if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/')
+                  {
+                      delStart++;
+                      if (delEnd<buf.length() && buf.charAt(delEnd)=='/')
+                          delEnd++;
+                      break;
+                  }
+                  if (end==buf.length())
+                      delStart++;
+                  
+                  end=start--;
+                  while (start>=0 && buf.charAt(start)!='/')
+                      start--;
+                  continue;
+                  
+              case 3: // possible double dot
+                  if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.')
+                  {
+                      if (skip>0 && --skip==0)
+                      {   delStart=start>=0?start:0;
+                          if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                              delStart++;
+                      }
+                      break;
+                  }
+                  
+                  delStart=start;
+                  if (delEnd<0)
+                      delEnd=end;
+
+                  skip++;
+                  end=start--;
+                  while (start>=0 && buf.charAt(start)!='/')
+                      start--;
+                  continue;
+
+              default:
+                  if (skip>0 && --skip==0)
+                  {
+                      delStart=start>=0?start:0;
+                      if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                          delStart++;
+                  }
+            }     
+            
+            // Do the delete
+            if (skip<=0 && delStart>=0 && delEnd>=delStart)
+            {  
+                buf.delete(delStart,delEnd);
+                delStart=delEnd=-1;
+                if (skip>0)
+                    delEnd=end;
+            }
+            
+            end=start--;
+            while (start>=0 && buf.charAt(start)!='/')
+                start--;
+        }      
+
+        // Too many ..
+        if (skip>0)
+            return null;
+        
+        // Do the delete
+        if (delEnd>=0)
+            buf.delete(delStart,delEnd);
+
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convert a path to a compact form.
+     * All instances of "//" and "///" etc. are factored out to single "/" 
+     * @param path 
+     * @return path
+     */
+    public static String compactPath(String path)
+    {
+        if (path==null || path.length()==0)
+            return path;
+
+        int state=0;
+        int end=path.length();
+        int i=0;
+        
+        loop:
+        while (i<end)
+        {
+            char c=path.charAt(i);
+            switch(c)
+            {
+                case '?':
+                    return path;
+                case '/':
+                    state++;
+                    if (state==2)
+                        break loop;
+                    break;
+                default:
+                    state=0;
+            }
+            i++;
+        }
+        
+        if (state<2)
+            return path;
+        
+        StringBuffer buf = new StringBuffer(path.length());
+        buf.append(path,0,i);
+        
+        loop2:
+        while (i<end)
+        {
+            char c=path.charAt(i);
+            switch(c)
+            {
+                case '?':
+                    buf.append(path,i,end);
+                    break loop2;
+                case '/':
+                    if (state++==0)
+                        buf.append(c);
+                    break;
+                default:
+                    state=0;
+                    buf.append(c);
+            }
+            i++;
+        }
+        
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @param uri URI
+     * @return True if the uri has a scheme
+     */
+    public static boolean hasScheme(String uri)
+    {
+        for (int i=0;i<uri.length();i++)
+        {
+            char c=uri.charAt(i);
+            if (c==':')
+                return true;
+            if (!(c>='a'&&c<='z' ||
+                  c>='A'&&c<='Z' ||
+                  (i>0 &&(c>='0'&&c<='9' ||
+                          c=='.' ||
+                          c=='+' ||
+                          c=='-'))
+                  ))
+                break;
+        }
+        return false;
+    }
+    
+}
+
+
+
diff --git a/src/java/org/eclipse/jetty/util/UrlEncoded.java b/src/java/org/eclipse/jetty/util/UrlEncoded.java
new file mode 100644
index 0000000..692fba1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/UrlEncoded.java
@@ -0,0 +1,1034 @@
+//
+//  ========================================================================
+//  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.util;
+
+import static org.eclipse.jetty.util.TypeUtil.convertHexDigit;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Handles coding of MIME  "x-www-form-urlencoded".
+ * <p>
+ * This class handles the encoding and decoding for either
+ * the query string of a URL or the _content of a POST HTTP request.
+ *
+ * <h4>Notes</h4>
+ * The UTF-8 charset is assumed, unless otherwise defined by either
+ * passing a parameter or setting the "org.eclipse.jetty.util.UrlEncoding.charset"
+ * System property.
+ * <p>
+ * The hashtable either contains String single values, vectors
+ * of String or arrays of Strings.
+ * <p>
+ * This class is only partially synchronised.  In particular, simple
+ * get operations are not protected from concurrent updates.
+ *
+ * @see java.net.URLEncoder
+ */
+public class UrlEncoded extends MultiMap implements Cloneable
+{
+    private static final Logger LOG = Log.getLogger(UrlEncoded.class);
+
+    public static final String ENCODING = System.getProperty("org.eclipse.jetty.util.UrlEncoding.charset",StringUtil.__UTF8);
+
+    /* ----------------------------------------------------------------- */
+    public UrlEncoded(UrlEncoded url)
+    {
+        super(url);
+    }
+    
+    /* ----------------------------------------------------------------- */
+    public UrlEncoded()
+    {
+        super(6);
+    }
+    
+    /* ----------------------------------------------------------------- */
+    public UrlEncoded(String s)
+    {
+        super(6);
+        decode(s,ENCODING);
+    }
+    
+    /* ----------------------------------------------------------------- */
+    public UrlEncoded(String s, String charset)
+    {
+        super(6);
+        decode(s,charset);
+    }
+    
+    /* ----------------------------------------------------------------- */
+    public void decode(String query)
+    {
+        decodeTo(query,this,ENCODING,-1);
+    }
+    
+    /* ----------------------------------------------------------------- */
+    public void decode(String query,String charset)
+    {
+        decodeTo(query,this,charset,-1);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Encode Hashtable with % encoding.
+     */
+    public String encode()
+    {
+        return encode(ENCODING,false);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Encode Hashtable with % encoding.
+     */
+    public String encode(String charset)
+    {
+        return encode(charset,false);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Encode Hashtable with % encoding.
+     * @param equalsForNullValue if True, then an '=' is always used, even
+     * for parameters without a value. e.g. "blah?a=&b=&c=".
+     */
+    public synchronized String encode(String charset, boolean equalsForNullValue)
+    {
+        return encode(this,charset,equalsForNullValue);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Encode Hashtable with % encoding.
+     * @param equalsForNullValue if True, then an '=' is always used, even
+     * for parameters without a value. e.g. "blah?a=&b=&c=".
+     */
+    public static String encode(MultiMap map, String charset, boolean equalsForNullValue)
+    {
+        if (charset==null)
+            charset=ENCODING;
+
+        StringBuilder result = new StringBuilder(128);
+
+        Iterator iter = map.entrySet().iterator();
+        while(iter.hasNext())
+        {
+            Map.Entry entry = (Map.Entry)iter.next();
+
+            String key = entry.getKey().toString();
+            Object list = entry.getValue();
+            int s=LazyList.size(list);
+
+            if (s==0)
+            {
+                result.append(encodeString(key,charset));
+                if(equalsForNullValue)
+                    result.append('=');
+            }
+            else
+            {
+                for (int i=0;i<s;i++)
+                {
+                    if (i>0)
+                        result.append('&');
+                    Object val=LazyList.get(list,i);
+                    result.append(encodeString(key,charset));
+
+                    if (val!=null)
+                    {
+                        String str=val.toString();
+                        if (str.length()>0)
+                        {
+                            result.append('=');
+                            result.append(encodeString(str,charset));
+                        }
+                        else if (equalsForNullValue)
+                            result.append('=');
+                    }
+                    else if (equalsForNullValue)
+                        result.append('=');
+                }
+            }
+            if (iter.hasNext())
+                result.append('&');
+        }
+        return result.toString();
+    }
+
+
+
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param content the string containing the encoded parameters
+     */
+    public static void decodeTo(String content, MultiMap map, String charset)
+    {
+        decodeTo(content,map,charset,-1);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param content the string containing the encoded parameters
+     */
+    public static void decodeTo(String content, MultiMap map, String charset, int maxKeys)
+    {
+        if (charset==null)
+            charset=ENCODING;
+
+        synchronized(map)
+        {
+            String key = null;
+            String value = null;
+            int mark=-1;
+            boolean encoded=false;
+            for (int i=0;i<content.length();i++)
+            {
+                char c = content.charAt(i);
+                switch (c)
+                {
+                  case '&':
+                      int l=i-mark-1;
+                      value = l==0?"":
+                          (encoded?decodeString(content,mark+1,l,charset):content.substring(mark+1,i));
+                      mark=i;
+                      encoded=false;
+                      if (key != null)
+                      {
+                          map.add(key,value);
+                      }
+                      else if (value!=null&&value.length()>0)
+                      {
+                          map.add(value,"");
+                      }
+                      key = null;
+                      value=null;
+                      if (maxKeys>0 && map.size()>maxKeys)
+                          throw new IllegalStateException("Form too many keys");
+                      break;
+                  case '=':
+                      if (key!=null)
+                          break;
+                      key = encoded?decodeString(content,mark+1,i-mark-1,charset):content.substring(mark+1,i);
+                      mark=i;
+                      encoded=false;
+                      break;
+                  case '+':
+                      encoded=true;
+                      break;
+                  case '%':
+                      encoded=true;
+                      break;
+                }                
+            }
+            
+            if (key != null)
+            {
+                int l=content.length()-mark-1;
+                value = l==0?"":(encoded?decodeString(content,mark+1,l,charset):content.substring(mark+1));
+                map.add(key,value);
+            }
+            else if (mark<content.length())
+            {
+                key = encoded
+                    ?decodeString(content,mark+1,content.length()-mark-1,charset)
+                    :content.substring(mark+1);
+                if (key != null && key.length() > 0)
+                {
+                    map.add(key,"");
+                }
+            }
+        }
+    }
+
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param raw the byte[] containing the encoded parameters
+     * @param offset the offset within raw to decode from
+     * @param length the length of the section to decode
+     * @param map the {@link MultiMap} to populate
+     */
+    public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map)
+    {
+        decodeUtf8To(raw,offset,length,map,new Utf8StringBuilder());
+    }
+
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param raw the byte[] containing the encoded parameters
+     * @param offset the offset within raw to decode from
+     * @param length the length of the section to decode
+     * @param map the {@link MultiMap} to populate
+     * @param buffer the buffer to decode into
+     */
+    public static void decodeUtf8To(byte[] raw,int offset, int length, MultiMap map,Utf8StringBuilder buffer)
+    {
+        synchronized(map)
+        {
+            String key = null;
+            String value = null;
+
+            // TODO cache of parameter names ???
+            int end=offset+length;
+            for (int i=offset;i<end;i++)
+            {
+                byte b=raw[i];
+                try
+                {
+                    switch ((char)(0xff&b))
+                    {
+                        case '&':
+                            value = buffer.length()==0?"":buffer.toString();
+                            buffer.reset();
+                            if (key != null)
+                            {
+                                map.add(key,value);
+                            }
+                            else if (value!=null&&value.length()>0)
+                            {
+                                map.add(value,"");
+                            }
+                            key = null;
+                            value=null;
+                            break;
+
+                        case '=':
+                            if (key!=null)
+                            {
+                                buffer.append(b);
+                                break;
+                            }
+                            key = buffer.toString();
+                            buffer.reset();
+                            break;
+
+                        case '+':
+                            buffer.append((byte)' ');
+                            break;
+
+                        case '%':
+                            if (i+2<end)
+                            {
+                                if ('u'==raw[i+1])
+                                {
+                                    i++;
+                                    if (i+4<end)
+                                        buffer.getStringBuilder().append(Character.toChars((convertHexDigit(raw[++i])<<12) +(convertHexDigit(raw[++i])<<8) + (convertHexDigit(raw[++i])<<4) +convertHexDigit(raw[++i])));
+                                    else
+                                    {
+                                        buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT);
+                                        i=end;
+                                    }
+                                }
+                                else
+                                    buffer.append((byte)((convertHexDigit(raw[++i])<<4) + convertHexDigit(raw[++i])));
+                            }
+                            else
+                            {
+                                buffer.getStringBuilder().append(Utf8Appendable.REPLACEMENT);
+                                i=end;
+                            }
+                            break;
+                            
+                        default:
+                            buffer.append(b);
+                            break;
+                    }
+                }
+                catch(NotUtf8Exception e)
+                {
+                    LOG.warn(e.toString());
+                    LOG.debug(e);
+                }
+            }
+            
+            if (key != null)
+            {
+                value = buffer.length()==0?"":buffer.toReplacedString();
+                buffer.reset();
+                map.add(key,value);
+            }
+            else if (buffer.length()>0)
+            {
+                map.add(buffer.toReplacedString(),"");
+            }
+        }
+    }
+
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param in InputSteam to read
+     * @param map MultiMap to add parameters to
+     * @param maxLength maximum number of keys to read or -1 for no limit
+     */
+    public static void decode88591To(InputStream in, MultiMap map, int maxLength, int maxKeys)
+    throws IOException
+    {
+        synchronized(map)
+        {
+            StringBuffer buffer = new StringBuffer();
+            String key = null;
+            String value = null;
+            
+            int b;
+
+            // TODO cache of parameter names ???
+            int totalLength=0;
+            while ((b=in.read())>=0)
+            {
+                switch ((char) b)
+                {
+                    case '&':
+                        value = buffer.length()==0?"":buffer.toString();
+                        buffer.setLength(0);
+                        if (key != null)
+                        {
+                            map.add(key,value);
+                        }
+                        else if (value!=null&&value.length()>0)
+                        {
+                            map.add(value,"");
+                        }
+                        key = null;
+                        value=null;
+                        if (maxKeys>0 && map.size()>maxKeys)
+                            throw new IllegalStateException("Form too many keys");
+                        break;
+                        
+                    case '=':
+                        if (key!=null)
+                        {
+                            buffer.append((char)b);
+                            break;
+                        }
+                        key = buffer.toString();
+                        buffer.setLength(0);
+                        break;
+                        
+                    case '+':
+                        buffer.append(' ');
+                        break;
+                        
+                    case '%':
+                        int code0=in.read();
+                        if ('u'==code0)
+                        {
+                            int code1=in.read();
+                            if (code1>=0)
+                            {
+                                int code2=in.read();
+                                if (code2>=0)
+                                {
+                                    int code3=in.read();
+                                    if (code3>=0)
+                                        buffer.append(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3)));
+                                }
+                            }
+                        }
+                        else if (code0>=0)
+                        {
+                            int code1=in.read();
+                            if (code1>=0)
+                                buffer.append((char)((convertHexDigit(code0)<<4)+convertHexDigit(code1)));
+                        }
+                        break;
+                     
+                    default:
+                        buffer.append((char)b);
+                    break;
+                }
+                if (maxLength>=0 && (++totalLength > maxLength))
+                    throw new IllegalStateException("Form too large");
+            }
+            
+            if (key != null)
+            {
+                value = buffer.length()==0?"":buffer.toString();
+                buffer.setLength(0);
+                map.add(key,value);
+            }
+            else if (buffer.length()>0)
+            {
+                map.add(buffer.toString(), "");
+            }
+        }
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param in InputSteam to read
+     * @param map MultiMap to add parameters to
+     * @param maxLength maximum number of keys to read or -1 for no limit
+     */
+    public static void decodeUtf8To(InputStream in, MultiMap map, int maxLength, int maxKeys)
+    throws IOException
+    {
+        synchronized(map)
+        {
+            Utf8StringBuilder buffer = new Utf8StringBuilder();
+            String key = null;
+            String value = null;
+            
+            int b;
+            
+            // TODO cache of parameter names ???
+            int totalLength=0;
+            while ((b=in.read())>=0)
+            {
+                try
+                {
+                    switch ((char) b)
+                    {
+                        case '&':
+                            value = buffer.length()==0?"":buffer.toString();
+                            buffer.reset();
+                            if (key != null)
+                            {
+                                map.add(key,value);
+                            }
+                            else if (value!=null&&value.length()>0)
+                            {
+                                map.add(value,"");
+                            }
+                            key = null;
+                            value=null;
+                            if (maxKeys>0 && map.size()>maxKeys)
+                                throw new IllegalStateException("Form too many keys");
+                            break;
+
+                        case '=':
+                            if (key!=null)
+                            {
+                                buffer.append((byte)b);
+                                break;
+                            }
+                            key = buffer.toString();
+                            buffer.reset();
+                            break;
+
+                        case '+':
+                            buffer.append((byte)' ');
+                            break;
+
+                        case '%':
+                            int code0=in.read();
+                            if ('u'==code0)
+                            {
+                                int code1=in.read();
+                                if (code1>=0)
+                                {
+                                    int code2=in.read();
+                                    if (code2>=0)
+                                    {
+                                        int code3=in.read();
+                                        if (code3>=0)
+                                            buffer.getStringBuilder().append(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3)));
+                                    }
+                                }
+                            }
+                            else if (code0>=0)
+                            {
+                                int code1=in.read();
+                                if (code1>=0)
+                                    buffer.append((byte)((convertHexDigit(code0)<<4)+convertHexDigit(code1)));
+                            }
+                            break;
+                          
+                        default:
+                            buffer.append((byte)b);
+                            break;
+                    }
+                }
+                catch(NotUtf8Exception e)
+                {
+                    LOG.warn(e.toString());
+                    LOG.debug(e);
+                }
+                if (maxLength>=0 && (++totalLength > maxLength))
+                    throw new IllegalStateException("Form too large");
+            }
+            
+            if (key != null)
+            {
+                value = buffer.length()==0?"":buffer.toString();
+                buffer.reset();
+                map.add(key,value);
+            }
+            else if (buffer.length()>0)
+            {
+                map.add(buffer.toString(), "");
+            }
+        }
+    }
+    
+    /* -------------------------------------------------------------- */
+    public static void decodeUtf16To(InputStream in, MultiMap map, int maxLength, int maxKeys) throws IOException
+    {
+        InputStreamReader input = new InputStreamReader(in,StringUtil.__UTF16);
+        StringWriter buf = new StringWriter(8192);
+        IO.copy(input,buf,maxLength);
+        
+        decodeTo(buf.getBuffer().toString(),map,StringUtil.__UTF16,maxKeys);
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Decoded parameters to Map.
+     * @param in the stream containing the encoded parameters
+     */
+    public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength, int maxKeys)
+    throws IOException
+    {
+        //no charset present, use the configured default
+        if (charset==null) 
+        {
+           charset=ENCODING;
+        }
+            
+        if (StringUtil.__UTF8.equalsIgnoreCase(charset))
+        {
+            decodeUtf8To(in,map,maxLength,maxKeys);
+            return;
+        }
+        
+        if (StringUtil.__ISO_8859_1.equals(charset))
+        {
+            decode88591To(in,map,maxLength,maxKeys);
+            return;
+        }
+
+        if (StringUtil.__UTF16.equalsIgnoreCase(charset)) // Should be all 2 byte encodings
+        {
+            decodeUtf16To(in,map,maxLength,maxKeys);
+            return;
+        }
+        
+
+        synchronized(map)
+        {
+            String key = null;
+            String value = null;
+            
+            int c;
+            
+            int totalLength = 0;
+            ByteArrayOutputStream2 output = new ByteArrayOutputStream2();
+            
+            int size=0;
+            
+            while ((c=in.read())>0)
+            {
+                switch ((char) c)
+                {
+                    case '&':
+                        size=output.size();
+                        value = size==0?"":output.toString(charset);
+                        output.setCount(0);
+                        if (key != null)
+                        {
+                            map.add(key,value);
+                        }
+                        else if (value!=null&&value.length()>0)
+                        {
+                            map.add(value,"");
+                        }
+                        key = null;
+                        value=null;
+                        if (maxKeys>0 && map.size()>maxKeys)
+                            throw new IllegalStateException("Form too many keys");
+                        break;
+                    case '=':
+                        if (key!=null)
+                        {
+                            output.write(c);
+                            break;
+                        }
+                        size=output.size();
+                        key = size==0?"":output.toString(charset);
+                        output.setCount(0);
+                        break;
+                    case '+':
+                        output.write(' ');
+                        break;
+                    case '%':
+                        int code0=in.read();
+                        if ('u'==code0)
+                        {
+                            int code1=in.read();
+                            if (code1>=0)
+                            {
+                                int code2=in.read();
+                                if (code2>=0)
+                                {
+                                    int code3=in.read();
+                                    if (code3>=0)
+                                        output.write(new String(Character.toChars((convertHexDigit(code0)<<12)+(convertHexDigit(code1)<<8)+(convertHexDigit(code2)<<4)+convertHexDigit(code3))).getBytes(charset));
+                                }
+                            }
+                            
+                        }
+                        else if (code0>=0)
+                        {
+                            int code1=in.read();
+                            if (code1>=0)
+                                output.write((convertHexDigit(code0)<<4)+convertHexDigit(code1));
+                        }
+                        break;
+                    default:
+                        output.write(c);
+                    break;
+                }
+                
+                totalLength++;
+                if (maxLength>=0 && totalLength > maxLength)
+                    throw new IllegalStateException("Form too large");
+            }
+
+            size=output.size();
+            if (key != null)
+            {
+                value = size==0?"":output.toString(charset);
+                output.setCount(0);
+                map.add(key,value);
+            }
+            else if (size>0)
+                map.add(output.toString(charset),"");
+        }
+    }
+    
+    /* -------------------------------------------------------------- */
+    /** Decode String with % encoding.
+     * This method makes the assumption that the majority of calls
+     * will need no decoding.
+     */
+    public static String decodeString(String encoded,int offset,int length,String charset)
+    {
+        if (charset==null || StringUtil.isUTF8(charset))
+        {
+            Utf8StringBuffer buffer=null;
+
+            for (int i=0;i<length;i++)
+            {
+                char c = encoded.charAt(offset+i);
+                if (c<0||c>0xff)
+                {
+                    if (buffer==null)
+                    {
+                        buffer=new Utf8StringBuffer(length);
+                        buffer.getStringBuffer().append(encoded,offset,offset+i+1);
+                    }
+                    else
+                        buffer.getStringBuffer().append(c);
+                }
+                else if (c=='+')
+                {
+                    if (buffer==null)
+                    {
+                        buffer=new Utf8StringBuffer(length);
+                        buffer.getStringBuffer().append(encoded,offset,offset+i);
+                    }
+                    
+                    buffer.getStringBuffer().append(' ');
+                }
+                else if (c=='%')
+                {
+                    if (buffer==null)
+                    {
+                        buffer=new Utf8StringBuffer(length);
+                        buffer.getStringBuffer().append(encoded,offset,offset+i);
+                    }
+                    
+                    if ((i+2)<length)
+                    {
+                        try
+                        {
+                            if ('u'==encoded.charAt(offset+i+1))
+                            {
+                                if((i+5)<length)
+                                {
+                                    int o=offset+i+2;
+                                    i+=5;
+                                    String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16)));
+                                    buffer.getStringBuffer().append(unicode); 
+                                }
+                                else
+                                {
+                                    i=length;
+                                    buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT); 
+                                }
+                            }
+                            else
+                            {
+                                int o=offset+i+1;
+                                i+=2;
+                                byte b=(byte)TypeUtil.parseInt(encoded,o,2,16);
+                                buffer.append(b);
+                            }
+                        }
+                        catch(NotUtf8Exception e)
+                        {
+                            LOG.warn(e.toString());
+                            LOG.debug(e);
+                        }
+                        catch(NumberFormatException nfe)
+                        {
+                            LOG.debug(nfe);
+                            buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT);  
+                        }
+                    }
+                    else
+                    {
+                        buffer.getStringBuffer().append(Utf8Appendable.REPLACEMENT); 
+                        i=length;
+                    }
+                }
+                else if (buffer!=null)
+                    buffer.getStringBuffer().append(c);
+            }
+
+            if (buffer==null)
+            {
+                if (offset==0 && encoded.length()==length)
+                    return encoded;
+                return encoded.substring(offset,offset+length);
+            }
+
+            return buffer.toReplacedString();
+        }
+        else
+        {
+            StringBuffer buffer=null;
+
+            try
+            {
+                for (int i=0;i<length;i++)
+                {
+                    char c = encoded.charAt(offset+i);
+                    if (c<0||c>0xff)
+                    {
+                        if (buffer==null)
+                        {
+                            buffer=new StringBuffer(length);
+                            buffer.append(encoded,offset,offset+i+1);
+                        }
+                        else
+                            buffer.append(c);
+                    }
+                    else if (c=='+')
+                    {
+                        if (buffer==null)
+                        {
+                            buffer=new StringBuffer(length);
+                            buffer.append(encoded,offset,offset+i);
+                        }
+                        
+                        buffer.append(' ');
+                    }
+                    else if (c=='%')
+                    {
+                        if (buffer==null)
+                        {
+                            buffer=new StringBuffer(length);
+                            buffer.append(encoded,offset,offset+i);
+                        }
+
+                        byte[] ba=new byte[length];
+                        int n=0;
+                        while(c>=0 && c<=0xff)
+                        {
+                            if (c=='%')
+                            {   
+                                if(i+2<length)
+                                {
+                                    try
+                                    {
+                                        if ('u'==encoded.charAt(offset+i+1))
+                                        {
+                                            if (i+6<length)
+                                            {
+                                                int o=offset+i+2;
+                                                i+=6;
+                                                String unicode = new String(Character.toChars(TypeUtil.parseInt(encoded,o,4,16)));
+                                                byte[] reencoded = unicode.getBytes(charset);
+                                                System.arraycopy(reencoded,0,ba,n,reencoded.length);
+                                                n+=reencoded.length;
+                                            }
+                                            else
+                                            {
+                                                ba[n++] = (byte)'?';
+                                                i=length;
+                                            }
+                                        }
+                                        else
+                                        {
+                                            int o=offset+i+1;
+                                            i+=3;
+                                            ba[n]=(byte)TypeUtil.parseInt(encoded,o,2,16);
+                                            n++;
+                                        }
+                                    }
+                                    catch(NumberFormatException nfe)
+                                    {   
+                                        LOG.ignore(nfe);
+                                        ba[n++] = (byte)'?';
+                                    }
+                                }
+                                else
+                                {
+                                    ba[n++] = (byte)'?';
+                                    i=length;
+                                }
+                            }
+                            else if (c=='+')
+                            {
+                                ba[n++]=(byte)' ';
+                                i++;
+                            }
+                            else
+                            {
+                                ba[n++]=(byte)c;
+                                i++;
+                            }
+                            
+                            if (i>=length)
+                                break;
+                            c = encoded.charAt(offset+i);
+                        }
+
+                        i--;
+                        buffer.append(new String(ba,0,n,charset));
+
+                    }
+                    else if (buffer!=null)
+                        buffer.append(c);
+                }
+
+                if (buffer==null)
+                {
+                    if (offset==0 && encoded.length()==length)
+                        return encoded;
+                    return encoded.substring(offset,offset+length);
+                }
+
+                return buffer.toString();
+            }
+            catch (UnsupportedEncodingException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Perform URL encoding.
+     * @param string 
+     * @return encoded string.
+     */
+    public static String encodeString(String string)
+    {
+        return encodeString(string,ENCODING);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Perform URL encoding.
+     * @param string 
+     * @return encoded string.
+     */
+    public static String encodeString(String string,String charset)
+    {
+        if (charset==null)
+            charset=ENCODING;
+        byte[] bytes=null;
+        try
+        {
+            bytes=string.getBytes(charset);
+        }
+        catch(UnsupportedEncodingException e)
+        {
+            // LOG.warn(LogSupport.EXCEPTION,e);
+            bytes=string.getBytes();
+        }
+        
+        int len=bytes.length;
+        byte[] encoded= new byte[bytes.length*3];
+        int n=0;
+        boolean noEncode=true;
+        
+        for (int i=0;i<len;i++)
+        {
+            byte b = bytes[i];
+            
+            if (b==' ')
+            {
+                noEncode=false;
+                encoded[n++]=(byte)'+';
+            }
+            else if (b>='a' && b<='z' ||
+                     b>='A' && b<='Z' ||
+                     b>='0' && b<='9')
+            {
+                encoded[n++]=b;
+            }
+            else
+            {
+                noEncode=false;
+                encoded[n++]=(byte)'%';
+                byte nibble= (byte) ((b&0xf0)>>4);
+                if (nibble>=10)
+                    encoded[n++]=(byte)('A'+nibble-10);
+                else
+                    encoded[n++]=(byte)('0'+nibble);
+                nibble= (byte) (b&0xf);
+                if (nibble>=10)
+                    encoded[n++]=(byte)('A'+nibble-10);
+                else
+                    encoded[n++]=(byte)('0'+nibble);
+            }
+        }
+
+        if (noEncode)
+            return string;
+        
+        try
+        {    
+            return new String(encoded,0,n,charset);
+        }
+        catch(UnsupportedEncodingException e)
+        {
+            // LOG.warn(LogSupport.EXCEPTION,e);
+            return new String(encoded,0,n);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** 
+     */
+    @Override
+    public Object clone()
+    {
+        return new UrlEncoded(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Utf8Appendable.java b/src/java/org/eclipse/jetty/util/Utf8Appendable.java
new file mode 100644
index 0000000..ffe403c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Utf8Appendable.java
@@ -0,0 +1,238 @@
+//
+//  ========================================================================
+//  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.util;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Utf8 Appendable abstract base class
+ *
+ * This abstract class wraps a standard {@link java.lang.Appendable} and provides methods to append UTF-8 encoded bytes, that are converted into characters.
+ *
+ * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before state a character is appended to the string buffer.
+ *
+ * The UTF-8 decoding is done by this class and no additional buffers or Readers are used. The UTF-8 code was inspired by
+ * http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+ *
+ * License information for Bjoern Hoehrmann's code:
+ *
+ * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ **/
+public abstract class Utf8Appendable
+{
+    protected static final Logger LOG = Log.getLogger(Utf8Appendable.class);
+    public static final char REPLACEMENT = '\ufffd';
+    private static final int UTF8_ACCEPT = 0;
+    private static final int UTF8_REJECT = 12;
+
+    protected final Appendable _appendable;
+    protected int _state = UTF8_ACCEPT;
+
+    private static final byte[] BYTE_TABLE =
+    {
+        // The first part of the table maps bytes to character classes that
+        // to reduce the size of the transition table and create bitmasks.
+         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+         8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+        10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8
+    };
+
+    private static final byte[] TRANS_TABLE =
+    {
+        // The second part is a transition table that maps a combination
+        // of a state of the automaton and a character class to a state.
+         0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
+        12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
+        12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
+        12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
+        12,36,12,12,12,12,12,12,12,12,12,12
+    };
+
+    private int _codep;
+
+    public Utf8Appendable(Appendable appendable)
+    {
+        _appendable = appendable;
+    }
+
+    public abstract int length();
+
+    protected void reset()
+    {
+        _state = UTF8_ACCEPT;
+    }
+
+    public void append(byte b)
+    {
+        try
+        {
+            appendByte(b);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void append(byte[] b, int offset, int length)
+    {
+        try
+        {
+            int end = offset + length;
+            for (int i = offset; i < end; i++)
+                appendByte(b[i]);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public boolean append(byte[] b, int offset, int length, int maxChars)
+    {
+        try
+        {
+            int end = offset + length;
+            for (int i = offset; i < end; i++)
+            {
+                if (length() > maxChars)
+                    return false;
+                appendByte(b[i]);
+            }
+            return true;
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected void appendByte(byte b) throws IOException
+    {
+
+        if (b > 0 && _state == UTF8_ACCEPT)
+        {
+            _appendable.append((char)(b & 0xFF));
+        }
+        else
+        {
+            int i = b & 0xFF;
+            int type = BYTE_TABLE[i];
+            _codep = _state == UTF8_ACCEPT ? (0xFF >> type) & i : (i & 0x3F) | (_codep << 6);
+            int next = TRANS_TABLE[_state + type];
+
+            switch(next)
+            {
+                case UTF8_ACCEPT:
+                    _state=next;
+                    if (_codep < Character.MIN_HIGH_SURROGATE)
+                    {
+                        _appendable.append((char)_codep);
+                    }
+                    else
+                    {
+                        for (char c : Character.toChars(_codep))
+                            _appendable.append(c);
+                    }
+                    break;
+                    
+                case UTF8_REJECT:
+                    String reason = "byte "+TypeUtil.toHexString(b)+" in state "+(_state/12);
+                    _codep=0;
+                    _state = UTF8_ACCEPT;
+                    _appendable.append(REPLACEMENT);
+                    throw new NotUtf8Exception(reason);
+                    
+                default:
+                    _state=next;
+                    
+            }
+        }
+    }
+
+    public boolean isUtf8SequenceComplete()
+    {
+        return _state == UTF8_ACCEPT;
+    }
+
+    public static class NotUtf8Exception extends IllegalArgumentException
+    {
+        public NotUtf8Exception(String reason)
+        {
+            super("Not valid UTF8! "+reason);
+        }
+    }
+
+    protected void checkState()
+    {
+        if (!isUtf8SequenceComplete())
+        {
+            _codep=0;
+            _state = UTF8_ACCEPT;
+            try
+            {
+                _appendable.append(REPLACEMENT);
+            }
+            catch(IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+            throw new NotUtf8Exception("incomplete UTF8 sequence");
+        }
+    }
+    
+    public String toReplacedString()
+    {
+        if (!isUtf8SequenceComplete())
+        {
+            _codep=0;
+            _state = UTF8_ACCEPT;
+            try
+            {
+                _appendable.append(REPLACEMENT);
+            }
+            catch(IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+            Throwable th= new NotUtf8Exception("incomplete UTF8 sequence");
+            LOG.warn(th.toString());
+            LOG.debug(th);
+        }
+        return _appendable.toString();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Utf8StringBuffer.java b/src/java/org/eclipse/jetty/util/Utf8StringBuffer.java
new file mode 100644
index 0000000..63fb1ac
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Utf8StringBuffer.java
@@ -0,0 +1,75 @@
+//
+//  ========================================================================
+//  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.util;
+
+/* ------------------------------------------------------------ */
+/**
+ * UTF-8 StringBuffer.
+ *
+ * This class wraps a standard {@link java.lang.StringBuffer} and provides methods to append
+ * UTF-8 encoded bytes, that are converted into characters.
+ *
+ * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before
+ * state a character is appended to the string buffer.
+ *
+ * The UTF-8 decoding is done by this class and no additional buffers or Readers are used.
+ * The UTF-8 code was inspired by http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+ */
+public class Utf8StringBuffer extends Utf8Appendable
+{
+    final StringBuffer _buffer;
+
+    public Utf8StringBuffer()
+    {
+        super(new StringBuffer());
+        _buffer = (StringBuffer)_appendable;
+    }
+
+    public Utf8StringBuffer(int capacity)
+    {
+        super(new StringBuffer(capacity));
+        _buffer = (StringBuffer)_appendable;
+    }
+
+    @Override
+    public int length()
+    {
+        return _buffer.length();
+    }
+
+    @Override
+    public void reset()
+    {
+        super.reset();
+        _buffer.setLength(0);
+    }
+
+    public StringBuffer getStringBuffer()
+    {
+        checkState();
+        return _buffer;
+    }
+
+    @Override
+    public String toString()
+    {
+        checkState();
+        return _buffer.toString();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/Utf8StringBuilder.java b/src/java/org/eclipse/jetty/util/Utf8StringBuilder.java
new file mode 100644
index 0000000..28fa20b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/Utf8StringBuilder.java
@@ -0,0 +1,78 @@
+//
+//  ========================================================================
+//  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.util;
+
+
+/* ------------------------------------------------------------ */
+/** UTF-8 StringBuilder.
+ *
+ * This class wraps a standard {@link java.lang.StringBuilder} and provides methods to append
+ * UTF-8 encoded bytes, that are converted into characters.
+ *
+ * This class is stateful and up to 4 calls to {@link #append(byte)} may be needed before
+ * state a character is appended to the string buffer.
+ *
+ * The UTF-8 decoding is done by this class and no additional buffers or Readers are used.
+ * The UTF-8 code was inspired by http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+ *
+ */
+public class Utf8StringBuilder extends Utf8Appendable
+{
+    final StringBuilder _buffer;
+
+    public Utf8StringBuilder()
+    {
+        super(new StringBuilder());
+        _buffer=(StringBuilder)_appendable;
+    }
+
+    public Utf8StringBuilder(int capacity)
+    {
+        super(new StringBuilder(capacity));
+        _buffer=(StringBuilder)_appendable;
+    }
+
+    @Override
+    public int length()
+    {
+        return _buffer.length();
+    }
+
+    @Override
+    public void reset()
+    {
+        super.reset();
+        _buffer.setLength(0);
+    }
+
+    public StringBuilder getStringBuilder()
+    {
+        checkState();
+        return _buffer;
+    }
+
+    @Override
+    public String toString()
+    {
+        checkState();
+        return _buffer.toString();
+    }
+
+
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSON.java b/src/java/org/eclipse/jetty/util/ajax/JSON.java
new file mode 100644
index 0000000..566179d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSON.java
@@ -0,0 +1,1640 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * JSON Parser and Generator.
+ * <p />
+ * This class provides some static methods to convert POJOs to and from JSON
+ * notation. The mapping from JSON to java is:
+ *
+ * <pre>
+ *   object ==> Map
+ *   array  ==> Object[]
+ *   number ==> Double or Long
+ *   string ==> String
+ *   null   ==> null
+ *   bool   ==> Boolean
+ * </pre>
+
+ * The java to JSON mapping is:
+ *
+ * <pre>
+ *   String --> string
+ *   Number --> number
+ *   Map    --> object
+ *   List   --> array
+ *   Array  --> array
+ *   null   --> null
+ *   Boolean--> boolean
+ *   Object --> string (dubious!)
+ * </pre>
+ *
+ * The interface {@link JSON.Convertible} may be implemented by classes that
+ * wish to externalize and initialize specific fields to and from JSON objects.
+ * Only directed acyclic graphs of objects are supported.
+ * <p />
+ * The interface {@link JSON.Generator} may be implemented by classes that know
+ * how to render themselves as JSON and the {@link #toString(Object)} method
+ * will use {@link JSON.Generator#addJSON(Appendable)} to generate the JSON.
+ * The class {@link JSON.Literal} may be used to hold pre-generated JSON object.
+ * <p />
+ * The interface {@link JSON.Convertor} may be implemented to provide static
+ * converters for objects that may be registered with
+ * {@link #registerConvertor(Class, Convertor)}.
+ * These converters are looked up by class, interface and super class by
+ * {@link #getConvertor(Class)}.
+ * <p />
+ * If a JSON object has a "class" field, then a java class for that name is
+ * loaded and the method {@link #convertTo(Class,Map)} is used to find a
+ * {@link JSON.Convertor} for that class.
+ * <p />
+ * If a JSON object has a "x-class" field then a direct lookup for a
+ * {@link JSON.Convertor} for that class name is done (without loading the class).
+ */
+public class JSON
+{
+    static final Logger LOG = Log.getLogger(JSON.class);
+    public final static JSON DEFAULT = new JSON();
+
+    private Map<String, Convertor> _convertors = new ConcurrentHashMap<String, Convertor>();
+    private int _stringBufferSize = 1024;
+
+    public JSON()
+    {
+    }
+
+    /**
+     * @return the initial stringBuffer size to use when creating JSON strings
+     *         (default 1024)
+     */
+    public int getStringBufferSize()
+    {
+        return _stringBufferSize;
+    }
+
+    /**
+     * @param stringBufferSize
+     *            the initial stringBuffer size to use when creating JSON
+     *            strings (default 1024)
+     */
+    public void setStringBufferSize(int stringBufferSize)
+    {
+        _stringBufferSize = stringBufferSize;
+    }
+
+    /**
+     * Register a {@link Convertor} for a class or interface.
+     *
+     * @param forClass
+     *            The class or interface that the convertor applies to
+     * @param convertor
+     *            the convertor
+     */
+    public static void registerConvertor(Class forClass, Convertor convertor)
+    {
+        DEFAULT.addConvertor(forClass,convertor);
+    }
+
+    public static JSON getDefault()
+    {
+        return DEFAULT;
+    }
+
+    @Deprecated
+    public static void setDefault(JSON json)
+    {
+    }
+
+    public static String toString(Object object)
+    {
+        StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+        DEFAULT.append(buffer,object);
+        return buffer.toString();
+    }
+
+    public static String toString(Map object)
+    {
+        StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+        DEFAULT.appendMap(buffer,object);
+        return buffer.toString();
+    }
+
+    public static String toString(Object[] array)
+    {
+        StringBuilder buffer = new StringBuilder(DEFAULT.getStringBufferSize());
+        DEFAULT.appendArray(buffer,array);
+        return buffer.toString();
+    }
+
+    /**
+     * @param s
+     *            String containing JSON object or array.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    public static Object parse(String s)
+    {
+        return DEFAULT.parse(new StringSource(s),false);
+    }
+
+    /**
+     * @param s
+     *            String containing JSON object or array.
+     * @param stripOuterComment
+     *            If true, an outer comment around the JSON is ignored.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    public static Object parse(String s, boolean stripOuterComment)
+    {
+        return DEFAULT.parse(new StringSource(s),stripOuterComment);
+    }
+
+    /**
+     * @param in
+     *            Reader containing JSON object or array.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    public static Object parse(Reader in) throws IOException
+    {
+        return DEFAULT.parse(new ReaderSource(in),false);
+    }
+
+    /**
+     * @param in
+     *            Reader containing JSON object or array.
+     * @param stripOuterComment
+     *            If true, an outer comment around the JSON is ignored.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    public static Object parse(Reader in, boolean stripOuterComment) throws IOException
+    {
+        return DEFAULT.parse(new ReaderSource(in),stripOuterComment);
+    }
+
+    /**
+     * @deprecated use {@link #parse(Reader)}
+     * @param in
+     *            Reader containing JSON object or array.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    @Deprecated
+    public static Object parse(InputStream in) throws IOException
+    {
+        return DEFAULT.parse(new StringSource(IO.toString(in)),false);
+    }
+
+    /**
+     * @deprecated use {@link #parse(Reader, boolean)}
+     * @param in
+     *            Stream containing JSON object or array.
+     * @param stripOuterComment
+     *            If true, an outer comment around the JSON is ignored.
+     * @return A Map, Object array or primitive array parsed from the JSON.
+     */
+    @Deprecated
+    public static Object parse(InputStream in, boolean stripOuterComment) throws IOException
+    {
+        return DEFAULT.parse(new StringSource(IO.toString(in)),stripOuterComment);
+    }
+
+    /**
+     * Convert Object to JSON
+     *
+     * @param object
+     *            The object to convert
+     * @return The JSON String
+     */
+    public String toJSON(Object object)
+    {
+        StringBuilder buffer = new StringBuilder(getStringBufferSize());
+        append(buffer,object);
+        return buffer.toString();
+    }
+
+    /**
+     * Convert JSON to Object
+     *
+     * @param json
+     *            The json to convert
+     * @return The object
+     */
+    public Object fromJSON(String json)
+    {
+        Source source = new StringSource(json);
+        return parse(source);
+    }
+
+    @Deprecated
+    public void append(StringBuffer buffer, Object object)
+    {
+        append((Appendable)buffer,object);
+    }
+
+    /**
+     * Append object as JSON to string buffer.
+     *
+     * @param buffer
+     *            the buffer to append to
+     * @param object
+     *            the object to append
+     */
+    public void append(Appendable buffer, Object object)
+    {
+        try
+        {
+            if (object == null)
+            {
+                buffer.append("null");
+            }
+            // Most likely first
+            else if (object instanceof Map)
+            {
+                appendMap(buffer,(Map)object);
+            }
+            else if (object instanceof String)
+            {
+                appendString(buffer,(String)object);
+            }
+            else if (object instanceof Number)
+            {
+                appendNumber(buffer,(Number)object);
+            }
+            else if (object instanceof Boolean)
+            {
+                appendBoolean(buffer,(Boolean)object);
+            }
+            else if (object.getClass().isArray())
+            {
+                appendArray(buffer,object);
+            }
+            else if (object instanceof Character)
+            {
+                appendString(buffer,object.toString());
+            }
+            else if (object instanceof Convertible)
+            {
+                appendJSON(buffer,(Convertible)object);
+            }
+            else if (object instanceof Generator)
+            {
+                appendJSON(buffer,(Generator)object);
+            }
+            else
+            {
+                // Check Convertor before Collection to support JSONCollectionConvertor
+                Convertor convertor = getConvertor(object.getClass());
+                if (convertor != null)
+                {
+                    appendJSON(buffer,convertor,object);
+                }
+                else if (object instanceof Collection)
+                {
+                    appendArray(buffer,(Collection)object);
+                }
+                else
+                {
+                    appendString(buffer,object.toString());
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendNull(StringBuffer buffer)
+    {
+        appendNull((Appendable)buffer);
+    }
+
+    public void appendNull(Appendable buffer)
+    {
+        try
+        {
+            buffer.append("null");
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendJSON(final StringBuffer buffer, final Convertor convertor, final Object object)
+    {
+        appendJSON((Appendable)buffer,convertor,object);
+    }
+
+    public void appendJSON(final Appendable buffer, final Convertor convertor, final Object object)
+    {
+        appendJSON(buffer,new Convertible()
+        {
+            public void fromJSON(Map object)
+            {
+            }
+
+            public void toJSON(Output out)
+            {
+                convertor.toJSON(object,out);
+            }
+        });
+    }
+
+    @Deprecated
+    public void appendJSON(final StringBuffer buffer, Convertible converter)
+    {
+        appendJSON((Appendable)buffer,converter);
+    }
+
+    public void appendJSON(final Appendable buffer, Convertible converter)
+    {
+        ConvertableOutput out=new ConvertableOutput(buffer);
+        converter.toJSON(out);
+        out.complete();
+    }
+
+    @Deprecated
+    public void appendJSON(StringBuffer buffer, Generator generator)
+    {
+        generator.addJSON(buffer);
+    }
+
+    public void appendJSON(Appendable buffer, Generator generator)
+    {
+        generator.addJSON(buffer);
+    }
+
+    @Deprecated
+    public void appendMap(StringBuffer buffer, Map<?,?> map)
+    {
+        appendMap((Appendable)buffer,map);
+    }
+
+    public void appendMap(Appendable buffer, Map<?,?> map)
+    {
+        try
+        {
+            if (map == null)
+            {
+                appendNull(buffer);
+                return;
+            }
+
+            buffer.append('{');
+            Iterator<?> iter = map.entrySet().iterator();
+            while (iter.hasNext())
+            {
+                Map.Entry<?,?> entry = (Map.Entry<?,?>)iter.next();
+                QuotedStringTokenizer.quote(buffer,entry.getKey().toString());
+                buffer.append(':');
+                append(buffer,entry.getValue());
+                if (iter.hasNext())
+                    buffer.append(',');
+            }
+
+            buffer.append('}');
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendArray(StringBuffer buffer, Collection collection)
+    {
+        appendArray((Appendable)buffer,collection);
+    }
+
+    public void appendArray(Appendable buffer, Collection collection)
+    {
+        try
+        {
+            if (collection == null)
+            {
+                appendNull(buffer);
+                return;
+            }
+
+            buffer.append('[');
+            Iterator iter = collection.iterator();
+            boolean first = true;
+            while (iter.hasNext())
+            {
+                if (!first)
+                    buffer.append(',');
+
+                first = false;
+                append(buffer,iter.next());
+            }
+
+            buffer.append(']');
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendArray(StringBuffer buffer, Object array)
+    {
+    appendArray((Appendable)buffer,array);
+    }
+
+    public void appendArray(Appendable buffer, Object array)
+    {
+        try
+        {
+            if (array == null)
+            {
+                appendNull(buffer);
+                return;
+            }
+
+            buffer.append('[');
+            int length = Array.getLength(array);
+
+            for (int i = 0; i < length; i++)
+            {
+                if (i != 0)
+                    buffer.append(',');
+                append(buffer,Array.get(array,i));
+            }
+
+            buffer.append(']');
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendBoolean(StringBuffer buffer, Boolean b)
+    {
+        appendBoolean((Appendable)buffer,b);
+    }
+
+    public void appendBoolean(Appendable buffer, Boolean b)
+    {
+        try
+        {
+            if (b == null)
+            {
+                appendNull(buffer);
+                return;
+            }
+            buffer.append(b?"true":"false");
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendNumber(StringBuffer buffer, Number number)
+    {
+        appendNumber((Appendable)buffer,number);
+    }
+
+    public void appendNumber(Appendable buffer, Number number)
+    {
+        try
+        {
+            if (number == null)
+            {
+                appendNull(buffer);
+                return;
+            }
+            buffer.append(String.valueOf(number));
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Deprecated
+    public void appendString(StringBuffer buffer, String string)
+    {
+        appendString((Appendable)buffer,string);
+    }
+
+    public void appendString(Appendable buffer, String string)
+    {
+        if (string == null)
+        {
+            appendNull(buffer);
+            return;
+        }
+
+        QuotedStringTokenizer.quote(buffer,string);
+    }
+
+    // Parsing utilities
+
+    protected String toString(char[] buffer, int offset, int length)
+    {
+        return new String(buffer,offset,length);
+    }
+
+    protected Map<String, Object> newMap()
+    {
+        return new HashMap<String, Object>();
+    }
+
+    protected Object[] newArray(int size)
+    {
+        return new Object[size];
+    }
+
+    protected JSON contextForArray()
+    {
+        return this;
+    }
+
+    protected JSON contextFor(String field)
+    {
+        return this;
+    }
+
+    protected Object convertTo(Class type, Map map)
+    {
+        if (type != null && Convertible.class.isAssignableFrom(type))
+        {
+            try
+            {
+                Convertible conv = (Convertible)type.newInstance();
+                conv.fromJSON(map);
+                return conv;
+            }
+            catch (Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        Convertor convertor = getConvertor(type);
+        if (convertor != null)
+        {
+            return convertor.fromJSON(map);
+        }
+        return map;
+    }
+
+    /**
+     * Register a {@link Convertor} for a class or interface.
+     *
+     * @param forClass
+     *            The class or interface that the convertor applies to
+     * @param convertor
+     *            the convertor
+     */
+    public void addConvertor(Class forClass, Convertor convertor)
+    {
+        _convertors.put(forClass.getName(),convertor);
+    }
+
+    /**
+     * Lookup a convertor for a class.
+     * <p>
+     * If no match is found for the class, then the interfaces for the class are
+     * tried. If still no match is found, then the super class and it's
+     * interfaces are tried recursively.
+     *
+     * @param forClass
+     *            The class
+     * @return a {@link JSON.Convertor} or null if none were found.
+     */
+    protected Convertor getConvertor(Class forClass)
+    {
+        Class cls = forClass;
+        Convertor convertor = _convertors.get(cls.getName());
+        if (convertor == null && this != DEFAULT)
+            convertor = DEFAULT.getConvertor(cls);
+
+        while (convertor == null && cls != Object.class)
+        {
+            Class[] ifs = cls.getInterfaces();
+            int i = 0;
+            while (convertor == null && ifs != null && i < ifs.length)
+                convertor = _convertors.get(ifs[i++].getName());
+            if (convertor == null)
+            {
+                cls = cls.getSuperclass();
+                convertor = _convertors.get(cls.getName());
+            }
+        }
+        return convertor;
+    }
+
+    /**
+     * Register a {@link JSON.Convertor} for a named class or interface.
+     *
+     * @param name
+     *            name of a class or an interface that the convertor applies to
+     * @param convertor
+     *            the convertor
+     */
+    public void addConvertorFor(String name, Convertor convertor)
+    {
+        _convertors.put(name,convertor);
+    }
+
+    /**
+     * Lookup a convertor for a named class.
+     *
+     * @param name
+     *            name of the class
+     * @return a {@link JSON.Convertor} or null if none were found.
+     */
+    public Convertor getConvertorFor(String name)
+    {
+        Convertor convertor = _convertors.get(name);
+        if (convertor == null && this != DEFAULT)
+            convertor = DEFAULT.getConvertorFor(name);
+        return convertor;
+    }
+
+    public Object parse(Source source, boolean stripOuterComment)
+    {
+        int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
+        if (!stripOuterComment)
+            return parse(source);
+
+        int strip_state = 1; // 0=no strip, 1=wait for /*, 2= wait for */
+
+        Object o = null;
+        while (source.hasNext())
+        {
+            char c = source.peek();
+
+            // handle // or /* comment
+            if (comment_state == 1)
+            {
+                switch (c)
+                {
+                    case '/':
+                        comment_state = -1;
+                        break;
+                    case '*':
+                        comment_state = 2;
+                        if (strip_state == 1)
+                        {
+                            comment_state = 0;
+                            strip_state = 2;
+                        }
+                }
+            }
+            // handle /* */ comment
+            else if (comment_state > 1)
+            {
+                switch (c)
+                {
+                    case '*':
+                        comment_state = 3;
+                        break;
+                    case '/':
+                        if (comment_state == 3)
+                        {
+                            comment_state = 0;
+                            if (strip_state == 2)
+                                return o;
+                        }
+                        else
+                            comment_state = 2;
+                        break;
+                    default:
+                        comment_state = 2;
+                }
+            }
+            // handle // comment
+            else if (comment_state < 0)
+            {
+                switch (c)
+                {
+                    case '\r':
+                    case '\n':
+                        comment_state = 0;
+                    default:
+                        break;
+                }
+            }
+            // handle unknown
+            else
+            {
+                if (!Character.isWhitespace(c))
+                {
+                    if (c == '/')
+                        comment_state = 1;
+                    else if (c == '*')
+                        comment_state = 3;
+                    else if (o == null)
+                    {
+                        o = parse(source);
+                        continue;
+                    }
+                }
+            }
+
+            source.next();
+        }
+
+        return o;
+    }
+
+    public Object parse(Source source)
+    {
+        int comment_state = 0; // 0=no comment, 1="/", 2="/*", 3="/* *" -1="//"
+
+        while (source.hasNext())
+        {
+            char c = source.peek();
+
+            // handle // or /* comment
+            if (comment_state == 1)
+            {
+                switch (c)
+                {
+                    case '/':
+                        comment_state = -1;
+                        break;
+                    case '*':
+                        comment_state = 2;
+                }
+            }
+            // handle /* */ comment
+            else if (comment_state > 1)
+            {
+                switch (c)
+                {
+                    case '*':
+                        comment_state = 3;
+                        break;
+                    case '/':
+                        if (comment_state == 3)
+                            comment_state = 0;
+                        else
+                            comment_state = 2;
+                        break;
+                    default:
+                        comment_state = 2;
+                }
+            }
+            // handle // comment
+            else if (comment_state < 0)
+            {
+                switch (c)
+                {
+                    case '\r':
+                    case '\n':
+                        comment_state = 0;
+                        break;
+                    default:
+                        break;
+                }
+            }
+            // handle unknown
+            else
+            {
+                switch (c)
+                {
+                    case '{':
+                        return parseObject(source);
+                    case '[':
+                        return parseArray(source);
+                    case '"':
+                        return parseString(source);
+                    case '-':
+                        return parseNumber(source);
+
+                    case 'n':
+                        complete("null",source);
+                        return null;
+                    case 't':
+                        complete("true",source);
+                        return Boolean.TRUE;
+                    case 'f':
+                        complete("false",source);
+                        return Boolean.FALSE;
+                    case 'u':
+                        complete("undefined",source);
+                        return null;
+                    case 'N':
+                        complete("NaN",source);
+                        return null;
+
+                    case '/':
+                        comment_state = 1;
+                        break;
+
+                    default:
+                        if (Character.isDigit(c))
+                            return parseNumber(source);
+                        else if (Character.isWhitespace(c))
+                            break;
+                        return handleUnknown(source,c);
+                }
+            }
+            source.next();
+        }
+
+        return null;
+    }
+
+    protected Object handleUnknown(Source source, char c)
+    {
+        throw new IllegalStateException("unknown char '" + c + "'(" + (int)c + ") in " + source);
+    }
+
+    protected Object parseObject(Source source)
+    {
+        if (source.next() != '{')
+            throw new IllegalStateException();
+        Map<String, Object> map = newMap();
+
+        char next = seekTo("\"}",source);
+
+        while (source.hasNext())
+        {
+            if (next == '}')
+            {
+                source.next();
+                break;
+            }
+
+            String name = parseString(source);
+            seekTo(':',source);
+            source.next();
+
+            Object value = contextFor(name).parse(source);
+            map.put(name,value);
+
+            seekTo(",}",source);
+            next = source.next();
+            if (next == '}')
+                break;
+            else
+                next = seekTo("\"}",source);
+        }
+
+        String xclassname = (String)map.get("x-class");
+        if (xclassname != null)
+        {
+            Convertor c = getConvertorFor(xclassname);
+            if (c != null)
+                return c.fromJSON(map);
+            LOG.warn("No Convertor for x-class '{}'", xclassname);
+        }
+
+        String classname = (String)map.get("class");
+        if (classname != null)
+        {
+            try
+            {
+                Class c = Loader.loadClass(JSON.class,classname);
+                return convertTo(c,map);
+            }
+            catch (ClassNotFoundException e)
+            {
+                LOG.warn("No Class for '{}'", classname);
+            }
+        }
+
+        return map;
+    }
+
+    protected Object parseArray(Source source)
+    {
+        if (source.next() != '[')
+            throw new IllegalStateException();
+
+        int size = 0;
+        ArrayList list = null;
+        Object item = null;
+        boolean coma = true;
+
+        while (source.hasNext())
+        {
+            char c = source.peek();
+            switch (c)
+            {
+                case ']':
+                    source.next();
+                    switch (size)
+                    {
+                        case 0:
+                            return newArray(0);
+                        case 1:
+                            Object array = newArray(1);
+                            Array.set(array,0,item);
+                            return array;
+                        default:
+                            return list.toArray(newArray(list.size()));
+                    }
+
+                case ',':
+                    if (coma)
+                        throw new IllegalStateException();
+                    coma = true;
+                    source.next();
+                    break;
+
+                default:
+                    if (Character.isWhitespace(c))
+                        source.next();
+                    else
+                    {
+                        coma = false;
+                        if (size++ == 0)
+                            item = contextForArray().parse(source);
+                        else if (list == null)
+                        {
+                            list = new ArrayList();
+                            list.add(item);
+                            item = contextForArray().parse(source);
+                            list.add(item);
+                            item = null;
+                        }
+                        else
+                        {
+                            item = contextForArray().parse(source);
+                            list.add(item);
+                            item = null;
+                        }
+                    }
+            }
+
+        }
+
+        throw new IllegalStateException("unexpected end of array");
+    }
+
+    protected String parseString(Source source)
+    {
+        if (source.next() != '"')
+            throw new IllegalStateException();
+
+        boolean escape = false;
+
+        StringBuilder b = null;
+        final char[] scratch = source.scratchBuffer();
+
+        if (scratch != null)
+        {
+            int i = 0;
+            while (source.hasNext())
+            {
+                if (i >= scratch.length)
+                {
+                    // we have filled the scratch buffer, so we must
+                    // use the StringBuffer for a large string
+                    b = new StringBuilder(scratch.length * 2);
+                    b.append(scratch,0,i);
+                    break;
+                }
+
+                char c = source.next();
+
+                if (escape)
+                {
+                    escape = false;
+                    switch (c)
+                    {
+                        case '"':
+                            scratch[i++] = '"';
+                            break;
+                        case '\\':
+                            scratch[i++] = '\\';
+                            break;
+                        case '/':
+                            scratch[i++] = '/';
+                            break;
+                        case 'b':
+                            scratch[i++] = '\b';
+                            break;
+                        case 'f':
+                            scratch[i++] = '\f';
+                            break;
+                        case 'n':
+                            scratch[i++] = '\n';
+                            break;
+                        case 'r':
+                            scratch[i++] = '\r';
+                            break;
+                        case 't':
+                            scratch[i++] = '\t';
+                            break;
+                        case 'u':
+                            char uc = (char)((TypeUtil.convertHexDigit((byte)source.next()) << 12) + (TypeUtil.convertHexDigit((byte)source.next()) << 8)
+                                    + (TypeUtil.convertHexDigit((byte)source.next()) << 4) + (TypeUtil.convertHexDigit((byte)source.next())));
+                            scratch[i++] = uc;
+                            break;
+                        default:
+                            scratch[i++] = c;
+                    }
+                }
+                else if (c == '\\')
+                {
+                    escape = true;
+                }
+                else if (c == '\"')
+                {
+                    // Return string that fits within scratch buffer
+                    return toString(scratch,0,i);
+                }
+                else
+                {
+                    scratch[i++] = c;
+                }
+            }
+
+            // Missing end quote, but return string anyway ?
+            if (b == null)
+                return toString(scratch,0,i);
+        }
+        else
+            b = new StringBuilder(getStringBufferSize());
+
+        // parse large string into string buffer
+        final StringBuilder builder=b;
+        while (source.hasNext())
+        {
+            char c = source.next();
+
+            if (escape)
+            {
+                escape = false;
+                switch (c)
+                {
+                    case '"':
+                        builder.append('"');
+                        break;
+                    case '\\':
+                        builder.append('\\');
+                        break;
+                    case '/':
+                        builder.append('/');
+                        break;
+                    case 'b':
+                        builder.append('\b');
+                        break;
+                    case 'f':
+                        builder.append('\f');
+                        break;
+                    case 'n':
+                        builder.append('\n');
+                        break;
+                    case 'r':
+                        builder.append('\r');
+                        break;
+                    case 't':
+                        builder.append('\t');
+                        break;
+                    case 'u':
+                        char uc = (char)((TypeUtil.convertHexDigit((byte)source.next()) << 12) + (TypeUtil.convertHexDigit((byte)source.next()) << 8)
+                                + (TypeUtil.convertHexDigit((byte)source.next()) << 4) + (TypeUtil.convertHexDigit((byte)source.next())));
+                        builder.append(uc);
+                        break;
+                    default:
+                        builder.append(c);
+                }
+            }
+            else if (c == '\\')
+            {
+                escape = true;
+            }
+            else if (c == '\"')
+            {
+                break;
+            }
+            else
+            {
+                builder.append(c);
+            }
+        }
+        return builder.toString();
+    }
+
+    public Number parseNumber(Source source)
+    {
+        boolean minus = false;
+        long number = 0;
+        StringBuilder buffer = null;
+
+        longLoop: while (source.hasNext())
+        {
+            char c = source.peek();
+            switch (c)
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                    number = number * 10 + (c - '0');
+                    source.next();
+                    break;
+
+                case '-':
+                case '+':
+                    if (number != 0)
+                        throw new IllegalStateException("bad number");
+                    minus = true;
+                    source.next();
+                    break;
+
+                case '.':
+                case 'e':
+                case 'E':
+                    buffer = new StringBuilder(16);
+                    if (minus)
+                        buffer.append('-');
+                    buffer.append(number);
+                    buffer.append(c);
+                    source.next();
+                    break longLoop;
+
+                default:
+                    break longLoop;
+            }
+        }
+
+        if (buffer == null)
+            return minus ? -1 * number : number;
+
+        doubleLoop: while (source.hasNext())
+        {
+            char c = source.peek();
+            switch (c)
+            {
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                case '-':
+                case '.':
+                case '+':
+                case 'e':
+                case 'E':
+                    buffer.append(c);
+                    source.next();
+                    break;
+
+                default:
+                    break doubleLoop;
+            }
+        }
+        return new Double(buffer.toString());
+
+    }
+
+    protected void seekTo(char seek, Source source)
+    {
+        while (source.hasNext())
+        {
+            char c = source.peek();
+            if (c == seek)
+                return;
+
+            if (!Character.isWhitespace(c))
+                throw new IllegalStateException("Unexpected '" + c + " while seeking '" + seek + "'");
+            source.next();
+        }
+
+        throw new IllegalStateException("Expected '" + seek + "'");
+    }
+
+    protected char seekTo(String seek, Source source)
+    {
+        while (source.hasNext())
+        {
+            char c = source.peek();
+            if (seek.indexOf(c) >= 0)
+            {
+                return c;
+            }
+
+            if (!Character.isWhitespace(c))
+                throw new IllegalStateException("Unexpected '" + c + "' while seeking one of '" + seek + "'");
+            source.next();
+        }
+
+        throw new IllegalStateException("Expected one of '" + seek + "'");
+    }
+
+    protected static void complete(String seek, Source source)
+    {
+        int i = 0;
+        while (source.hasNext() && i < seek.length())
+        {
+            char c = source.next();
+            if (c != seek.charAt(i++))
+                throw new IllegalStateException("Unexpected '" + c + " while seeking  \"" + seek + "\"");
+        }
+
+        if (i < seek.length())
+            throw new IllegalStateException("Expected \"" + seek + "\"");
+    }
+
+    private final class ConvertableOutput implements Output
+    {
+        private final Appendable _buffer;
+        char c = '{';
+
+        private ConvertableOutput(Appendable buffer)
+        {
+            _buffer = buffer;
+        }
+
+        public void complete()
+        {
+            try
+            {
+                if (c == '{')
+                    _buffer.append("{}");
+                else if (c != 0)
+                    _buffer.append("}");
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void add(Object obj)
+        {
+            if (c == 0)
+                throw new IllegalStateException();
+            append(_buffer,obj);
+            c = 0;
+        }
+
+        public void addClass(Class type)
+        {
+            try
+            {
+                if (c == 0)
+                    throw new IllegalStateException();
+                _buffer.append(c);
+                _buffer.append("\"class\":");
+                append(_buffer,type.getName());
+                c = ',';
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void add(String name, Object value)
+        {
+            try
+            {
+                if (c == 0)
+                    throw new IllegalStateException();
+                _buffer.append(c);
+                QuotedStringTokenizer.quote(_buffer,name);
+                _buffer.append(':');
+                append(_buffer,value);
+                c = ',';
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void add(String name, double value)
+        {
+            try
+            {
+                if (c == 0)
+                    throw new IllegalStateException();
+                _buffer.append(c);
+                QuotedStringTokenizer.quote(_buffer,name);
+                _buffer.append(':');
+                appendNumber(_buffer, value);
+                c = ',';
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void add(String name, long value)
+        {
+            try
+            {
+                if (c == 0)
+                    throw new IllegalStateException();
+                _buffer.append(c);
+                QuotedStringTokenizer.quote(_buffer,name);
+                _buffer.append(':');
+                appendNumber(_buffer, value);
+                c = ',';
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void add(String name, boolean value)
+        {
+            try
+            {
+                if (c == 0)
+                    throw new IllegalStateException();
+                _buffer.append(c);
+                QuotedStringTokenizer.quote(_buffer,name);
+                _buffer.append(':');
+                appendBoolean(_buffer,value?Boolean.TRUE:Boolean.FALSE);
+                c = ',';
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public interface Source
+    {
+        boolean hasNext();
+
+        char next();
+
+        char peek();
+
+        char[] scratchBuffer();
+    }
+
+    public static class StringSource implements Source
+    {
+        private final String string;
+        private int index;
+        private char[] scratch;
+
+        public StringSource(String s)
+        {
+            string = s;
+        }
+
+        public boolean hasNext()
+        {
+            if (index < string.length())
+                return true;
+            scratch = null;
+            return false;
+        }
+
+        public char next()
+        {
+            return string.charAt(index++);
+        }
+
+        public char peek()
+        {
+            return string.charAt(index);
+        }
+
+        @Override
+        public String toString()
+        {
+            return string.substring(0,index) + "|||" + string.substring(index);
+        }
+
+        public char[] scratchBuffer()
+        {
+            if (scratch == null)
+                scratch = new char[string.length()];
+            return scratch;
+        }
+    }
+
+    public static class ReaderSource implements Source
+    {
+        private Reader _reader;
+        private int _next = -1;
+        private char[] scratch;
+
+        public ReaderSource(Reader r)
+        {
+            _reader = r;
+        }
+
+        public void setReader(Reader reader)
+        {
+            _reader = reader;
+            _next = -1;
+        }
+
+        public boolean hasNext()
+        {
+            getNext();
+            if (_next < 0)
+            {
+                scratch = null;
+                return false;
+            }
+            return true;
+        }
+
+        public char next()
+        {
+            getNext();
+            char c = (char)_next;
+            _next = -1;
+            return c;
+        }
+
+        public char peek()
+        {
+            getNext();
+            return (char)_next;
+        }
+
+        private void getNext()
+        {
+            if (_next < 0)
+            {
+                try
+                {
+                    _next = _reader.read();
+                }
+                catch (IOException e)
+                {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        public char[] scratchBuffer()
+        {
+            if (scratch == null)
+                scratch = new char[1024];
+            return scratch;
+        }
+
+    }
+
+    /**
+     * JSON Output class for use by {@link Convertible}.
+     */
+    public interface Output
+    {
+        public void addClass(Class c);
+
+        public void add(Object obj);
+
+        public void add(String name, Object value);
+
+        public void add(String name, double value);
+
+        public void add(String name, long value);
+
+        public void add(String name, boolean value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * JSON Convertible object. Object can implement this interface in a similar
+     * way to the {@link Externalizable} interface is used to allow classes to
+     * provide their own serialization mechanism.
+     * <p>
+     * A JSON.Convertible object may be written to a JSONObject or initialized
+     * from a Map of field names to values.
+     * <p>
+     * If the JSON is to be convertible back to an Object, then the method
+     * {@link Output#addClass(Class)} must be called from within toJSON()
+     *
+     */
+    public interface Convertible
+    {
+        public void toJSON(Output out);
+
+        public void fromJSON(Map object);
+    }
+
+    /**
+     * Static JSON Convertor.
+     * <p>
+     * may be implemented to provide static convertors for objects that may be
+     * registered with
+     * {@link JSON#registerConvertor(Class, org.eclipse.jetty.util.ajax.JSON.Convertor)}
+     * . These convertors are looked up by class, interface and super class by
+     * {@link JSON#getConvertor(Class)}. Convertors should be used when the
+     * classes to be converted cannot implement {@link Convertible} or
+     * {@link Generator}.
+     */
+    public interface Convertor
+    {
+        public void toJSON(Object obj, Output out);
+
+        public Object fromJSON(Map object);
+    }
+
+    /**
+     * JSON Generator. A class that can add it's JSON representation directly to
+     * a StringBuffer. This is useful for object instances that are frequently
+     * converted and wish to avoid multiple Conversions
+     */
+    public interface Generator
+    {
+        public void addJSON(Appendable buffer);
+    }
+
+    /**
+     * A Literal JSON generator A utility instance of {@link JSON.Generator}
+     * that holds a pre-generated string on JSON text.
+     */
+    public static class Literal implements Generator
+    {
+        private String _json;
+
+        /**
+         * Construct a literal JSON instance for use by
+         * {@link JSON#toString(Object)}. If {@link Log#isDebugEnabled()} is
+         * true, the JSON will be parsed to check validity
+         *
+         * @param json
+         *            A literal JSON string.
+         */
+        public Literal(String json)
+        {
+            if (LOG.isDebugEnabled()) // TODO: Make this a configurable option on JSON instead!
+                parse(json);
+            _json = json;
+        }
+
+        @Override
+        public String toString()
+        {
+            return _json;
+        }
+
+        public void addJSON(Appendable buffer)
+        {
+            try
+            {
+                buffer.append(_json);
+            }
+            catch(IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java b/src/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java
new file mode 100644
index 0000000..cd75cb3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java
@@ -0,0 +1,50 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.jetty.util.Loader;
+
+public class JSONCollectionConvertor implements JSON.Convertor
+{
+    public void toJSON(Object obj, JSON.Output out)
+    {
+        out.addClass(obj.getClass());
+        out.add("list", ((Collection)obj).toArray());
+    }
+
+    public Object fromJSON(Map object)
+    {
+        try
+        {
+            Collection result = (Collection)Loader.loadClass(getClass(), (String)object.get("class")).newInstance();
+            Collections.addAll(result, (Object[])object.get("list"));
+            return result;
+        }
+        catch (Exception x)
+        {
+            if (x instanceof RuntimeException)
+                throw (RuntimeException)x;
+            throw new RuntimeException(x);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java b/src/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java
new file mode 100644
index 0000000..e0c31ac
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java
@@ -0,0 +1,107 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.eclipse.jetty.util.DateCache;
+import org.eclipse.jetty.util.ajax.JSON.Output;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+* Convert a {@link Date} to JSON.
+* If fromJSON is true in the constructor, the JSON generated will
+* be of the form {class="java.util.Date",value="1/1/1970 12:00 GMT"}
+* If fromJSON is false, then only the string value of the date is generated.
+*/
+public class JSONDateConvertor implements JSON.Convertor
+{
+    private static final Logger LOG = Log.getLogger(JSONDateConvertor.class);
+
+    private final boolean _fromJSON;
+    private final DateCache _dateCache;
+    private final SimpleDateFormat _format;
+
+    public JSONDateConvertor()
+    {
+        this(false);
+    }
+
+    public JSONDateConvertor(boolean fromJSON)
+    {
+        this(DateCache.DEFAULT_FORMAT,TimeZone.getTimeZone("GMT"),fromJSON);
+    }
+
+    public JSONDateConvertor(String format,TimeZone zone,boolean fromJSON)
+    {
+        _dateCache=new DateCache(format);
+        _dateCache.setTimeZone(zone);
+        _fromJSON=fromJSON;
+        _format=new SimpleDateFormat(format);
+        _format.setTimeZone(zone);
+    }
+
+    public JSONDateConvertor(String format, TimeZone zone, boolean fromJSON, Locale locale)
+    {
+        _dateCache = new DateCache(format, locale);
+        _dateCache.setTimeZone(zone);
+        _fromJSON = fromJSON;
+        _format = new SimpleDateFormat(format, new DateFormatSymbols(locale));
+        _format.setTimeZone(zone);
+    }
+
+    public Object fromJSON(Map map)
+    {
+        if (!_fromJSON)
+            throw new UnsupportedOperationException();
+        try
+        {
+            synchronized(_format)
+            {
+                return _format.parseObject((String)map.get("value"));
+            }
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+        return null;
+    }
+
+    public void toJSON(Object obj, Output out)
+    {
+        String date = _dateCache.format((Date)obj);
+        if (_fromJSON)
+        {
+            out.addClass(obj.getClass());
+            out.add("value",date);
+        }
+        else
+        {
+            out.add(date);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java b/src/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java
new file mode 100644
index 0000000..9b63547
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java
@@ -0,0 +1,93 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.ajax.JSON.Output;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Convert an {@link Enum} to JSON.
+ * If fromJSON is true in the constructor, the JSON generated will
+ * be of the form {class="com.acme.TrafficLight",value="Green"}
+ * If fromJSON is false, then only the string value of the enum is generated.
+ *
+ *
+ */
+public class JSONEnumConvertor implements JSON.Convertor
+{
+    private static final Logger LOG = Log.getLogger(JSONEnumConvertor.class);
+    private boolean _fromJSON;
+    private Method _valueOf;
+    {
+        try
+        {
+            Class<?> e = Loader.loadClass(getClass(),"java.lang.Enum");
+            _valueOf=e.getMethod("valueOf",Class.class,String.class);
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException("!Enums",e);
+        }
+    }
+
+    public JSONEnumConvertor()
+    {
+        this(false);
+    }
+
+    public JSONEnumConvertor(boolean fromJSON)
+    {
+        _fromJSON=fromJSON;
+    }
+
+    public Object fromJSON(Map map)
+    {
+        if (!_fromJSON)
+            throw new UnsupportedOperationException();
+        try
+        {
+            Class c=Loader.loadClass(getClass(),(String)map.get("class"));
+            return _valueOf.invoke(null,c,map.get("value"));
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+        return null;
+    }
+
+    public void toJSON(Object obj, Output out)
+    {
+        if (_fromJSON)
+        {
+            out.addClass(obj.getClass());
+            out.add("value",((Enum)obj).name());
+        }
+        else
+        {
+            out.add(((Enum)obj).name());
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java b/src/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java
new file mode 100755
index 0000000..d0c222e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java
@@ -0,0 +1,115 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jetty.util.ajax.JSON.Output;
+
+/* ------------------------------------------------------------ */
+/**
+ * Convert an Object to JSON using reflection on getters methods.
+ * 
+ * 
+ *
+ */
+public class JSONObjectConvertor implements JSON.Convertor
+{
+    private boolean _fromJSON;
+    private Set _excluded=null;
+
+    public JSONObjectConvertor()
+    {
+        _fromJSON=false;
+    }
+    
+    public JSONObjectConvertor(boolean fromJSON)
+    {
+        _fromJSON=fromJSON;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param fromJSON
+     * @param excluded An array of field names to exclude from the conversion
+     */
+    public JSONObjectConvertor(boolean fromJSON,String[] excluded)
+    {
+        _fromJSON=fromJSON;
+        if (excluded!=null)
+            _excluded=new HashSet(Arrays.asList(excluded));
+    }
+
+    public Object fromJSON(Map map)
+    {
+        if (_fromJSON)
+            throw new UnsupportedOperationException();
+        return map;
+    }
+
+    public void toJSON(Object obj, Output out)
+    {
+        try
+        {
+            Class c=obj.getClass();
+
+            if (_fromJSON)
+                out.addClass(obj.getClass());
+
+            Method[] methods = obj.getClass().getMethods();
+
+            for (int i=0;i<methods.length;i++)
+            {
+                Method m=methods[i];
+                if (!Modifier.isStatic(m.getModifiers()) &&  
+                        m.getParameterTypes().length==0 && 
+                        m.getReturnType()!=null &&
+                        m.getDeclaringClass()!=Object.class)
+                {
+                    String name=m.getName();
+                    if (name.startsWith("is"))
+                        name=name.substring(2,3).toLowerCase(Locale.ENGLISH)+name.substring(3);
+                    else if (name.startsWith("get"))
+                        name=name.substring(3,4).toLowerCase(Locale.ENGLISH)+name.substring(4);
+                    else
+                        continue;
+
+                    if (includeField(name,obj,m))
+                        out.add(name, m.invoke(obj,(Object[])null));
+                }
+            }
+        } 
+        catch (Throwable e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+    
+    protected boolean includeField(String name, Object o, Method m)
+    {
+        return _excluded==null || !_excluded.contains(name);
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertor.java b/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertor.java
new file mode 100644
index 0000000..b1867cc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertor.java
@@ -0,0 +1,431 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jetty.util.ajax.JSON.Output;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+/**
+ * Converts POJOs to JSON and vice versa.
+ * The key difference:
+ *  - returns the actual object from Convertor.fromJSON (JSONObjectConverter returns a Map)
+ *  - the getters/setters are resolved at initialization (JSONObjectConverter resolves it at runtime)
+ *  - correctly sets the number fields
+ * 
+ */
+public class JSONPojoConvertor implements JSON.Convertor
+{
+    private static final Logger LOG = Log.getLogger(JSONPojoConvertor.class);
+    public static final Object[] GETTER_ARG = new Object[]{}, NULL_ARG = new Object[]{null};
+    private static final Map<Class<?>, NumberType> __numberTypes = new HashMap<Class<?>, NumberType>();
+    
+    public static NumberType getNumberType(Class<?> clazz)
+    {
+        return __numberTypes.get(clazz);
+    }
+    
+    protected boolean _fromJSON;
+    protected Class<?> _pojoClass;
+    protected Map<String,Method> _getters = new HashMap<String,Method>();
+    protected Map<String,Setter> _setters = new HashMap<String,Setter>();
+    protected Set<String> _excluded;
+
+    /**
+     * @param pojoClass The class to convert
+     */
+    public JSONPojoConvertor(Class<?> pojoClass)
+    {
+        this(pojoClass, (Set<String>)null, true);
+    }
+
+    /**
+     * @param pojoClass The class to convert
+     * @param excluded The fields to exclude
+     */
+    public JSONPojoConvertor(Class<?> pojoClass, String[] excluded)
+    {
+        this(pojoClass, new HashSet<String>(Arrays.asList(excluded)), true);
+    }
+
+    /**
+     * @param pojoClass The class to convert
+     * @param excluded The fields to exclude
+     */
+    public JSONPojoConvertor(Class<?> pojoClass, Set<String> excluded)
+    {
+        this(pojoClass, excluded, true);
+    }
+
+    /**
+     * @param pojoClass The class to convert
+     * @param excluded The fields to exclude
+     * @param fromJSON If true, add a class field to the JSON
+     */
+    public JSONPojoConvertor(Class<?> pojoClass, Set<String> excluded, boolean fromJSON)
+    {
+        _pojoClass = pojoClass;
+        _excluded = excluded;
+        _fromJSON = fromJSON;
+        init();
+    }    
+
+    /**
+     * @param pojoClass The class to convert
+     * @param fromJSON If true, add a class field to the JSON
+     */
+    public JSONPojoConvertor(Class<?> pojoClass, boolean fromJSON)
+    {
+        this(pojoClass, (Set<String>)null, fromJSON);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void init()
+    {
+        Method[] methods = _pojoClass.getMethods();
+        for (int i=0;i<methods.length;i++)
+        {
+            Method m=methods[i];
+            if (!Modifier.isStatic(m.getModifiers()) && m.getDeclaringClass()!=Object.class)
+            {
+                String name=m.getName();
+                switch(m.getParameterTypes().length)
+                {
+                    case 0:
+                        
+                        if(m.getReturnType()!=null)
+                        {
+                            if (name.startsWith("is") && name.length()>2)
+                                name=name.substring(2,3).toLowerCase(Locale.ENGLISH)+name.substring(3);
+                            else if (name.startsWith("get") && name.length()>3)
+                                name=name.substring(3,4).toLowerCase(Locale.ENGLISH)+name.substring(4);
+                            else 
+                                break;
+                            if(includeField(name, m))
+                                addGetter(name, m);
+                        }
+                        break;
+                    case 1:
+                        if (name.startsWith("set") && name.length()>3)
+                        {
+                            name=name.substring(3,4).toLowerCase(Locale.ENGLISH)+name.substring(4);
+                            if(includeField(name, m))
+                                addSetter(name, m);
+                        }
+                        break;                
+                }
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void addGetter(String name, Method method)
+    {
+        _getters.put(name, method);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void addSetter(String name, Method method)
+    {
+        _setters.put(name, new Setter(name, method));
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected Setter getSetter(String name)
+    {
+        return _setters.get(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected boolean includeField(String name, Method m)
+    {
+        return _excluded==null || !_excluded.contains(name);
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected int getExcludedCount()
+    {
+        return _excluded==null ? 0 : _excluded.size();
+    }
+
+    /* ------------------------------------------------------------ */
+    public Object fromJSON(Map object)
+    {        
+        Object obj = null;
+        try
+        {
+            obj = _pojoClass.newInstance();
+        }
+        catch(Exception e)
+        {
+            // TODO return Map instead?
+            throw new RuntimeException(e);
+        }
+        
+        setProps(obj, object);
+        return obj;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public int setProps(Object obj, Map<?,?> props)
+    {
+        int count = 0;
+        for(Iterator<?> iterator = props.entrySet().iterator(); iterator.hasNext();)
+        {
+            Map.Entry<?, ?> entry = (Map.Entry<?,?>) iterator.next();
+            Setter setter = getSetter((String)entry.getKey());
+            if(setter!=null)
+            {
+                try
+                {
+                    setter.invoke(obj, entry.getValue());                    
+                    count++;
+                }
+                catch(Exception e)
+                {
+                    // TODO throw exception?
+                    LOG.warn(_pojoClass.getName()+"#"+setter.getPropertyName()+" not set from "+
+                            (entry.getValue().getClass().getName())+"="+entry.getValue().toString());
+                    log(e);
+                }
+            }
+        }
+        return count;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void toJSON(Object obj, Output out)
+    {
+        if(_fromJSON)
+            out.addClass(_pojoClass);
+        for(Map.Entry<String,Method> entry : _getters.entrySet())
+        {            
+            try
+            {
+                out.add(entry.getKey(), entry.getValue().invoke(obj, GETTER_ARG));                    
+            }
+            catch(Exception e)
+            {
+                // TODO throw exception?
+                LOG.warn("{} property '{}' excluded. (errors)", _pojoClass.getName(), 
+                        entry.getKey());
+                log(e);
+            }
+        }        
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void log(Throwable t)
+    {
+        LOG.ignore(t);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static class Setter
+    {
+        protected String _propertyName;
+        protected Method _setter;
+        protected NumberType _numberType;
+        protected Class<?> _type;
+        protected Class<?> _componentType;
+        
+        public Setter(String propertyName, Method method)
+        {
+            _propertyName = propertyName;
+            _setter = method;
+            _type = method.getParameterTypes()[0];
+            _numberType = __numberTypes.get(_type);
+            if(_numberType==null && _type.isArray())
+            {
+                _componentType = _type.getComponentType();
+                _numberType = __numberTypes.get(_componentType);
+            }
+        }
+        
+        public String getPropertyName()
+        {
+            return _propertyName;
+        }
+        
+        public Method getMethod()
+        {
+            return _setter;
+        }
+        
+        public NumberType getNumberType()
+        {
+            return _numberType;
+        }
+        
+        public Class<?> getType()
+        {
+            return _type;
+        }
+        
+        public Class<?> getComponentType()
+        {
+            return _componentType;
+        }
+        
+        public boolean isPropertyNumber()
+        {
+            return _numberType!=null;
+        }
+        
+        public void invoke(Object obj, Object value) throws IllegalArgumentException, 
+        IllegalAccessException, InvocationTargetException
+        {
+            if(value==null)
+                _setter.invoke(obj, NULL_ARG);
+            else
+                invokeObject(obj, value);
+        }
+        
+        protected void invokeObject(Object obj, Object value) throws IllegalArgumentException, 
+            IllegalAccessException, InvocationTargetException
+        {
+            
+            if (_type.isEnum())
+            {
+                if (value instanceof Enum)
+                    _setter.invoke(obj, new Object[]{value});
+                else
+                    _setter.invoke(obj, new Object[]{Enum.valueOf((Class<? extends Enum>)_type,value.toString())});
+            }
+            else if(_numberType!=null && value instanceof Number)
+            {
+                _setter.invoke(obj, new Object[]{_numberType.getActualValue((Number)value)});
+            }
+            else if (Character.TYPE.equals(_type) || Character.class.equals(_type))
+            {
+                _setter.invoke(obj, new Object[]{String.valueOf(value).charAt(0)});
+            }
+            else if(_componentType!=null && value.getClass().isArray())
+            {
+                if(_numberType==null)
+                {
+                    int len = Array.getLength(value);
+                    Object array = Array.newInstance(_componentType, len);
+                    try
+                    {
+                        System.arraycopy(value, 0, array, 0, len);
+                    }
+                    catch(Exception e)
+                    {                        
+                        // unusual array with multiple types
+                        LOG.ignore(e);
+                        _setter.invoke(obj, new Object[]{value});
+                        return;
+                    }                    
+                    _setter.invoke(obj, new Object[]{array});
+                }
+                else
+                {
+                    Object[] old = (Object[])value;
+                    Object array = Array.newInstance(_componentType, old.length);
+                    try
+                    {
+                        for(int i=0; i<old.length; i++)
+                            Array.set(array, i, _numberType.getActualValue((Number)old[i]));
+                    }
+                    catch(Exception e)
+                    {                        
+                        // unusual array with multiple types
+                        LOG.ignore(e);
+                        _setter.invoke(obj, new Object[]{value});
+                        return;
+                    }
+                    _setter.invoke(obj, new Object[]{array});
+                }
+            }
+            else
+                _setter.invoke(obj, new Object[]{value});
+        }
+    }
+    
+    public interface NumberType
+    {        
+        public Object getActualValue(Number number);     
+    }
+    
+    public static final NumberType SHORT = new NumberType()
+    {
+        public Object getActualValue(Number number)
+        {            
+            return new Short(number.shortValue());
+        } 
+    };
+
+    public static final NumberType INTEGER = new NumberType()
+    {
+        public Object getActualValue(Number number)
+        {            
+            return new Integer(number.intValue());
+        }
+    };
+    
+    public static final NumberType FLOAT = new NumberType()
+    {
+        public Object getActualValue(Number number)
+        {            
+            return new Float(number.floatValue());
+        }      
+    };
+
+    public static final NumberType LONG = new NumberType()
+    {
+        public Object getActualValue(Number number)
+        {            
+            return number instanceof Long ? number : new Long(number.longValue());
+        }     
+    };
+
+    public static final NumberType DOUBLE = new NumberType()
+    {
+        public Object getActualValue(Number number)
+        {            
+            return number instanceof Double ? number : new Double(number.doubleValue());
+        }       
+    };
+
+    static
+    {
+        __numberTypes.put(Short.class, SHORT);
+        __numberTypes.put(Short.TYPE, SHORT);
+        __numberTypes.put(Integer.class, INTEGER);
+        __numberTypes.put(Integer.TYPE, INTEGER);
+        __numberTypes.put(Long.class, LONG);
+        __numberTypes.put(Long.TYPE, LONG);
+        __numberTypes.put(Float.class, FLOAT);
+        __numberTypes.put(Float.TYPE, FLOAT);
+        __numberTypes.put(Double.class, DOUBLE);
+        __numberTypes.put(Double.TYPE, DOUBLE);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java b/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java
new file mode 100644
index 0000000..18fc8ee
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java
@@ -0,0 +1,110 @@
+//
+//  ========================================================================
+//  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.util.ajax;
+
+import java.util.Map;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.ajax.JSON.Convertor;
+import org.eclipse.jetty.util.ajax.JSON.Output;
+
+public class JSONPojoConvertorFactory implements JSON.Convertor
+{
+    private final JSON _json;
+    private final boolean _fromJson;
+
+    public JSONPojoConvertorFactory(JSON json)
+    {
+        if (json==null)
+        {
+            throw new IllegalArgumentException();
+        }
+        _json=json;
+        _fromJson=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param json The JSON instance to use
+     * @param fromJSON If true, the class name of the objects is included
+     * in the generated JSON and is used to instantiate the object when
+     * JSON is parsed (otherwise a Map is used).
+     */
+    public JSONPojoConvertorFactory(JSON json,boolean fromJSON)
+    {
+        if (json==null)
+        {
+            throw new IllegalArgumentException();
+        }
+        _json=json;
+        _fromJson=fromJSON;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void toJSON(Object obj, Output out)
+    {
+        String clsName=obj.getClass().getName();
+        Convertor convertor=_json.getConvertorFor(clsName);
+        if (convertor==null)
+        {
+            try
+            {
+                Class cls=Loader.loadClass(JSON.class,clsName);
+                convertor=new JSONPojoConvertor(cls,_fromJson);
+                _json.addConvertorFor(clsName, convertor);
+             }
+            catch (ClassNotFoundException e)
+            {
+                JSON.LOG.warn(e);
+            }
+        }
+        if (convertor!=null)
+        {
+            convertor.toJSON(obj, out);
+        }
+    }
+
+    public Object fromJSON(Map object)
+    {
+        Map map=object;
+        String clsName=(String)map.get("class");
+        if (clsName!=null)
+        {
+            Convertor convertor=_json.getConvertorFor(clsName);
+            if (convertor==null)
+            {
+                try
+                {
+                    Class cls=Loader.loadClass(JSON.class,clsName);
+                    convertor=new JSONPojoConvertor(cls,_fromJson);
+                    _json.addConvertorFor(clsName, convertor);
+                }
+                catch (ClassNotFoundException e)
+                {
+                    JSON.LOG.warn(e);
+                }
+            }
+            if (convertor!=null)
+            {
+                return convertor.fromJSON(object);
+            }
+        }
+        return map;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/src/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java
new file mode 100644
index 0000000..ec3dd0e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java
@@ -0,0 +1,217 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Basic implementation of the life cycle interface for components.
+ * 
+ * 
+ */
+public abstract class AbstractLifeCycle implements LifeCycle
+{
+    private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class);
+    public static final String STOPPED="STOPPED";
+    public static final String FAILED="FAILED";
+    public static final String STARTING="STARTING";
+    public static final String STARTED="STARTED";
+    public static final String STOPPING="STOPPING";
+    public static final String RUNNING="RUNNING";
+    
+    private final Object _lock = new Object();
+    private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3;
+    private volatile int _state = __STOPPED;
+    
+    protected final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>();
+
+    protected void doStart() throws Exception
+    {
+    }
+
+    protected void doStop() throws Exception
+    {
+    }
+
+    public final void start() throws Exception
+    {
+        synchronized (_lock)
+        {
+            try
+            {
+                if (_state == __STARTED || _state == __STARTING)
+                    return;
+                setStarting();
+                doStart();
+                setStarted();
+            }
+            catch (Exception e)
+            {
+                setFailed(e);
+                throw e;
+            }
+            catch (Error e)
+            {
+                setFailed(e);
+                throw e;
+            }
+        }
+    }
+
+    public final void stop() throws Exception
+    {
+        synchronized (_lock)
+        {
+            try
+            {
+                if (_state == __STOPPING || _state == __STOPPED)
+                    return;
+                setStopping();
+                doStop();
+                setStopped();
+            }
+            catch (Exception e)
+            {
+                setFailed(e);
+                throw e;
+            }
+            catch (Error e)
+            {
+                setFailed(e);
+                throw e;
+            }
+        }
+    }
+
+    public boolean isRunning()
+    {
+        final int state = _state;
+        
+        return state == __STARTED || state == __STARTING;
+    }
+
+    public boolean isStarted()
+    {
+        return _state == __STARTED;
+    }
+
+    public boolean isStarting()
+    {
+        return _state == __STARTING;
+    }
+
+    public boolean isStopping()
+    {
+        return _state == __STOPPING;
+    }
+
+    public boolean isStopped()
+    {
+        return _state == __STOPPED;
+    }
+
+    public boolean isFailed()
+    {
+        return _state == __FAILED;
+    }
+
+    public void addLifeCycleListener(LifeCycle.Listener listener)
+    {
+        _listeners.add(listener);
+    }
+
+    public void removeLifeCycleListener(LifeCycle.Listener listener)
+    {
+        _listeners.remove(listener);
+    }
+    
+    public String getState()
+    {
+        switch(_state)
+        {
+            case __FAILED: return FAILED;
+            case __STARTING: return STARTING;
+            case __STARTED: return STARTED;
+            case __STOPPING: return STOPPING;
+            case __STOPPED: return STOPPED;
+        }
+        return null;
+    }
+    
+    public static String getState(LifeCycle lc)
+    {
+        if (lc.isStarting()) return STARTING;
+        if (lc.isStarted()) return STARTED;
+        if (lc.isStopping()) return STOPPING;
+        if (lc.isStopped()) return STOPPED;
+        return FAILED;
+    }
+
+    private void setStarted()
+    {
+        _state = __STARTED;
+        LOG.debug(STARTED+" {}",this);
+        for (Listener listener : _listeners)
+            listener.lifeCycleStarted(this);
+    }
+
+    private void setStarting()
+    {
+        LOG.debug("starting {}",this);
+        _state = __STARTING;
+        for (Listener listener : _listeners)
+            listener.lifeCycleStarting(this);
+    }
+
+    private void setStopping()
+    {
+        LOG.debug("stopping {}",this);
+        _state = __STOPPING;
+        for (Listener listener : _listeners)
+            listener.lifeCycleStopping(this);
+    }
+
+    private void setStopped()
+    {
+        _state = __STOPPED;
+        LOG.debug("{} {}",STOPPED,this);
+        for (Listener listener : _listeners)
+            listener.lifeCycleStopped(this);
+    }
+
+    private void setFailed(Throwable th)
+    {
+        _state = __FAILED;
+        LOG.warn(FAILED+" " + this+": "+th,th);
+        for (Listener listener : _listeners)
+            listener.lifeCycleFailure(this,th);
+    }
+
+    public static abstract class AbstractLifeCycleListener implements LifeCycle.Listener
+    {
+        public void lifeCycleFailure(LifeCycle event, Throwable cause) {}
+        public void lifeCycleStarted(LifeCycle event) {}
+        public void lifeCycleStarting(LifeCycle event) {}
+        public void lifeCycleStopped(LifeCycle event) {}
+        public void lifeCycleStopping(LifeCycle event) {}
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/src/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java
new file mode 100644
index 0000000..1eb22dd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java
@@ -0,0 +1,441 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans.
+ * <p>
+ * Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans.  A managed bean is started, stopped and destroyed with the aggregate.  
+ * An unmanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally.
+ * <p>
+ * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean.  
+ * Otherwise the methods {@link #addBean(Object, boolean)}, {@link #manage(Object)} and {@link #unmanage(Object)} can be used to 
+ * explicitly control the life cycle relationship.
+ * <p>
+ * If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanaged, or 
+ * the API must be used to explicitly set it as unmanaged.
+ * <p>
+ */
+public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
+{
+    private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
+    private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();
+    private boolean _started=false;
+
+    private class Bean
+    {
+        Bean(Object b) 
+        {
+            _bean=b;
+        }
+        final Object _bean;
+        volatile boolean _managed=true;
+        
+        public String toString()
+        {
+            return "{"+_bean+","+_managed+"}";
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Start the managed lifecycle beans in the order they were added.
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        for (Bean b:_beans)
+        {
+            if (b._managed && b._bean instanceof LifeCycle)
+            {
+                LifeCycle l=(LifeCycle)b._bean;
+                if (!l.isRunning())
+                    l.start();
+            }
+        }
+        // indicate that we are started, so that addBean will start other beans added.
+        _started=true;
+        super.doStart();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Stop the joined lifecycle beans in the reverse order they were added.
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        _started=false;
+        super.doStop();
+        List<Bean> reverse = new ArrayList<Bean>(_beans);
+        Collections.reverse(reverse);
+        for (Bean b:reverse)
+        {
+            if (b._managed && b._bean instanceof LifeCycle)
+            {
+                LifeCycle l=(LifeCycle)b._bean;
+                if (l.isRunning())
+                    l.stop();
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Destroy the joined Destroyable beans in the reverse order they were added.
+     * @see org.eclipse.jetty.util.component.Destroyable#destroy()
+     */
+    public void destroy()
+    {
+        List<Bean> reverse = new ArrayList<Bean>(_beans);
+        Collections.reverse(reverse);
+        for (Bean b:reverse)
+        {
+            if (b._bean instanceof Destroyable && b._managed)
+            {
+                Destroyable d=(Destroyable)b._bean;
+                d.destroy();
+            }
+        }
+        _beans.clear();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Is the bean contained in the aggregate.
+     * @param bean
+     * @return True if the aggregate contains the bean
+     */
+    public boolean contains(Object bean)
+    {
+        for (Bean b:_beans)
+            if (b._bean==bean)
+                return true;
+        return false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Is the bean joined to the aggregate.
+     * @param bean
+     * @return True if the aggregate contains the bean and it is joined
+     */
+    public boolean isManaged(Object bean)
+    {
+        for (Bean b:_beans)
+            if (b._bean==bean)
+                return b._managed;
+        return false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Add an associated bean.
+     * If the bean is a {@link LifeCycle}, then it will be managed if it is not 
+     * already started and umanaged if it is already started. The {@link #addBean(Object, boolean)}
+     * method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)}
+     * methods may be used after an add to change the status.
+     * @param o the bean object to add
+     * @return true if the bean was added or false if it has already been added.
+     */
+    public boolean addBean(Object o)
+    {
+        // beans are joined unless they are started lifecycles
+        return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted()));
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add an associated lifecycle.
+     * @param o The lifecycle to add
+     * @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint.
+     * @return true if bean was added, false if already present.
+     */
+    public boolean addBean(Object o, boolean managed)
+    {
+        if (contains(o))
+            return false;
+        
+        Bean b = new Bean(o);
+        b._managed=managed;
+        _beans.add(b);
+        
+        if (o instanceof LifeCycle)
+        {
+            LifeCycle l=(LifeCycle)o;
+
+            // Start the bean if we are started
+            if (managed && _started)
+            {
+                try
+                {
+                    l.start();
+                }
+                catch(Exception e)
+                {
+                    throw new RuntimeException (e);
+                }
+            }
+        }
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Manage a bean by this aggregate, so that it is started/stopped/destroyed with the 
+     * aggregate lifecycle.  
+     * @param bean The bean to manage (must already have been added).
+     */
+    public void manage(Object bean)
+    {    
+        for (Bean b :_beans)
+        {
+            if (b._bean==bean)
+            {
+                b._managed=true;
+                return;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unmanage a bean by this aggregate, so that it is not started/stopped/destroyed with the 
+     * aggregate lifecycle.  
+     * @param bean The bean to manage (must already have been added).
+     */
+    public void unmanage(Object bean)
+    {
+        for (Bean b :_beans)
+        {
+            if (b._bean==bean)
+            {
+                b._managed=false;
+                return;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get dependent beans 
+     * @return List of beans.
+     */
+    public Collection<Object> getBeans()
+    {
+        return getBeans(Object.class);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get dependent beans of a specific class
+     * @see #addBean(Object)
+     * @param clazz
+     * @return List of beans.
+     */
+    public <T> List<T> getBeans(Class<T> clazz)
+    {
+        ArrayList<T> beans = new ArrayList<T>();
+        for (Bean b:_beans)
+        {
+            if (clazz.isInstance(b._bean))
+                beans.add((T)(b._bean));
+        }
+        return beans;
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /** Get dependent beans of a specific class.
+     * If more than one bean of the type exist, the first is returned.
+     * @see #addBean(Object)
+     * @param clazz
+     * @return bean or null
+     */
+    public <T> T getBean(Class<T> clazz)
+    {
+        for (Bean b:_beans)
+        {
+            if (clazz.isInstance(b._bean))
+                return (T)b._bean;
+        }
+        
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Remove all associated bean.
+     */
+    public void removeBeans ()
+    {
+        _beans.clear();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Remove an associated bean.
+     */
+    public boolean removeBean (Object o)
+    {
+        Iterator<Bean> i = _beans.iterator();
+        while(i.hasNext())
+        {
+            Bean b=i.next();
+            if (b._bean==o)
+            {
+                _beans.remove(b);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dumpStdErr()
+    {
+        try
+        {
+            dump(System.err,"");
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public String dump()
+    {
+        return dump(this);
+    }    
+    
+    /* ------------------------------------------------------------ */
+    public static String dump(Dumpable dumpable)
+    {
+        StringBuilder b = new StringBuilder();
+        try
+        {
+            dumpable.dump(b,"");
+        }
+        catch (IOException e)
+        {
+            LOG.warn(e);
+        }
+        return b.toString();
+    }    
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out) throws IOException
+    {
+        dump(out,"");
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void dumpThis(Appendable out) throws IOException
+    {
+        out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n");
+    }
+
+    /* ------------------------------------------------------------ */
+    public static void dumpObject(Appendable out,Object o) throws IOException
+    {
+        try
+        {
+            if (o instanceof LifeCycle)
+                out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");
+            else
+                out.append(String.valueOf(o)).append("\n");
+        }
+        catch(Throwable th)
+        {
+            out.append(" => ").append(th.toString()).append('\n');
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out,String indent) throws IOException
+    {
+        dumpThis(out);
+        int size=_beans.size();
+        if (size==0)
+            return;
+        int i=0;
+        for (Bean b : _beans)
+        {
+            i++;
+
+            out.append(indent).append(" +- ");
+            if (b._managed)
+            {
+                if (b._bean instanceof Dumpable)
+                    ((Dumpable)b._bean).dump(out,indent+(i==size?"    ":" |  "));
+                else 
+                    dumpObject(out,b._bean);
+            }
+            else 
+                dumpObject(out,b._bean);
+        }
+
+        if (i!=size)
+            out.append(indent).append(" |\n");
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static void dump(Appendable out,String indent,Collection<?>... collections) throws IOException
+    {
+        if (collections.length==0)
+            return;
+        int size=0;
+        for (Collection<?> c : collections)
+            size+=c.size();    
+        if (size==0)
+            return;
+
+        int i=0;
+        for (Collection<?> c : collections)
+        {
+            for (Object o : c)
+            {
+                i++;
+                out.append(indent).append(" +- ");
+
+                if (o instanceof Dumpable)
+                    ((Dumpable)o).dump(out,indent+(i==size?"    ":" |  "));
+                else 
+                    dumpObject(out,o);
+            }
+            
+            if (i!=size)
+                out.append(indent).append(" |\n");          
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/component/Container.java b/src/java/org/eclipse/jetty/util/component/Container.java
new file mode 100644
index 0000000..a83064a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/Container.java
@@ -0,0 +1,305 @@
+//
+//  ========================================================================
+//  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.util.component;
+import java.lang.ref.WeakReference;
+import java.util.EventListener;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Container.
+ * This class allows a containment events to be generated from update methods.
+ * 
+ * The style of usage is: <pre>
+ *   public void setFoo(Foo foo)
+ *   {
+ *       getContainer().update(this,this.foo,foo,"foo");
+ *       this.foo=foo;
+ *   }
+ *   
+ *   public void setBars(Bar[] bars)
+ *   {
+ *       getContainer().update(this,this.bars,bars,"bar");
+ *       this.bars=bars;
+ *   }
+ * </pre>
+ */
+public class Container
+{
+    private static final Logger LOG = Log.getLogger(Container.class);
+    private final CopyOnWriteArrayList<Container.Listener> _listeners=new CopyOnWriteArrayList<Container.Listener>();
+    
+    public void addEventListener(Container.Listener listener)
+    {
+        _listeners.add(listener);
+    }
+    
+    public void removeEventListener(Container.Listener listener)
+    {
+        _listeners.remove(listener);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Update single parent to child relationship.
+     * @param parent The parent of the child.
+     * @param oldChild The previous value of the child.  If this is non null and differs from <code>child</code>, then a remove event is generated.
+     * @param child The current child. If this is non null and differs from <code>oldChild</code>, then an add event is generated.
+     * @param relationship The name of the relationship
+     */
+    public void update(Object parent, Object oldChild, final Object child, String relationship)
+    {
+        if (oldChild!=null && !oldChild.equals(child))
+            remove(parent,oldChild,relationship);
+        if (child!=null && !child.equals(oldChild))
+            add(parent,child,relationship);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Update single parent to child relationship.
+     * @param parent The parent of the child.
+     * @param oldChild The previous value of the child.  If this is non null and differs from <code>child</code>, then a remove event is generated.
+     * @param child The current child. If this is non null and differs from <code>oldChild</code>, then an add event is generated.
+     * @param relationship The name of the relationship
+     * @param addRemove If true add/remove is called for the new/old children as well as the relationships
+     */
+    public void update(Object parent, Object oldChild, final Object child, String relationship,boolean addRemove)
+    {
+        if (oldChild!=null && !oldChild.equals(child))
+        {
+            remove(parent,oldChild,relationship);
+            if (addRemove)
+                removeBean(oldChild);
+        }
+        
+        if (child!=null && !child.equals(oldChild))
+        {
+            if (addRemove)
+                addBean(child);
+            add(parent,child,relationship);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Update multiple parent to child relationship.
+     * @param parent The parent of the child.
+     * @param oldChildren The previous array of children.  A remove event is generated for any child in this array but not in the  <code>children</code> array.
+     * This array is modified and children that remain in the new children array are nulled out of the old children array.
+     * @param children The current array of children. An add event is generated for any child in this array but not in the <code>oldChildren</code> array.
+     * @param relationship The name of the relationship
+     */
+    public void update(Object parent, Object[] oldChildren, final Object[] children, String relationship)
+    {
+        update(parent,oldChildren,children,relationship,false);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Update multiple parent to child relationship.
+     * @param parent The parent of the child.
+     * @param oldChildren The previous array of children.  A remove event is generated for any child in this array but not in the  <code>children</code> array.
+     * This array is modified and children that remain in the new children array are nulled out of the old children array.
+     * @param children The current array of children. An add event is generated for any child in this array but not in the <code>oldChildren</code> array.
+     * @param relationship The name of the relationship
+     * @param addRemove If true add/remove is called for the new/old children as well as the relationships
+     */
+    public void update(Object parent, Object[] oldChildren, final Object[] children, String relationship, boolean addRemove)
+    {
+        Object[] newChildren = null;
+        if (children!=null)
+        {
+            newChildren = new Object[children.length];
+        
+            for (int i=children.length;i-->0;)
+            {
+                boolean new_child=true;
+                if (oldChildren!=null)
+                {
+                    for (int j=oldChildren.length;j-->0;)
+                    {
+                        if (children[i]!=null && children[i].equals(oldChildren[j]))
+                        {
+                            oldChildren[j]=null;
+                            new_child=false;
+                        }
+                    }
+                }
+                if (new_child)
+                    newChildren[i]=children[i];
+            }
+        }
+        
+        if (oldChildren!=null)
+        {
+            for (int i=oldChildren.length;i-->0;)
+            {
+                if (oldChildren[i]!=null)
+                {
+                    remove(parent,oldChildren[i],relationship);
+                    if (addRemove)
+                        removeBean(oldChildren[i]);
+                }
+            }
+        }
+        
+        if (newChildren!=null)
+        {
+            for (int i=0;i<newChildren.length;i++)
+                if (newChildren[i]!=null)
+                {
+                    if (addRemove)
+                        addBean(newChildren[i]);
+                    add(parent,newChildren[i],relationship);
+                }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addBean(Object obj)
+    {
+        if (_listeners!=null)
+        {
+            for (int i=0; i<LazyList.size(_listeners); i++)
+            {
+                Listener listener=(Listener)LazyList.get(_listeners, i);
+                listener.addBean(obj);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void removeBean(Object obj)
+    {
+        if (_listeners!=null)
+        {
+            for (int i=0; i<LazyList.size(_listeners); i++)
+                ((Listener)LazyList.get(_listeners, i)).removeBean(obj);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add a parent child relationship
+     * @param parent
+     * @param child
+     * @param relationship
+     */
+    private void add(Object parent, Object child, String relationship)
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("Container "+parent+" + "+child+" as "+relationship);
+        if (_listeners!=null)
+        {
+            Relationship event=new Relationship(this,parent,child,relationship);
+            for (int i=0; i<LazyList.size(_listeners); i++)
+                ((Listener)LazyList.get(_listeners, i)).add(event);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** remove a parent child relationship
+     * @param parent
+     * @param child
+     * @param relationship
+     */
+    private void remove(Object parent, Object child, String relationship)
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("Container "+parent+" - "+child+" as "+relationship);
+        if (_listeners!=null)
+        {
+            Relationship event=new Relationship(this,parent,child,relationship);
+            for (int i=0; i<LazyList.size(_listeners); i++)
+                ((Listener)LazyList.get(_listeners, i)).remove(event);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** A Container event.
+     * @see Listener
+     */
+    public static class Relationship
+    {
+        private final WeakReference<Object> _parent;
+        private final WeakReference<Object> _child;
+        private String _relationship;
+        private Container _container;
+        
+        private Relationship(Container container, Object parent,Object child, String relationship)
+        {
+            _container=container;
+            _parent=new WeakReference<Object>(parent);
+            _child=new WeakReference<Object>(child);
+            _relationship=relationship;
+        }
+        
+        public Container getContainer()
+        {
+            return _container;
+        }
+        
+        public Object getChild()
+        {
+            return _child.get();
+        }
+        
+        public Object getParent()
+        {
+            return _parent.get();
+        }
+        
+        public String getRelationship()
+        {
+            return _relationship;
+        }
+        
+        @Override
+        public String toString()
+        {
+            return _parent+"---"+_relationship+"-->"+_child;
+        }
+        
+        @Override
+        public int hashCode()
+        {
+            return _parent.hashCode()+_child.hashCode()+_relationship.hashCode();
+        }
+        
+        @Override
+        public boolean equals(Object o)
+        {
+            if (o==null || !(o instanceof Relationship))
+                return false;
+            Relationship r = (Relationship)o;
+            return r._parent.get()==_parent.get() && r._child.get()==_child.get() && r._relationship.equals(_relationship);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Listener.
+     * A listener for Container events.
+     */
+    public interface Listener extends EventListener
+    {
+        public void addBean(Object bean);
+        public void removeBean(Object bean);
+        public void add(Container.Relationship relationship);
+        public void remove(Container.Relationship relationship);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/component/Destroyable.java b/src/java/org/eclipse/jetty/util/component/Destroyable.java
new file mode 100644
index 0000000..2e7e441
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/Destroyable.java
@@ -0,0 +1,31 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+
+/**
+ * <p>A Destroyable is an object which can be destroyed.</p>
+ * <p>Typically a Destroyable is a {@link LifeCycle} component that can hold onto
+ * resources over multiple start/stop cycles.   A call to destroy will release all
+ * resources and will prevent any further start/stop cycles from being successful.</p>
+ */
+public interface Destroyable
+{
+    void destroy();
+}
diff --git a/src/java/org/eclipse/jetty/util/component/Dumpable.java b/src/java/org/eclipse/jetty/util/component/Dumpable.java
new file mode 100644
index 0000000..104fb08
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/Dumpable.java
@@ -0,0 +1,27 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.io.IOException;
+
+public interface Dumpable
+{
+    String dump();
+    void dump(Appendable out,String indent) throws IOException;
+}
diff --git a/src/java/org/eclipse/jetty/util/component/FileDestroyable.java b/src/java/org/eclipse/jetty/util/component/FileDestroyable.java
new file mode 100644
index 0000000..1da4e8d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/FileDestroyable.java
@@ -0,0 +1,88 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+public class FileDestroyable implements Destroyable
+{
+    private static final Logger LOG = Log.getLogger(FileDestroyable.class);
+    final List<File> _files = new ArrayList<File>();
+
+    public FileDestroyable()
+    {
+    }
+    
+    public FileDestroyable(String file) throws IOException
+    {
+        _files.add(Resource.newResource(file).getFile());
+    }
+    
+    public FileDestroyable(File file)
+    {
+        _files.add(file);
+    }
+    
+    public void addFile(String file) throws IOException
+    {
+        _files.add(Resource.newResource(file).getFile());
+    }
+    
+    public void addFile(File file)
+    {
+        _files.add(file);
+    }
+    
+    public void addFiles(Collection<File> files)
+    {
+        _files.addAll(files);
+    }
+    
+    public void removeFile(String file) throws IOException
+    {
+        _files.remove(Resource.newResource(file).getFile());
+    }
+    
+    public void removeFile(File file)
+    {
+        _files.remove(file);
+    }
+    
+    public void destroy()
+    {
+        for (File file : _files)
+        {
+            if (file.exists())
+            {
+                LOG.debug("Destroy {}",file);
+                IO.delete(file);
+            }
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java b/src/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java
new file mode 100644
index 0000000..0f1ec44
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java
@@ -0,0 +1,80 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.io.FileWriter;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** A LifeCycle Listener that writes state changes to a file.
+ * <p>This can be used with the jetty.sh script to wait for successful startup.
+ */
+public class FileNoticeLifeCycleListener implements LifeCycle.Listener
+{
+    Logger LOG = Log.getLogger(FileNoticeLifeCycleListener.class);
+    
+    private final String _filename;
+    
+    public FileNoticeLifeCycleListener(String filename)
+    {
+        _filename=filename;
+    }
+
+    private void writeState(String action, LifeCycle lifecycle)
+    {
+        try
+        {
+            FileWriter out = new FileWriter(_filename,true);
+            out.append(action).append(" ").append(lifecycle.toString()).append("\n");
+            out.close();
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    public void lifeCycleStarting(LifeCycle event)
+    {  
+        writeState("STARTING",event);      
+    }
+
+    public void lifeCycleStarted(LifeCycle event)
+    {        
+        writeState("STARTED",event); 
+    }
+
+    public void lifeCycleFailure(LifeCycle event, Throwable cause)
+    {        
+        writeState("FAILED",event);
+    }
+
+    public void lifeCycleStopping(LifeCycle event)
+    {        
+        writeState("STOPPING",event);
+    }
+
+    public void lifeCycleStopped(LifeCycle event)
+    {        
+        writeState("STOPPED",event);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/component/LifeCycle.java b/src/java/org/eclipse/jetty/util/component/LifeCycle.java
new file mode 100644
index 0000000..1d58e3e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/component/LifeCycle.java
@@ -0,0 +1,119 @@
+//
+//  ========================================================================
+//  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.util.component;
+
+import java.util.EventListener;
+
+/* ------------------------------------------------------------ */
+/**
+ * The lifecycle interface for generic components.
+ * <br />
+ * Classes implementing this interface have a defined life cycle
+ * defined by the methods of this interface.
+ *
+ * 
+ */
+public interface LifeCycle
+{
+    /* ------------------------------------------------------------ */
+    /**
+     * Starts the component.
+     * @throws Exception If the component fails to start
+     * @see #isStarted()
+     * @see #stop()
+     * @see #isFailed()
+     */
+    public void start()
+        throws Exception;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Stops the component.
+     * The component may wait for current activities to complete
+     * normally, but it can be interrupted.
+     * @exception Exception If the component fails to stop
+     * @see #isStopped()
+     * @see #start()
+     * @see #isFailed()
+     */
+    public void stop()
+        throws Exception;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component is starting or has been started.
+     */
+    public boolean isRunning();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component has been started.
+     * @see #start()
+     * @see #isStarting()
+     */
+    public boolean isStarted();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component is starting.
+     * @see #isStarted()
+     */
+    public boolean isStarting();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component is stopping.
+     * @see #isStopped()
+     */
+    public boolean isStopping();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component has been stopped.
+     * @see #stop()
+     * @see #isStopping()
+     */
+    public boolean isStopped();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if the component has failed to start or has failed to stop.
+     */
+    public boolean isFailed();
+    
+    /* ------------------------------------------------------------ */
+    public void addLifeCycleListener(LifeCycle.Listener listener);
+
+    /* ------------------------------------------------------------ */
+    public void removeLifeCycleListener(LifeCycle.Listener listener);
+    
+
+    /* ------------------------------------------------------------ */
+    /** Listener.
+     * A listener for Lifecycle events.
+     */
+    public interface Listener extends EventListener
+    {
+        public void lifeCycleStarting(LifeCycle event);
+        public void lifeCycleStarted(LifeCycle event);
+        public void lifeCycleFailure(LifeCycle event,Throwable cause);
+        public void lifeCycleStopping(LifeCycle event);
+        public void lifeCycleStopped(LifeCycle event);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/AbstractLogger.java b/src/java/org/eclipse/jetty/util/log/AbstractLogger.java
new file mode 100644
index 0000000..2441bb5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/AbstractLogger.java
@@ -0,0 +1,77 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+
+/* ------------------------------------------------------------ */
+/** Abstract Logger.
+ * Manages the atomic registration of the logger by name.
+ */
+public abstract class AbstractLogger implements Logger
+{
+    public final Logger getLogger(String name)
+    {
+        if (isBlank(name))
+            return this;
+
+        final String basename = getName();
+        final String fullname = (isBlank(basename) || Log.getRootLogger()==this)?name:(basename + "." + name);
+        
+        Logger logger = Log.getLoggers().get(fullname);
+        if (logger == null)
+        {
+            Logger newlog = newLogger(fullname);
+            
+            logger = Log.getMutableLoggers().putIfAbsent(fullname,newlog);
+            if (logger == null)
+                logger=newlog;
+        }
+
+        return logger;
+    }
+    
+
+    protected abstract Logger newLogger(String fullname);
+
+    /**
+     * A more robust form of name blank test. Will return true for null names, and names that have only whitespace
+     *
+     * @param name
+     *            the name to test
+     * @return true for null or blank name, false if any non-whitespace character is found.
+     */
+    private static boolean isBlank(String name)
+    {
+        if (name == null)
+        {
+            return true;
+        }
+        int size = name.length();
+        char c;
+        for (int i = 0; i < size; i++)
+        {
+            c = name.charAt(i);
+            if (!Character.isWhitespace(c))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/JavaUtilLog.java b/src/java/org/eclipse/jetty/util/log/JavaUtilLog.java
new file mode 100644
index 0000000..b79d7a1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/JavaUtilLog.java
@@ -0,0 +1,163 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+import java.util.logging.Level;
+
+/**
+ * <p>
+ * Implementation of Jetty {@link Logger} based on {@link java.util.logging.Logger}.
+ * </p>
+ *
+ * <p>
+ * You can also set the logger level using <a href="http://java.sun.com/j2se/1.5.0/docs/guide/logging/overview.html">
+ * standard java.util.logging configuration</a>.
+ * </p>
+ */
+public class JavaUtilLog extends AbstractLogger
+{
+    private Level configuredLevel;
+    private java.util.logging.Logger _logger;
+
+    public JavaUtilLog()
+    {
+        this("org.eclipse.jetty.util.log");
+    }
+
+    public JavaUtilLog(String name)
+    {
+        _logger = java.util.logging.Logger.getLogger(name);
+        if (Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.DEBUG", "false")))
+        {
+            _logger.setLevel(Level.FINE);
+        }
+        configuredLevel = _logger.getLevel();
+    }
+
+    public String getName()
+    {
+        return _logger.getName();
+    }
+
+    public void warn(String msg, Object... args)
+    {
+        _logger.log(Level.WARNING, format(msg, args));
+    }
+
+    public void warn(Throwable thrown)
+    {
+        warn("", thrown);
+    }
+
+    public void warn(String msg, Throwable thrown)
+    {
+        _logger.log(Level.WARNING, msg, thrown);
+    }
+
+    public void info(String msg, Object... args)
+    {
+        _logger.log(Level.INFO, format(msg, args));
+    }
+
+    public void info(Throwable thrown)
+    {
+        info("", thrown);
+    }
+
+    public void info(String msg, Throwable thrown)
+    {
+        _logger.log(Level.INFO, msg, thrown);
+    }
+
+    public boolean isDebugEnabled()
+    {
+        return _logger.isLoggable(Level.FINE);
+    }
+
+    public void setDebugEnabled(boolean enabled)
+    {
+        if (enabled)
+        {
+            configuredLevel = _logger.getLevel();
+            _logger.setLevel(Level.FINE);
+        }
+        else
+        {
+            _logger.setLevel(configuredLevel);
+        }
+    }
+
+    public void debug(String msg, Object... args)
+    {
+        _logger.log(Level.FINE, format(msg, args));
+    }
+
+    public void debug(Throwable thrown)
+    {
+        debug("", thrown);
+    }
+
+    public void debug(String msg, Throwable thrown)
+    {
+        _logger.log(Level.FINE, msg, thrown);
+    }
+
+    /**
+     * Create a Child Logger of this Logger.
+     */
+    protected Logger newLogger(String fullname)
+    {
+        return new JavaUtilLog(fullname);
+    }
+
+    public void ignore(Throwable ignored)
+    {
+        if (Log.isIgnored())
+        {
+            warn(Log.IGNORED, ignored);
+        }
+    }
+
+    private String format(String msg, Object... args)
+    {
+        msg = String.valueOf(msg); // Avoids NPE
+        String braces = "{}";
+        StringBuilder builder = new StringBuilder();
+        int start = 0;
+        for (Object arg : args)
+        {
+            int bracesIndex = msg.indexOf(braces, start);
+            if (bracesIndex < 0)
+            {
+                builder.append(msg.substring(start));
+                builder.append(" ");
+                builder.append(arg);
+                start = msg.length();
+            }
+            else
+            {
+                builder.append(msg.substring(start, bracesIndex));
+                builder.append(String.valueOf(arg));
+                start = bracesIndex + braces.length();
+            }
+        }
+        builder.append(msg.substring(start));
+        return builder.toString();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/JettyAwareLogger.java b/src/java/org/eclipse/jetty/util/log/JettyAwareLogger.java
new file mode 100644
index 0000000..fb0ea18
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/JettyAwareLogger.java
@@ -0,0 +1,624 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+import org.slf4j.Marker;
+import org.slf4j.helpers.FormattingTuple;
+import org.slf4j.helpers.MessageFormatter;
+
+/**
+ * JettyAwareLogger is used to fix a FQCN bug that arises from how Jetty
+ * Log uses an indirect slf4j implementation.
+ *
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=276670
+ */
+class JettyAwareLogger implements org.slf4j.Logger
+{
+    private static final int DEBUG = org.slf4j.spi.LocationAwareLogger.DEBUG_INT;
+    private static final int ERROR = org.slf4j.spi.LocationAwareLogger.ERROR_INT;
+    private static final int INFO  = org.slf4j.spi.LocationAwareLogger.INFO_INT;
+    private static final int TRACE = org.slf4j.spi.LocationAwareLogger.TRACE_INT;
+    private static final int WARN  = org.slf4j.spi.LocationAwareLogger.WARN_INT;
+
+    private static final String FQCN = Slf4jLog.class.getName();
+    private final org.slf4j.spi.LocationAwareLogger _logger;
+
+    public JettyAwareLogger(org.slf4j.spi.LocationAwareLogger logger)
+    {
+        _logger = logger;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#getName()
+     */
+    public String getName()
+    {
+        return _logger.getName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isTraceEnabled()
+     */
+    public boolean isTraceEnabled()
+    {
+        return _logger.isTraceEnabled();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(java.lang.String)
+     */
+    public void trace(String msg)
+    {
+        log(null, TRACE, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object)
+     */
+    public void trace(String format, Object arg)
+    {
+        log(null, TRACE, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void trace(String format, Object arg1, Object arg2)
+    {
+        log(null, TRACE, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Object[])
+     */
+    public void trace(String format, Object[] argArray)
+    {
+        log(null, TRACE, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(java.lang.String, java.lang.Throwable)
+     */
+    public void trace(String msg, Throwable t)
+    {
+        log(null, TRACE, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isTraceEnabled(org.slf4j.Marker)
+     */
+    public boolean isTraceEnabled(Marker marker)
+    {
+        return _logger.isTraceEnabled(marker);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(org.slf4j.Marker, java.lang.String)
+     */
+    public void trace(Marker marker, String msg)
+    {
+        log(marker, TRACE, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(org.slf4j.Marker, java.lang.String, java.lang.Object)
+     */
+    public void trace(Marker marker, String format, Object arg)
+    {
+        log(marker, TRACE, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void trace(Marker marker, String format, Object arg1, Object arg2)
+    {
+        log(marker, TRACE, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(org.slf4j.Marker, java.lang.String, java.lang.Object[])
+     */
+    public void trace(Marker marker, String format, Object[] argArray)
+    {
+        log(marker, TRACE, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#trace(org.slf4j.Marker, java.lang.String, java.lang.Throwable)
+     */
+    public void trace(Marker marker, String msg, Throwable t)
+    {
+        log(marker, TRACE, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isDebugEnabled()
+     */
+    public boolean isDebugEnabled()
+    {
+        return _logger.isDebugEnabled();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(java.lang.String)
+     */
+    public void debug(String msg)
+    {
+        log(null, DEBUG, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object)
+     */
+    public void debug(String format, Object arg)
+    {
+        log(null, DEBUG, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void debug(String format, Object arg1, Object arg2)
+    {
+        log(null, DEBUG, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Object[])
+     */
+    public void debug(String format, Object[] argArray)
+    {
+        log(null, DEBUG, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(java.lang.String, java.lang.Throwable)
+     */
+    public void debug(String msg, Throwable t)
+    {
+        log(null, DEBUG, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isDebugEnabled(org.slf4j.Marker)
+     */
+    public boolean isDebugEnabled(Marker marker)
+    {
+        return _logger.isDebugEnabled(marker);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(org.slf4j.Marker, java.lang.String)
+     */
+    public void debug(Marker marker, String msg)
+    {
+        log(marker, DEBUG, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(org.slf4j.Marker, java.lang.String, java.lang.Object)
+     */
+    public void debug(Marker marker, String format, Object arg)
+    {
+        log(marker, DEBUG, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void debug(Marker marker, String format, Object arg1, Object arg2)
+    {
+        log(marker, DEBUG, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(org.slf4j.Marker, java.lang.String, java.lang.Object[])
+     */
+    public void debug(Marker marker, String format, Object[] argArray)
+    {
+        log(marker, DEBUG, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#debug(org.slf4j.Marker, java.lang.String, java.lang.Throwable)
+     */
+    public void debug(Marker marker, String msg, Throwable t)
+    {
+        log(marker, DEBUG, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isInfoEnabled()
+     */
+    public boolean isInfoEnabled()
+    {
+        return _logger.isInfoEnabled();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(java.lang.String)
+     */
+    public void info(String msg)
+    {
+        log(null, INFO, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object)
+     */
+    public void info(String format, Object arg)
+    {
+        log(null, INFO, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void info(String format, Object arg1, Object arg2)
+    {
+        log(null, INFO, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(java.lang.String, java.lang.Object[])
+     */
+    public void info(String format, Object[] argArray)
+    {
+        log(null, INFO, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(java.lang.String, java.lang.Throwable)
+     */
+    public void info(String msg, Throwable t)
+    {
+        log(null, INFO, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isInfoEnabled(org.slf4j.Marker)
+     */
+    public boolean isInfoEnabled(Marker marker)
+    {
+        return _logger.isInfoEnabled(marker);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(org.slf4j.Marker, java.lang.String)
+     */
+    public void info(Marker marker, String msg)
+    {
+        log(marker, INFO, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(org.slf4j.Marker, java.lang.String, java.lang.Object)
+     */
+    public void info(Marker marker, String format, Object arg)
+    {
+        log(marker, INFO, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void info(Marker marker, String format, Object arg1, Object arg2)
+    {
+        log(marker, INFO, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(org.slf4j.Marker, java.lang.String, java.lang.Object[])
+     */
+    public void info(Marker marker, String format, Object[] argArray)
+    {
+        log(marker, INFO, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#info(org.slf4j.Marker, java.lang.String, java.lang.Throwable)
+     */
+    public void info(Marker marker, String msg, Throwable t)
+    {
+        log(marker, INFO, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isWarnEnabled()
+     */
+    public boolean isWarnEnabled()
+    {
+        return _logger.isWarnEnabled();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(java.lang.String)
+     */
+    public void warn(String msg)
+    {
+        log(null, WARN, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object)
+     */
+    public void warn(String format, Object arg)
+    {
+        log(null, WARN, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object[])
+     */
+    public void warn(String format, Object[] argArray)
+    {
+        log(null, WARN, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void warn(String format, Object arg1, Object arg2)
+    {
+        log(null, WARN, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(java.lang.String, java.lang.Throwable)
+     */
+    public void warn(String msg, Throwable t)
+    {
+        log(null, WARN, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isWarnEnabled(org.slf4j.Marker)
+     */
+    public boolean isWarnEnabled(Marker marker)
+    {
+        return _logger.isWarnEnabled(marker);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(org.slf4j.Marker, java.lang.String)
+     */
+    public void warn(Marker marker, String msg)
+    {
+        log(marker, WARN, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(org.slf4j.Marker, java.lang.String, java.lang.Object)
+     */
+    public void warn(Marker marker, String format, Object arg)
+    {
+        log(marker, WARN, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void warn(Marker marker, String format, Object arg1, Object arg2)
+    {
+        log(marker, WARN, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(org.slf4j.Marker, java.lang.String, java.lang.Object[])
+     */
+    public void warn(Marker marker, String format, Object[] argArray)
+    {
+        log(marker, WARN, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#warn(org.slf4j.Marker, java.lang.String, java.lang.Throwable)
+     */
+    public void warn(Marker marker, String msg, Throwable t)
+    {
+        log(marker, WARN, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isErrorEnabled()
+     */
+    public boolean isErrorEnabled()
+    {
+        return _logger.isErrorEnabled();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(java.lang.String)
+     */
+    public void error(String msg)
+    {
+        log(null, ERROR, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object)
+     */
+    public void error(String format, Object arg)
+    {
+        log(null, ERROR, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void error(String format, Object arg1, Object arg2)
+    {
+        log(null, ERROR, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(java.lang.String, java.lang.Object[])
+     */
+    public void error(String format, Object[] argArray)
+    {
+        log(null, ERROR, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(java.lang.String, java.lang.Throwable)
+     */
+    public void error(String msg, Throwable t)
+    {
+        log(null, ERROR, msg, null, t);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#isErrorEnabled(org.slf4j.Marker)
+     */
+    public boolean isErrorEnabled(Marker marker)
+    {
+        return _logger.isErrorEnabled(marker);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(org.slf4j.Marker, java.lang.String)
+     */
+    public void error(Marker marker, String msg)
+    {
+        log(marker, ERROR, msg, null, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(org.slf4j.Marker, java.lang.String, java.lang.Object)
+     */
+    public void error(Marker marker, String format, Object arg)
+    {
+        log(marker, ERROR, format, new Object[]{arg}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object)
+     */
+    public void error(Marker marker, String format, Object arg1, Object arg2)
+    {
+        log(marker, ERROR, format, new Object[]{arg1,arg2}, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(org.slf4j.Marker, java.lang.String, java.lang.Object[])
+     */
+    public void error(Marker marker, String format, Object[] argArray)
+    {
+        log(marker, ERROR, format, argArray, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.slf4j.Logger#error(org.slf4j.Marker, java.lang.String, java.lang.Throwable)
+     */
+    public void error(Marker marker, String msg, Throwable t)
+    {
+        log(marker, ERROR, msg, null, t);
+    }
+
+    @Override
+    public String toString()
+    {
+        return _logger.toString();
+    }
+
+    private void log(Marker marker, int level, String msg, Object[] argArray, Throwable t)
+    {
+        if (argArray == null)
+        {
+            // Simple SLF4J Message (no args)
+            _logger.log(marker, FQCN, level, msg, null, t);
+        }
+        else
+        {
+            int loggerLevel = _logger.isTraceEnabled() ? TRACE :
+                    _logger.isDebugEnabled() ? DEBUG :
+                            _logger.isInfoEnabled() ? INFO :
+                                    _logger.isWarnEnabled() ? WARN : ERROR;
+            if (loggerLevel <= level)
+            {
+                // Don't assume downstream handles argArray properly.
+                // Do it the SLF4J way here to eliminate that as a bug.
+                FormattingTuple ft = MessageFormatter.arrayFormat(msg, argArray);
+                _logger.log(marker, FQCN, level, ft.getMessage(), null, t);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/Log.java b/src/java/org/eclipse/jetty/util/log/Log.java
new file mode 100644
index 0000000..a35c18c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/Log.java
@@ -0,0 +1,462 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Loader;
+
+/**
+ * Logging.
+ * This class provides a static logging interface.  If an instance of the
+ * org.slf4j.Logger class is found on the classpath, the static log methods
+ * are directed to a slf4j logger for "org.eclipse.log".   Otherwise the logs
+ * are directed to stderr.
+ * <p>
+ * The "org.eclipse.jetty.util.log.class" system property can be used
+ * to select a specific logging implementation.
+ * <p>
+ * If the system property org.eclipse.jetty.util.log.IGNORED is set,
+ * then ignored exceptions are logged in detail.
+ *
+ * @see StdErrLog
+ * @see Slf4jLog
+ */
+public class Log
+{
+    public final static String EXCEPTION= "EXCEPTION ";
+    public final static String IGNORED= "IGNORED ";
+
+    /**
+     * Logging Configuration Properties
+     */
+    protected static Properties __props;
+    /**
+     * The {@link Logger} implementation class name
+     */
+    public static String __logClass;
+    /**
+     * Legacy flag indicating if {@link Log#ignore(Throwable)} methods produce any output in the {@link Logger}s
+     */
+    public static boolean __ignored;
+
+    /**
+     * Hold loggers only.
+     */
+    private final static ConcurrentMap<String, Logger> __loggers = new ConcurrentHashMap<String, Logger>();
+
+
+    static
+    {
+        /* Instantiate a default configuration properties (empty)
+         */
+        __props = new Properties();
+
+        AccessController.doPrivileged(new PrivilegedAction<Object>()
+        {
+            public Object run()
+            {
+                /* First see if the jetty-logging.properties object exists in the classpath.
+                 * This is an optional feature used by embedded mode use, and test cases to allow for early
+                 * configuration of the Log class in situations where access to the System.properties are
+                 * either too late or just impossible.
+                 */
+                URL testProps = Loader.getResource(Log.class,"jetty-logging.properties",true);
+                if (testProps != null)
+                {
+                    InputStream in = null;
+                    try
+                    {
+                        in = testProps.openStream();
+                        __props.load(in);
+                    }
+                    catch (IOException e)
+                    {
+                        System.err.println("Unable to load " + testProps);
+                        e.printStackTrace(System.err);
+                    }
+                    finally
+                    {
+                        IO.close(in);
+                    }
+                }
+
+                /* Now load the System.properties as-is into the __props, these values will override
+                 * any key conflicts in __props.
+                 */
+                @SuppressWarnings("unchecked")
+                Enumeration<String> systemKeyEnum = (Enumeration<String>)System.getProperties().propertyNames();
+                while (systemKeyEnum.hasMoreElements())
+                {
+                    String key = systemKeyEnum.nextElement();
+                    String val = System.getProperty(key);
+                    //protect against application code insertion of non-String values (returned as null)
+                    if (val != null)
+                        __props.setProperty(key,val);
+                }
+
+                /* Now use the configuration properties to configure the Log statics
+                 */
+                __logClass = __props.getProperty("org.eclipse.jetty.util.log.class","org.eclipse.jetty.util.log.Slf4jLog");
+                __ignored = Boolean.parseBoolean(__props.getProperty("org.eclipse.jetty.util.log.IGNORED","false"));
+                return null;
+            }
+        });
+    }
+
+    private static Logger LOG;
+    private static boolean __initialized;
+
+    public static boolean initialized()
+    {
+        if (LOG != null)
+        {
+            return true;
+        }
+
+        synchronized (Log.class)
+        {
+            if (__initialized)
+            {
+                return LOG != null;
+            }
+            __initialized = true;
+        }
+
+        try
+        {
+            Class<?> log_class = Loader.loadClass(Log.class, __logClass);
+            if (LOG == null || !LOG.getClass().equals(log_class))
+            {
+                LOG = (Logger)log_class.newInstance();
+                LOG.debug("Logging to {} via {}", LOG, log_class.getName());
+            }
+        }
+        catch(Throwable e)
+        {
+            // Unable to load specified Logger implementation, default to standard logging.
+            initStandardLogging(e);
+        }
+
+        return LOG != null;
+    }
+
+    private static void initStandardLogging(Throwable e)
+    {
+        Class<?> log_class;
+        if(e != null && __ignored)
+        {
+            e.printStackTrace();
+        }
+
+        if (LOG == null)
+        {
+            log_class = StdErrLog.class;
+            LOG = new StdErrLog();
+            LOG.debug("Logging to {} via {}", LOG, log_class.getName());
+        }
+    }
+
+    public static void setLog(Logger log)
+    {
+        Log.LOG = log;
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static Logger getLog()
+    {
+        initialized();
+        return LOG;
+    }
+
+    /**
+     * Get the root logger.
+     * @return the root logger
+     */
+    public static Logger getRootLogger() {
+        initialized();
+        return LOG;
+    }
+
+    static boolean isIgnored()
+    {
+        return __ignored;
+    }
+
+    /**
+     * Set Log to parent Logger.
+     * <p>
+     * If there is a different Log class available from a parent classloader,
+     * call {@link #getLogger(String)} on it and construct a {@link LoggerLog} instance
+     * as this Log's Logger, so that logging is delegated to the parent Log.
+     * <p>
+     * This should be used if a webapp is using Log, but wishes the logging to be
+     * directed to the containers log.
+     * <p>
+     * If there is not parent Log, then this call is equivalent to<pre>
+     *   Log.setLog(Log.getLogger(name));
+     * </pre>
+     * @param name Logger name
+     */
+    public static void setLogToParent(String name)
+    {
+        ClassLoader loader = Log.class.getClassLoader();
+        if (loader!=null && loader.getParent()!=null)
+        {
+            try
+            {
+                Class<?> uberlog = loader.getParent().loadClass("org.eclipse.jetty.util.log.Log");
+                Method getLogger = uberlog.getMethod("getLogger", new Class[]{String.class});
+                Object logger = getLogger.invoke(null,name);
+                setLog(new LoggerLog(logger));
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        else
+        {
+            setLog(getLogger(name));
+        }
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void debug(Throwable th)
+    {
+        if (!isDebugEnabled())
+            return;
+        LOG.debug(EXCEPTION, th);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void debug(String msg)
+    {
+        if (!initialized())
+            return;
+        LOG.debug(msg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void debug(String msg, Object arg)
+    {
+        if (!initialized())
+            return;
+        LOG.debug(msg, arg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void debug(String msg, Object arg0, Object arg1)
+    {
+        if (!initialized())
+            return;
+        LOG.debug(msg, arg0, arg1);
+    }
+
+    /**
+     * Ignore an exception unless trace is enabled.
+     * This works around the problem that log4j does not support the trace level.
+     * @param thrown the Throwable to ignore
+     */
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void ignore(Throwable thrown)
+    {
+        if (!initialized())
+            return;
+        LOG.ignore(thrown);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void info(String msg)
+    {
+        if (!initialized())
+            return;
+        LOG.info(msg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void info(String msg, Object arg)
+    {
+        if (!initialized())
+            return;
+        LOG.info(msg, arg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void info(String msg, Object arg0, Object arg1)
+    {
+        if (!initialized())
+            return;
+        LOG.info(msg, arg0, arg1);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static boolean isDebugEnabled()
+    {
+        if (!initialized())
+            return false;
+        return LOG.isDebugEnabled();
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void warn(String msg)
+    {
+        if (!initialized())
+            return;
+        LOG.warn(msg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void warn(String msg, Object arg)
+    {
+        if (!initialized())
+            return;
+        LOG.warn(msg, arg);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void warn(String msg, Object arg0, Object arg1)
+    {
+        if (!initialized())
+            return;
+        LOG.warn(msg, arg0, arg1);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void warn(String msg, Throwable th)
+    {
+        if (!initialized())
+            return;
+        LOG.warn(msg, th);
+    }
+
+    /**
+     * @deprecated anonymous logging is deprecated, use a named {@link Logger} obtained from {@link #getLogger(String)}
+     */
+    @Deprecated
+    public static void warn(Throwable th)
+    {
+        if (!initialized())
+            return;
+        LOG.warn(EXCEPTION, th);
+    }
+
+    /**
+     * Obtain a named Logger based on the fully qualified class name.
+     *
+     * @param clazz
+     *            the class to base the Logger name off of
+     * @return the Logger with the given name
+     */
+    public static Logger getLogger(Class<?> clazz)
+    {
+        return getLogger(clazz.getName());
+    }
+
+    /**
+     * Obtain a named Logger or the default Logger if null is passed.
+     * @param name the Logger name
+     * @return the Logger with the given name
+     */
+    public static Logger getLogger(String name)
+    {
+        if (!initialized())
+            return null;
+
+        if(name==null)
+            return LOG;
+
+        Logger logger = __loggers.get(name);
+        if(logger==null)
+            logger = LOG.getLogger(name);
+
+        return logger;
+    }
+
+    static ConcurrentMap<String, Logger> getMutableLoggers()
+    {
+        return __loggers;
+    }
+    
+    /**
+     * Get a map of all configured {@link Logger} instances.
+     *
+     * @return a map of all configured {@link Logger} instances
+     */
+    public static Map<String, Logger> getLoggers()
+    {
+        return Collections.unmodifiableMap(__loggers);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/Logger.java b/src/java/org/eclipse/jetty/util/log/Logger.java
new file mode 100644
index 0000000..83c499f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/Logger.java
@@ -0,0 +1,113 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+/**
+ * A simple logging facade that is intended simply to capture the style of logging as used by Jetty.
+ */
+public interface Logger
+{
+    /**
+     * @return the name of this logger
+     */
+    public String getName();
+
+    /**
+     * Formats and logs at warn level.
+     * @param msg the formatting string
+     * @param args the optional arguments
+     */
+    public void warn(String msg, Object... args);
+
+    /**
+     * Logs the given Throwable information at warn level
+     * @param thrown the Throwable to log
+     */
+    public void warn(Throwable thrown);
+
+    /**
+     * Logs the given message at warn level, with Throwable information.
+     * @param msg the message to log
+     * @param thrown the Throwable to log
+     */
+    public void warn(String msg, Throwable thrown);
+
+    /**
+     * Formats and logs at info level.
+     * @param msg the formatting string
+     * @param args the optional arguments
+     */
+    public void info(String msg, Object... args);
+
+    /**
+     * Logs the given Throwable information at info level
+     * @param thrown the Throwable to log
+     */
+    public void info(Throwable thrown);
+
+    /**
+     * Logs the given message at info level, with Throwable information.
+     * @param msg the message to log
+     * @param thrown the Throwable to log
+     */
+    public void info(String msg, Throwable thrown);
+
+    /**
+     * @return whether the debug level is enabled
+     */
+    public boolean isDebugEnabled();
+
+    /**
+     * Mutator used to turn debug on programmatically.
+     * @param enabled whether to enable the debug level
+     */
+    public void setDebugEnabled(boolean enabled);
+
+    /**
+     * Formats and logs at debug level.
+     * @param msg the formatting string
+     * @param args the optional arguments
+     */
+    public void debug(String msg, Object... args);
+
+    /**
+     * Logs the given Throwable information at debug level
+     * @param thrown the Throwable to log
+     */
+    public void debug(Throwable thrown);
+
+    /**
+     * Logs the given message at debug level, with Throwable information.
+     * @param msg the message to log
+     * @param thrown the Throwable to log
+     */
+    public void debug(String msg, Throwable thrown);
+
+    /**
+     * @param name the name of the logger
+     * @return a logger with the given name
+     */
+    public Logger getLogger(String name);
+    
+    /**
+     * Ignore an exception.
+     * <p>This should be used rather than an empty catch block.
+     */
+    public void ignore(Throwable ignored); 
+}
diff --git a/src/java/org/eclipse/jetty/util/log/LoggerLog.java b/src/java/org/eclipse/jetty/util/log/LoggerLog.java
new file mode 100644
index 0000000..f6fc052
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/LoggerLog.java
@@ -0,0 +1,213 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+import java.lang.reflect.Method;
+
+/**
+ *
+ */
+public class LoggerLog extends AbstractLogger
+{
+    private final Object _logger;
+    private final Method _debugMT;
+    private final Method _debugMAA;
+    private final Method _infoMT;
+    private final Method _infoMAA;
+    private final Method _warnMT;
+    private final Method _warnMAA;
+    private final Method _setDebugEnabledE;
+    private final Method _getLoggerN;
+    private final Method _getName;
+    private volatile boolean _debug;
+
+    public LoggerLog(Object logger)
+    {
+        try
+        {
+            _logger = logger;
+            Class<?> lc = logger.getClass();
+            _debugMT = lc.getMethod("debug", new Class[]{String.class, Throwable.class});
+            _debugMAA = lc.getMethod("debug", new Class[]{String.class, Object[].class});
+            _infoMT = lc.getMethod("info", new Class[]{String.class, Throwable.class});
+            _infoMAA = lc.getMethod("info", new Class[]{String.class, Object[].class});
+            _warnMT = lc.getMethod("warn", new Class[]{String.class, Throwable.class});
+            _warnMAA = lc.getMethod("warn", new Class[]{String.class, Object[].class});
+            Method _isDebugEnabled = lc.getMethod("isDebugEnabled");
+            _setDebugEnabledE = lc.getMethod("setDebugEnabled", new Class[]{Boolean.TYPE});
+            _getLoggerN = lc.getMethod("getLogger", new Class[]{String.class});
+            _getName = lc.getMethod("getName");
+
+            _debug = (Boolean)_isDebugEnabled.invoke(_logger);
+        }
+        catch(Exception x)
+        {
+            throw new IllegalStateException(x);
+        }
+    }
+
+    public String getName()
+    {
+        try
+        {
+            return (String)_getName.invoke(_logger);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public void warn(String msg, Object... args)
+    {
+        try
+        {
+            _warnMAA.invoke(_logger, args);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void warn(Throwable thrown)
+    {
+        warn("", thrown);
+    }
+
+    public void warn(String msg, Throwable thrown)
+    {
+        try
+        {
+            _warnMT.invoke(_logger, msg, thrown);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void info(String msg, Object... args)
+    {
+        try
+        {
+            _infoMAA.invoke(_logger, args);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void info(Throwable thrown)
+    {
+        info("", thrown);
+    }
+
+    public void info(String msg, Throwable thrown)
+    {
+        try
+        {
+            _infoMT.invoke(_logger, msg, thrown);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean isDebugEnabled()
+    {
+        return _debug;
+    }
+
+    public void setDebugEnabled(boolean enabled)
+    {
+        try
+        {
+            _setDebugEnabledE.invoke(_logger, enabled);
+            _debug = enabled;
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void debug(String msg, Object... args)
+    {
+        if (!_debug)
+            return;
+
+        try
+        {
+            _debugMAA.invoke(_logger, args);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void debug(Throwable thrown)
+    {
+        debug("", thrown);
+    }
+
+    public void debug(String msg, Throwable th)
+    {
+        if (!_debug)
+            return;
+
+        try
+        {
+            _debugMT.invoke(_logger, msg, th);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    public void ignore(Throwable ignored)
+    {
+        if (Log.isIgnored())
+        {
+            warn(Log.IGNORED, ignored);
+        }
+    }
+
+    /**
+     * Create a Child Logger of this Logger.
+     */
+    protected Logger newLogger(String fullname)
+    {
+        try
+        {
+            Object logger=_getLoggerN.invoke(_logger, fullname);
+            return new LoggerLog(logger);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            return this;
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/Slf4jLog.java b/src/java/org/eclipse/jetty/util/log/Slf4jLog.java
new file mode 100644
index 0000000..c5f739d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/Slf4jLog.java
@@ -0,0 +1,133 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+
+
+/**
+ * Slf4jLog Logger
+ */
+public class Slf4jLog extends AbstractLogger
+{
+    private final org.slf4j.Logger _logger;
+
+    public Slf4jLog() throws Exception
+    {
+        this("org.eclipse.jetty.util.log");
+    }
+
+    public Slf4jLog(String name)
+    {
+        //NOTE: if only an slf4j-api jar is on the classpath, slf4j will use a NOPLogger
+        org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger( name );
+        
+        // Fix LocationAwareLogger use to indicate FQCN of this class - 
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=276670
+        if (logger instanceof org.slf4j.spi.LocationAwareLogger)
+        {
+            _logger = new JettyAwareLogger((org.slf4j.spi.LocationAwareLogger)logger);
+        }
+        else
+        {
+            _logger = logger;
+        }
+    }
+
+    public String getName()
+    {
+        return _logger.getName();
+    }
+
+    public void warn(String msg, Object... args)
+    {
+        _logger.warn(msg, args);
+    }
+
+    public void warn(Throwable thrown)
+    {
+        warn("", thrown);
+    }
+
+    public void warn(String msg, Throwable thrown)
+    {
+        _logger.warn(msg, thrown);
+    }
+
+    public void info(String msg, Object... args)
+    {
+        _logger.info(msg, args);
+    }
+
+    public void info(Throwable thrown)
+    {
+        info("", thrown);
+    }
+
+    public void info(String msg, Throwable thrown)
+    {
+        _logger.info(msg, thrown);
+    }
+
+    public void debug(String msg, Object... args)
+    {
+        _logger.debug(msg, args);
+    }
+
+    public void debug(Throwable thrown)
+    {
+        debug("", thrown);
+    }
+
+    public void debug(String msg, Throwable thrown)
+    {
+        _logger.debug(msg, thrown);
+    }
+
+    public boolean isDebugEnabled()
+    {
+        return _logger.isDebugEnabled();
+    }
+
+    public void setDebugEnabled(boolean enabled)
+    {
+        warn("setDebugEnabled not implemented",null,null);
+    }
+
+    /**
+     * Create a Child Logger of this Logger.
+     */
+    protected Logger newLogger(String fullname)
+    {
+        return new Slf4jLog(fullname);
+    }
+
+    public void ignore(Throwable ignored)
+    {
+        if (Log.isIgnored())
+        {
+            warn(Log.IGNORED, ignored);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return _logger.toString();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/StdErrLog.java b/src/java/org/eclipse/jetty/util/log/StdErrLog.java
new file mode 100644
index 0000000..8373c07
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/StdErrLog.java
@@ -0,0 +1,630 @@
+//
+//  ========================================================================
+//  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.util.log;
+
+import java.io.PrintStream;
+import java.security.AccessControlException;
+import java.util.Properties;
+
+import org.eclipse.jetty.util.DateCache;
+
+/**
+ * StdErr Logging. This implementation of the Logging facade sends all logs to StdErr with minimal formatting.
+ * <p>
+ * If the system property "org.eclipse.jetty.LEVEL" is set to one of the following (ALL, DEBUG, INFO, WARN), then set
+ * the eclipse jetty root level logger level to that specified level. (Default level is INFO)
+ * <p>
+ * If the system property "org.eclipse.jetty.util.log.SOURCE" is set, then the source method/file of a log is logged.
+ * For named debuggers, the system property name+".SOURCE" is checked, eg "org.eclipse.jetty.util.log.stderr.SOURCE". 
+ * If it is not not set, then "org.eclipse.jetty.util.log.SOURCE" is used as the default.
+ * <p>
+ * If the system property "org.eclipse.jetty.util.log.stderr.LONG" is set, then the full, unabbreviated name of the logger is
+ * used for logging.
+ */
+public class StdErrLog extends AbstractLogger
+{
+    private static final String EOL = System.getProperty("line.separator");
+    private static DateCache _dateCache;
+    private static final Properties __props = new Properties();
+
+    private final static boolean __source = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.SOURCE",
+            Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
+    private final static boolean __long = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
+
+    static
+    {
+        __props.putAll(Log.__props);
+        
+        String deprecatedProperties[] =
+        { "DEBUG", "org.eclipse.jetty.util.log.DEBUG", "org.eclipse.jetty.util.log.stderr.DEBUG" };
+
+        // Toss a message to users about deprecated system properties
+        for (String deprecatedProp : deprecatedProperties)
+        {
+            if (System.getProperty(deprecatedProp) != null)
+            {
+                System.err.printf("System Property [%s] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead)%n",deprecatedProp);
+            }
+        }
+
+        try
+        {
+            _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
+        }
+        catch (Exception x)
+        {
+            x.printStackTrace(System.err);
+        }
+    }
+
+    public static final int LEVEL_ALL = 0;
+    public static final int LEVEL_DEBUG = 1;
+    public static final int LEVEL_INFO = 2;
+    public static final int LEVEL_WARN = 3;
+
+    private int _level = LEVEL_INFO;
+    // Level that this Logger was configured as (remembered in special case of .setDebugEnabled())
+    private int _configuredLevel;
+    private PrintStream _stderr = null;
+    private boolean _source = __source;
+    // Print the long form names, otherwise use abbreviated
+    private boolean _printLongNames = __long;
+    // The full log name, as provided by the system.
+    private final String _name;
+    // The abbreviated log name (used by default, unless _long is specified)
+    private final String _abbrevname;
+    private boolean _hideStacks = false;
+
+    public StdErrLog()
+    {
+        this(null);
+    }
+
+    public StdErrLog(String name)
+    {
+        this(name,__props);
+    }
+
+    public StdErrLog(String name, Properties props)
+    {
+        if (props!=null && props!=__props)
+            __props.putAll(props);
+        this._name = name == null?"":name;
+        this._abbrevname = condensePackageString(this._name);
+        this._level = getLoggingLevel(props,this._name);
+        this._configuredLevel = this._level;
+
+        try
+        {
+            _source = Boolean.parseBoolean(props.getProperty(_name + ".SOURCE",Boolean.toString(_source)));
+        }
+        catch (AccessControlException ace)
+        {
+            _source = __source;
+        }
+    }
+
+    /**
+     * Get the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
+     * shortest.
+     *
+     * @param props
+     *            the properties to check
+     * @param name
+     *            the name to get log for
+     * @return the logging level
+     */
+    public static int getLoggingLevel(Properties props, final String name)
+    {
+        // Calculate the level this named logger should operate under.
+        // Checking with FQCN first, then each package segment from longest to shortest.
+        String nameSegment = name;
+
+        while ((nameSegment != null) && (nameSegment.length() > 0))
+        {
+            String levelStr = props.getProperty(nameSegment + ".LEVEL");
+            // System.err.printf("[StdErrLog.CONFIG] Checking for property [%s.LEVEL] = %s%n",nameSegment,levelStr);
+            int level = getLevelId(nameSegment + ".LEVEL",levelStr);
+            if (level != (-1))
+            {
+                return level;
+            }
+
+            // Trim and try again.
+            int idx = nameSegment.lastIndexOf('.');
+            if (idx >= 0)
+            {
+                nameSegment = nameSegment.substring(0,idx);
+            }
+            else
+            {
+                nameSegment = null;
+            }
+        }
+
+        // Default Logging Level
+        return getLevelId("log.LEVEL",props.getProperty("log.LEVEL","INFO"));
+    }
+
+    protected static int getLevelId(String levelSegment, String levelName)
+    {
+        if (levelName == null)
+        {
+            return -1;
+        }
+        String levelStr = levelName.trim();
+        if ("ALL".equalsIgnoreCase(levelStr))
+        {
+            return LEVEL_ALL;
+        }
+        else if ("DEBUG".equalsIgnoreCase(levelStr))
+        {
+            return LEVEL_DEBUG;
+        }
+        else if ("INFO".equalsIgnoreCase(levelStr))
+        {
+            return LEVEL_INFO;
+        }
+        else if ("WARN".equalsIgnoreCase(levelStr))
+        {
+            return LEVEL_WARN;
+        }
+
+        System.err.println("Unknown StdErrLog level [" + levelSegment + "]=[" + levelStr + "], expecting only [ALL, DEBUG, INFO, WARN] as values.");
+        return -1;
+    }
+
+    /**
+     * Condenses a classname by stripping down the package name to just the first character of each package name
+     * segment.Configured
+     * <p>
+     *
+     * <pre>
+     * Examples:
+     * "org.eclipse.jetty.test.FooTest"           = "oejt.FooTest"
+     * "org.eclipse.jetty.server.logging.LogTest" = "orjsl.LogTest"
+     * </pre>
+     *
+     * @param classname
+     *            the fully qualified class name
+     * @return the condensed name
+     */
+    protected static String condensePackageString(String classname)
+    {
+        String parts[] = classname.split("\\.");
+        StringBuilder dense = new StringBuilder();
+        for (int i = 0; i < (parts.length - 1); i++)
+        {
+            dense.append(parts[i].charAt(0));
+        }
+        if (dense.length() > 0)
+        {
+            dense.append('.');
+        }
+        dense.append(parts[parts.length - 1]);
+        return dense.toString();
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public void setPrintLongNames(boolean printLongNames)
+    {
+        this._printLongNames = printLongNames;
+    }
+
+    public boolean isPrintLongNames()
+    {
+        return this._printLongNames;
+    }
+
+    public boolean isHideStacks()
+    {
+        return _hideStacks;
+    }
+
+    public void setHideStacks(boolean hideStacks)
+    {
+        _hideStacks = hideStacks;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Is the source of a log, logged
+     *
+     * @return true if the class, method, file and line number of a log is logged.
+     */
+    public boolean isSource()
+    {
+        return _source;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if a log source is logged.
+     *
+     * @param source
+     *            true if the class, method, file and line number of a log is logged.
+     */
+    public void setSource(boolean source)
+    {
+        _source = source;
+    }
+
+    public void warn(String msg, Object... args)
+    {
+        if (_level <= LEVEL_WARN)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":WARN:",msg,args);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    public void warn(Throwable thrown)
+    {
+        warn("",thrown);
+    }
+
+    public void warn(String msg, Throwable thrown)
+    {
+        if (_level <= LEVEL_WARN)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":WARN:",msg,thrown);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    public void info(String msg, Object... args)
+    {
+        if (_level <= LEVEL_INFO)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":INFO:",msg,args);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    public void info(Throwable thrown)
+    {
+        info("",thrown);
+    }
+
+    public void info(String msg, Throwable thrown)
+    {
+        if (_level <= LEVEL_INFO)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":INFO:",msg,thrown);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    public boolean isDebugEnabled()
+    {
+        return (_level <= LEVEL_DEBUG);
+    }
+
+    /**
+     * Legacy interface where a programmatic configuration of the logger level
+     * is done as a wholesale approach.
+     */
+    public void setDebugEnabled(boolean enabled)
+    {
+        if (enabled)
+        {
+            this._level = LEVEL_DEBUG;
+
+            for (Logger log : Log.getLoggers().values())
+            {                
+                if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
+                    ((StdErrLog)log).setLevel(LEVEL_DEBUG);
+            }
+        }
+        else
+        {
+            this._level = this._configuredLevel;
+            
+            for (Logger log : Log.getLoggers().values())
+            {
+                if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
+                    ((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
+            }
+        }
+    }
+
+    public int getLevel()
+    {
+        return _level;
+    }
+
+    /**
+     * Set the level for this logger.
+     * <p>
+     * Available values ({@link StdErrLog#LEVEL_ALL}, {@link StdErrLog#LEVEL_DEBUG}, {@link StdErrLog#LEVEL_INFO},
+     * {@link StdErrLog#LEVEL_WARN})
+     *
+     * @param level
+     *            the level to set the logger to
+     */
+    public void setLevel(int level)
+    {
+        this._level = level;
+    }
+
+    public void setStdErrStream(PrintStream stream)
+    {
+        this._stderr = stream==System.err?null:stream;
+    }
+
+    public void debug(String msg, Object... args)
+    {
+        if (_level <= LEVEL_DEBUG)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":DBUG:",msg,args);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    public void debug(Throwable thrown)
+    {
+        debug("",thrown);
+    }
+
+    public void debug(String msg, Throwable thrown)
+    {
+        if (_level <= LEVEL_DEBUG)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":DBUG:",msg,thrown);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+
+    private void format(StringBuilder buffer, String level, String msg, Object... args)
+    {
+        String d = _dateCache.now();
+        int ms = _dateCache.lastMs();
+        tag(buffer,d,ms,level);
+        format(buffer,msg,args);
+    }
+
+    private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
+    {
+        format(buffer,level,msg);
+        if (isHideStacks())
+        {
+            format(buffer,String.valueOf(thrown));
+        }
+        else
+        {
+            format(buffer,thrown);
+        }
+    }
+
+    private void tag(StringBuilder buffer, String d, int ms, String tag)
+    {
+        buffer.setLength(0);
+        buffer.append(d);
+        if (ms > 99)
+        {
+            buffer.append('.');
+        }
+        else if (ms > 9)
+        {
+            buffer.append(".0");
+        }
+        else
+        {
+            buffer.append(".00");
+        }
+        buffer.append(ms).append(tag);
+        if (_printLongNames)
+        {
+            buffer.append(_name);
+        }
+        else
+        {
+            buffer.append(_abbrevname);
+        }
+        buffer.append(':');
+        if (_source)
+        {
+            Throwable source = new Throwable();
+            StackTraceElement[] frames = source.getStackTrace();
+            for (int i = 0; i < frames.length; i++)
+            {
+                final StackTraceElement frame = frames[i];
+                String clazz = frame.getClassName();
+                if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
+                {
+                    continue;
+                }
+                if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
+                {
+                    buffer.append(condensePackageString(clazz));
+                }
+                else
+                {
+                    buffer.append(clazz);
+                }
+                buffer.append('#').append(frame.getMethodName());
+                if (frame.getFileName() != null)
+                {
+                    buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
+                }
+                buffer.append(':');
+                break;
+            }
+        }
+    }
+
+    private void format(StringBuilder builder, String msg, Object... args)
+    {
+        if (msg == null)
+        {
+            msg = "";
+            for (int i = 0; i < args.length; i++)
+            {
+                msg += "{} ";
+            }
+        }
+        String braces = "{}";
+        int start = 0;
+        for (Object arg : args)
+        {
+            int bracesIndex = msg.indexOf(braces,start);
+            if (bracesIndex < 0)
+            {
+                escape(builder,msg.substring(start));
+                builder.append(" ");
+                builder.append(arg);
+                start = msg.length();
+            }
+            else
+            {
+                escape(builder,msg.substring(start,bracesIndex));
+                builder.append(String.valueOf(arg));
+                start = bracesIndex + braces.length();
+            }
+        }
+        escape(builder,msg.substring(start));
+    }
+
+    private void escape(StringBuilder builder, String string)
+    {
+        for (int i = 0; i < string.length(); ++i)
+        {
+            char c = string.charAt(i);
+            if (Character.isISOControl(c))
+            {
+                if (c == '\n')
+                {
+                    builder.append('|');
+                }
+                else if (c == '\r')
+                {
+                    builder.append('<');
+                }
+                else
+                {
+                    builder.append('?');
+                }
+            }
+            else
+            {
+                builder.append(c);
+            }
+        }
+    }
+
+    private void format(StringBuilder buffer, Throwable thrown)
+    {
+        if (thrown == null)
+        {
+            buffer.append("null");
+        }
+        else
+        {
+            buffer.append(EOL);
+            format(buffer,thrown.toString());
+            StackTraceElement[] elements = thrown.getStackTrace();
+            for (int i = 0; elements != null && i < elements.length; i++)
+            {
+                buffer.append(EOL).append("\tat ");
+                format(buffer,elements[i].toString());
+            }
+
+            Throwable cause = thrown.getCause();
+            if (cause != null && cause != thrown)
+            {
+                buffer.append(EOL).append("Caused by: ");
+                format(buffer,cause);
+            }
+        }
+    }
+
+
+    /**
+     * Create a Child Logger of this Logger.
+     */
+    protected Logger newLogger(String fullname)
+    {
+        StdErrLog logger = new StdErrLog(fullname);
+        // Preserve configuration for new loggers configuration
+        logger.setPrintLongNames(_printLongNames);
+        // Let Level come from configured Properties instead - sel.setLevel(_level);
+        logger.setSource(_source);
+        logger._stderr = this._stderr;
+        
+        // Force the child to have any programmatic configuration
+        if (_level!=_configuredLevel)
+            logger._level=_level;
+
+        return logger;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder s = new StringBuilder();
+        s.append("StdErrLog:");
+        s.append(_name);
+        s.append(":LEVEL=");
+        switch (_level)
+        {
+            case LEVEL_ALL:
+                s.append("ALL");
+                break;
+            case LEVEL_DEBUG:
+                s.append("DEBUG");
+                break;
+            case LEVEL_INFO:
+                s.append("INFO");
+                break;
+            case LEVEL_WARN:
+                s.append("WARN");
+                break;
+            default:
+                s.append("?");
+                break;
+        }
+        return s.toString();
+    }
+
+    public static void setProperties(Properties props)
+    {
+        __props.clear();
+        __props.putAll(props);
+    }
+
+    public void ignore(Throwable ignored)
+    {
+        if (_level <= LEVEL_ALL)
+        {
+            StringBuilder buffer = new StringBuilder(64);
+            format(buffer,":IGNORED:","",ignored);
+            (_stderr==null?System.err:_stderr).println(buffer);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/log/jmx/LogMBean.java b/src/java/org/eclipse/jetty/util/log/jmx/LogMBean.java
new file mode 100644
index 0000000..9581a24
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/log/jmx/LogMBean.java
@@ -0,0 +1,53 @@
+//
+//  ========================================================================
+//  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.util.log.jmx;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jetty.jmx.ObjectMBean;
+import org.eclipse.jetty.util.log.Log;
+
+/* ------------------------------------------------------------ */
+/**
+ */
+public class LogMBean extends ObjectMBean
+{
+
+    public LogMBean(Object managedObject)
+    {
+        super(managedObject);
+    }
+
+    public List<String> getLoggers()
+    {
+        List<String> keySet = new ArrayList<String>(Log.getLoggers().keySet());
+        return keySet;
+    }
+
+    public boolean isDebugEnabled(String logger)
+    {
+        return Log.getLogger(logger).isDebugEnabled();
+    }
+
+    public void setDebugEnabled(String logger, Boolean enabled)
+    {
+        Log.getLogger(logger).setDebugEnabled(enabled);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java
new file mode 100644
index 0000000..0f6caf9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java
@@ -0,0 +1,47 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import java.awt.Toolkit;
+
+/**
+ * AWTLeakPreventer
+ *
+ * See https://issues.jboss.org/browse/AS7-3733
+ * 
+ * The java.awt.Toolkit class has a static field that is the default toolkit. 
+ * Creating the default toolkit causes the creation of an EventQueue, which has a 
+ * classloader field initialized by the thread context class loader. 
+ *
+ */
+public class AWTLeakPreventer extends AbstractLeakPreventer
+{
+   
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        LOG.debug("Pinning classloader for java.awt.EventQueue using "+loader);
+        Toolkit.getDefaultToolkit();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/AbstractLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/AbstractLeakPreventer.java
new file mode 100644
index 0000000..2322a76
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/AbstractLeakPreventer.java
@@ -0,0 +1,62 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * AbstractLeakPreventer
+ *
+ * Abstract base class for code that seeks to avoid pinning of webapp classloaders by using the jetty classloader to
+ * proactively call the code that pins them (generally pinned as static data members, or as static
+ * data members that are daemon threads (which use the context classloader)).
+ * 
+ * Instances of subclasses of this class should be set with Server.addBean(), which will
+ * ensure that they are called when the Server instance starts up, which will have the jetty
+ * classloader in scope.
+ *
+ */
+public abstract class AbstractLeakPreventer extends AbstractLifeCycle
+{
+    protected static final Logger LOG = Log.getLogger(AbstractLeakPreventer.class);
+    
+    /* ------------------------------------------------------------ */
+    abstract public void prevent(ClassLoader loader);
+    
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        try
+        {
+            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+            prevent(getClass().getClassLoader());
+            super.doStart();
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader(loader);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java
new file mode 100644
index 0000000..0cfd3c9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java
@@ -0,0 +1,41 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import javax.imageio.ImageIO;
+
+/**
+ * AppContextLeakPreventer
+ *
+ * Cause the classloader that is pinned by AppContext.getAppContext() to be 
+ * a container or system classloader, not a webapp classloader.
+ * 
+ * Inspired by Tomcat JreMemoryLeakPrevention.
+ */
+public class AppContextLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        LOG.debug("Pinning classloader for AppContext.getContext() with "+loader);
+        ImageIO.getUseCache();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/DOMLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/DOMLeakPreventer.java
new file mode 100644
index 0000000..5fee365
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/DOMLeakPreventer.java
@@ -0,0 +1,56 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/**
+ * DOMLeakPreventer
+ *
+ * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498
+ * 
+ * Prevent the RuntimeException that is a static member of AbstractDOMParser
+ * from pinning a webapp classloader by causing it to be set here by a non-webapp classloader.
+ * 
+ * Note that according to the bug report, a heap dump may not identify the GCRoot, making 
+ * it difficult to identify the cause of the leak.
+ *
+ */
+public class DOMLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        try 
+        {
+            factory.newDocumentBuilder();
+        } 
+        catch (Exception e) 
+        {
+            LOG.warn(e);
+        }
+
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/DriverManagerLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/DriverManagerLeakPreventer.java
new file mode 100644
index 0000000..d229ba7
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/DriverManagerLeakPreventer.java
@@ -0,0 +1,42 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import java.sql.DriverManager;
+
+
+/**
+ * DriverManagerLeakPreventer
+ *
+ * Cause DriverManager.getCallerClassLoader() to be called, which will pin the classloader.
+ * 
+ * Inspired by Tomcat JreMemoryLeakPrevention.
+ */
+public class DriverManagerLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        LOG.debug("Pinning DriverManager classloader with "+loader);
+        DriverManager.getDrivers();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/GCThreadLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/GCThreadLeakPreventer.java
new file mode 100644
index 0000000..6ea4de2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/GCThreadLeakPreventer.java
@@ -0,0 +1,64 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import java.lang.reflect.Method;
+
+/**
+ * GCThreadLeakPreventer
+ *
+ * Prevents a call to sun.misc.GC.requestLatency pinning a webapp classloader
+ * by calling it with a non-webapp classloader. The problem appears to be that
+ * when this method is called, a daemon thread is created which takes the 
+ * context classloader. A known caller of this method is the RMI impl. See
+ * http://stackoverflow.com/questions/6626680/does-java-garbage-collection-log-entry-full-gc-system-mean-some-class-called
+ * 
+ * This preventer will start the thread with the longest possible interval, although
+ * subsequent calls can vary that. Recommend to only use this class if you're doing
+ * RMI.
+ * 
+ * Inspired by Tomcat JreMemoryLeakPrevention.
+ *
+ */
+public class GCThreadLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        try
+        {
+            Class clazz = Class.forName("sun.misc.GC");
+            Method requestLatency = clazz.getMethod("requestLatency", new Class[] {long.class});
+            requestLatency.invoke(null, Long.valueOf(Long.MAX_VALUE-1));
+        }
+        catch (ClassNotFoundException e)
+        {
+            LOG.ignore(e);
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/Java2DLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/Java2DLeakPreventer.java
new file mode 100644
index 0000000..3a2ad82
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/Java2DLeakPreventer.java
@@ -0,0 +1,49 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+/**
+ * Java2DLeakPreventer
+ *
+ * Prevent pinning of webapp classloader by pre-loading sun.java2d.Disposer class
+ * before webapp classloaders are created.
+ * 
+ * See https://issues.apache.org/bugzilla/show_bug.cgi?id=51687
+ *
+ */
+public class Java2DLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        try
+        {
+            Class.forName("sun.java2d.Disposer", true, loader);
+        }
+        catch (ClassNotFoundException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/LDAPLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/LDAPLeakPreventer.java
new file mode 100644
index 0000000..5c497d1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/LDAPLeakPreventer.java
@@ -0,0 +1,51 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+/**
+ * LDAPLeakPreventer
+ *
+ * If com.sun.jndi.LdapPoolManager class is loaded and the system property
+ * com.sun.jndi.ldap.connect.pool.timeout is set to a nonzero value, a daemon
+ * thread is started which can pin a webapp classloader if it is the first to
+ * load the LdapPoolManager.
+ * 
+ * Inspired by Tomcat JreMemoryLeakPrevention
+ *
+ */
+public class LDAPLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        try
+        {
+            Class.forName("com.sun.jndi.LdapPoolManager", true, loader);
+        }
+        catch (ClassNotFoundException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/LoginConfigurationLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/LoginConfigurationLeakPreventer.java
new file mode 100644
index 0000000..c1d9fe2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/LoginConfigurationLeakPreventer.java
@@ -0,0 +1,49 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+/**
+ * LoginConfigurationLeakPreventer
+ *
+ * The javax.security.auth.login.Configuration class keeps a static reference to the 
+ * thread context classloader. We prevent a webapp context classloader being used for
+ * that by invoking the classloading here.
+ * 
+ * Inspired by Tomcat JreMemoryLeakPrevention
+ */
+public class LoginConfigurationLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        try
+        {
+            Class.forName("javax.security.auth.login.Configuration", true, loader);
+        }
+        catch (ClassNotFoundException e)
+        {
+            LOG.warn(e);
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/preventers/SecurityProviderLeakPreventer.java b/src/java/org/eclipse/jetty/util/preventers/SecurityProviderLeakPreventer.java
new file mode 100644
index 0000000..9976c56
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/preventers/SecurityProviderLeakPreventer.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.util.preventers;
+
+import java.security.Security;
+
+/**
+ * SecurityProviderLeakPreventer
+ *
+ * Some security providers, such as sun.security.pkcs11.SunPKCS11 start a deamon thread,
+ * which will use the thread context classloader. Load them here to ensure the classloader
+ * is not a webapp classloader.
+ *
+ * Inspired by Tomcat JreMemoryLeakPrevention
+ */
+public class SecurityProviderLeakPreventer extends AbstractLeakPreventer
+{
+    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.util.preventers.AbstractLeakPreventer#prevent(java.lang.ClassLoader)
+     */
+    @Override
+    public void prevent(ClassLoader loader)
+    {
+        Security.getProviders();
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/BadResource.java b/src/java/org/eclipse/jetty/util/resource/BadResource.java
new file mode 100644
index 0000000..fbb27f2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/BadResource.java
@@ -0,0 +1,139 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+
+
+/* ------------------------------------------------------------ */
+/** Bad Resource.
+ *
+ * A Resource that is returned for a bade URL.  Acts as a resource
+ * that does not exist and throws appropriate exceptions.
+ *
+ * 
+ */
+class BadResource extends URLResource
+{
+    /* ------------------------------------------------------------ */
+    private String _message=null;
+        
+    /* -------------------------------------------------------- */
+    BadResource(URL url,  String message)
+    {
+        super(url,null);
+        _message=message;
+    }
+    
+
+    /* -------------------------------------------------------- */
+    @Override
+    public boolean exists()
+    {
+        return false;
+    }
+        
+    /* -------------------------------------------------------- */
+    @Override
+    public long lastModified()
+    {
+        return -1;
+    }
+
+    /* -------------------------------------------------------- */
+    @Override
+    public boolean isDirectory()
+    {
+        return false;
+    }
+
+    /* --------------------------------------------------------- */
+    @Override
+    public long length()
+    {
+        return -1;
+    }
+        
+        
+    /* ------------------------------------------------------------ */
+    @Override
+    public File getFile()
+    {
+        return null;
+    }
+        
+    /* --------------------------------------------------------- */
+    @Override
+    public InputStream getInputStream() throws IOException
+    {
+        throw new FileNotFoundException(_message);
+    }
+        
+    /* --------------------------------------------------------- */
+    @Override
+    public OutputStream getOutputStream()
+        throws java.io.IOException, SecurityException
+    {
+        throw new FileNotFoundException(_message);
+    }
+        
+    /* --------------------------------------------------------- */
+    @Override
+    public boolean delete()
+        throws SecurityException
+    {
+        throw new SecurityException(_message);
+    }
+
+    /* --------------------------------------------------------- */
+    @Override
+    public boolean renameTo( Resource dest)
+        throws SecurityException
+    {
+        throw new SecurityException(_message);
+    }
+
+    /* --------------------------------------------------------- */
+    @Override
+    public String[] list()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void copyTo(File destination)
+        throws IOException
+    {
+        throw new SecurityException(_message);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return super.toString()+"; BadResource="+_message;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/FileResource.java b/src/java/org/eclipse/jetty/util/resource/FileResource.java
new file mode 100644
index 0000000..322c13c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/FileResource.java
@@ -0,0 +1,400 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** File Resource.
+ *
+ * Handle resources of implied or explicit file type.
+ * This class can check for aliasing in the filesystem (eg case
+ * insensitivity).  By default this is turned on, or it can be controlled 
+ * by calling the static method @see FileResource#setCheckAliases(boolean)
+ * 
+ */
+public class FileResource extends URLResource
+{
+    private static final Logger LOG = Log.getLogger(FileResource.class);
+    private static boolean __checkAliases = true;
+
+    /* ------------------------------------------------------------ */
+    private File _file;
+    private transient URL _alias=null;
+    private transient boolean _aliasChecked=false;
+
+    /* ------------------------------------------------------------------------------- */
+    /** setCheckAliases.
+     * @param checkAliases True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
+     */
+    public static void setCheckAliases(boolean checkAliases)
+    {
+        __checkAliases=checkAliases;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /** getCheckAliases.
+     * @return True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
+     */
+    public static boolean getCheckAliases()
+    {
+        return __checkAliases;
+    }
+    
+    /* -------------------------------------------------------- */
+    public FileResource(URL url)
+        throws IOException, URISyntaxException
+    {
+        super(url,null);
+
+        try
+        {
+            // Try standard API to convert URL to file.
+            _file =new File(new URI(url.toString()));
+        }
+        catch (URISyntaxException e) 
+        {
+            throw e;
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+            try
+            {
+                // Assume that File.toURL produced unencoded chars. So try
+                // encoding them.
+                String file_url="file:"+URIUtil.encodePath(url.toString().substring(5));           
+                URI uri = new URI(file_url);
+                if (uri.getAuthority()==null) 
+                    _file = new File(uri);
+                else
+                    _file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile()));
+            }
+            catch (Exception e2)
+            {
+                LOG.ignore(e2);
+
+                // Still can't get the file.  Doh! try good old hack!
+                checkConnection();
+                Permission perm = _connection.getPermission();
+                _file = new File(perm==null?url.getFile():perm.getName());
+            }
+        }
+        if (_file.isDirectory())
+        {
+            if (!_urlString.endsWith("/"))
+                _urlString=_urlString+"/";
+        }
+        else
+        {
+            if (_urlString.endsWith("/"))
+                _urlString=_urlString.substring(0,_urlString.length()-1);
+        }
+
+    }
+
+    /* -------------------------------------------------------- */
+    FileResource(URL url, URLConnection connection, File file)
+    {
+        super(url,connection);
+        _file=file;
+        if (_file.isDirectory() && !_urlString.endsWith("/"))
+            _urlString=_urlString+"/";
+    }
+    
+    /* -------------------------------------------------------- */
+    @Override
+    public Resource addPath(String path)
+        throws IOException,MalformedURLException
+    {
+        URLResource r=null;
+        String url=null;
+
+        path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);
+       
+        if ("/".equals(path))
+            return this;
+        else if (!isDirectory())
+        {
+            r=(FileResource)super.addPath(path);
+            url=r._urlString;
+        }
+        else
+        {
+            if (path==null)
+                throw new MalformedURLException();   
+            
+            // treat all paths being added as relative
+            String rel=path;
+            if (path.startsWith("/"))
+                rel = path.substring(1);
+            
+            url=URIUtil.addPaths(_urlString,URIUtil.encodePath(rel));
+            r=(URLResource)Resource.newResource(url);
+        }
+        
+        // Check for encoding aliases
+        // The encoded path should be a suffix of the resource (give or take a directory / )
+        String encoded=URIUtil.encodePath(path);
+        int expected=r.toString().length()-encoded.length();
+        int index = r._urlString.lastIndexOf(encoded, expected);
+        if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory()))
+        {
+            if (r instanceof FileResource)
+            {
+                ((FileResource)r)._alias=((FileResource)r)._file.getCanonicalFile().toURI().toURL();
+                ((FileResource)r)._aliasChecked=true;
+            }
+        }                             
+        return r;
+    }
+   
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public URL getAlias()
+    {
+        if (__checkAliases && !_aliasChecked)
+        {
+            try
+            {    
+                String abs=_file.getAbsolutePath();
+                String can=_file.getCanonicalPath();
+                
+                if (abs.length()!=can.length() || !abs.equals(can))
+                    _alias=Resource.toURL(new File(can));
+                
+                _aliasChecked=true;
+                
+                if (_alias!=null && LOG.isDebugEnabled())
+                {
+                    LOG.debug("ALIAS abs="+abs);
+                    LOG.debug("ALIAS can="+can);
+                }
+            }
+            catch(Exception e)
+            {
+                LOG.warn(Log.EXCEPTION,e);
+                return getURL();
+            }                
+        }
+        return _alias;
+    }
+    
+    /* -------------------------------------------------------- */
+    /**
+     * Returns true if the resource exists.
+     */
+    @Override
+    public boolean exists()
+    {
+        return _file.exists();
+    }
+        
+    /* -------------------------------------------------------- */
+    /**
+     * Returns the last modified time
+     */
+    @Override
+    public long lastModified()
+    {
+        return _file.lastModified();
+    }
+
+    /* -------------------------------------------------------- */
+    /**
+     * Returns true if the respresenetd resource is a container/directory.
+     */
+    @Override
+    public boolean isDirectory()
+    {
+        return _file.isDirectory();
+    }
+
+    /* --------------------------------------------------------- */
+    /**
+     * Return the length of the resource
+     */
+    @Override
+    public long length()
+    {
+        return _file.length();
+    }
+        
+
+    /* --------------------------------------------------------- */
+    /**
+     * Returns the name of the resource
+     */
+    @Override
+    public String getName()
+    {
+        return _file.getAbsolutePath();
+    }
+        
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an File representing the given resource or NULL if this
+     * is not possible.
+     */
+    @Override
+    public File getFile()
+    {
+        return _file;
+    }
+        
+    /* --------------------------------------------------------- */
+    /**
+     * Returns an input stream to the resource
+     */
+    @Override
+    public InputStream getInputStream() throws IOException
+    {
+        return new FileInputStream(_file);
+    }
+        
+    /* --------------------------------------------------------- */
+    /**
+     * Returns an output stream to the resource
+     */
+    @Override
+    public OutputStream getOutputStream()
+        throws java.io.IOException, SecurityException
+    {
+        return new FileOutputStream(_file);
+    }
+        
+    /* --------------------------------------------------------- */
+    /**
+     * Deletes the given resource
+     */
+    @Override
+    public boolean delete()
+        throws SecurityException
+    {
+        return _file.delete();
+    }
+
+    /* --------------------------------------------------------- */
+    /**
+     * Rename the given resource
+     */
+    @Override
+    public boolean renameTo( Resource dest)
+        throws SecurityException
+    {
+        if( dest instanceof FileResource)
+            return _file.renameTo( ((FileResource)dest)._file);
+        else
+            return false;
+    }
+
+    /* --------------------------------------------------------- */
+    /**
+     * Returns a list of resources contained in the given resource
+     */
+    @Override
+    public String[] list()
+    {
+        String[] list =_file.list();
+        if (list==null)
+            return null;
+        for (int i=list.length;i-->0;)
+        {
+            if (new File(_file,list[i]).isDirectory() &&
+                !list[i].endsWith("/"))
+                list[i]+="/";
+        }
+        return list;
+    }
+         
+    /* ------------------------------------------------------------ */
+    /** Encode according to this resource type.
+     * File URIs are encoded.
+     * @param uri URI to encode.
+     * @return The uri unchanged.
+     */
+    @Override
+    public String encode(String uri)
+    {
+        return uri;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @param o
+     * @return <code>true</code> of the object <code>o</code> is a {@link FileResource} pointing to the same file as this resource. 
+     */
+    @Override
+    public boolean equals( Object o)
+    {
+        if (this == o)
+            return true;
+
+        if (null == o || ! (o instanceof FileResource))
+            return false;
+
+        FileResource f=(FileResource)o;
+        return f._file == _file || (null != _file && _file.equals(f._file));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the hashcode.
+     */
+    @Override
+    public int hashCode()
+    {
+       return null == _file ? super.hashCode() : _file.hashCode();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void copyTo(File destination)
+        throws IOException
+    {
+        if (isDirectory())
+        {
+            IO.copyDir(getFile(),destination);
+        }
+        else
+        {
+            if (destination.exists())
+                throw new IllegalArgumentException(destination+" exists");
+            IO.copy(getFile(),destination);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/JarFileResource.java b/src/java/org/eclipse/jetty/util/resource/JarFileResource.java
new file mode 100644
index 0000000..ae33ac1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/JarFileResource.java
@@ -0,0 +1,435 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+class JarFileResource extends JarResource
+{
+    private static final Logger LOG = Log.getLogger(JarFileResource.class);
+    private JarFile _jarFile;
+    private File _file;
+    private String[] _list;
+    private JarEntry _entry;
+    private boolean _directory;
+    private String _jarUrl;
+    private String _path;
+    private boolean _exists;
+    
+    /* -------------------------------------------------------- */
+    JarFileResource(URL url)
+    {
+        super(url);
+    }
+    
+    /* ------------------------------------------------------------ */
+    JarFileResource(URL url, boolean useCaches)
+    {
+        super(url, useCaches);
+    }
+   
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public synchronized void release()
+    {
+        _list=null;
+        _entry=null;
+        _file=null;
+        //if the jvm is not doing url caching, then the JarFiles will not be cached either,
+        //and so they are safe to close
+        if (!getUseCaches())
+        {
+            if ( _jarFile != null )
+            {
+                try
+                {
+                    LOG.debug("Closing JarFile "+_jarFile.getName());
+                    _jarFile.close();
+                }
+                catch ( IOException ioe )
+                {
+                    LOG.ignore(ioe);
+                }
+            }
+        }
+        _jarFile=null;
+        super.release();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    protected boolean checkConnection()
+    {
+        try
+        {
+            super.checkConnection();
+        }
+        finally
+        {
+            if (_jarConnection==null)
+            {
+                _entry=null;
+                _file=null;
+                _jarFile=null;
+                _list=null;
+            }
+        }
+        return _jarFile!=null;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected synchronized void newConnection()
+        throws IOException
+    {
+        super.newConnection();
+        
+        _entry=null;
+        _file=null;
+        _jarFile=null;
+        _list=null;
+        
+        int sep = _urlString.indexOf("!/");
+        _jarUrl=_urlString.substring(0,sep+2);
+        _path=_urlString.substring(sep+2);
+        if (_path.length()==0)
+            _path=null;   
+        _jarFile=_jarConnection.getJarFile();
+        _file=new File(_jarFile.getName());
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the represented resource exists.
+     */
+    @Override
+    public boolean exists()
+    {
+        if (_exists)
+            return true;
+
+        if (_urlString.endsWith("!/"))
+        {
+            
+            String file_url=_urlString.substring(4,_urlString.length()-2);
+            try{return newResource(file_url).exists();}
+            catch(Exception e) {LOG.ignore(e); return false;}
+        }
+        
+        boolean check=checkConnection();
+        
+        // Is this a root URL?
+        if (_jarUrl!=null && _path==null)
+        {
+            // Then if it exists it is a directory
+            _directory=check;
+            return true;
+        }
+        else 
+        {
+            // Can we find a file for it?
+            JarFile jarFile=null;
+            if (check)
+                // Yes
+                jarFile=_jarFile;
+            else
+            {
+                // No - so lets look if the root entry exists.
+                try
+                {
+                    JarURLConnection c=(JarURLConnection)((new URL(_jarUrl)).openConnection());
+                    c.setUseCaches(getUseCaches());
+                    jarFile=c.getJarFile();
+                }
+                catch(Exception e)
+                {
+                       LOG.ignore(e);
+                }
+            }
+
+            // Do we need to look more closely?
+            if (jarFile!=null && _entry==null && !_directory)
+            {
+                // OK - we have a JarFile, lets look at the entries for our path
+                Enumeration<JarEntry> e=jarFile.entries();
+                while(e.hasMoreElements())
+                {
+                    JarEntry entry = (JarEntry) e.nextElement();
+                    String name=entry.getName().replace('\\','/');
+                    
+                    // Do we have a match
+                    if (name.equals(_path))
+                    {
+                        _entry=entry;
+                        // Is the match a directory
+                        _directory=_path.endsWith("/");
+                        break;
+                    }
+                    else if (_path.endsWith("/"))
+                    {
+                        if (name.startsWith(_path))
+                        {
+                            _directory=true;
+                            break;
+                        }
+                    }
+                    else if (name.startsWith(_path) && name.length()>_path.length() && name.charAt(_path.length())=='/')
+                    {
+                        _directory=true;
+                        break;
+                    }
+                }
+
+                if (_directory && !_urlString.endsWith("/"))
+                {
+                    _urlString+="/";
+                    try
+                    {
+                        _url=new URL(_urlString);
+                    }
+                    catch(MalformedURLException ex)
+                    {
+                        LOG.warn(ex);
+                    }
+                }
+            }
+        }    
+        
+        _exists= ( _directory || _entry!=null);
+        return _exists;
+    }
+
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the represented resource is a container/directory.
+     * If the resource is not a file, resources ending with "/" are
+     * considered directories.
+     */
+    @Override
+    public boolean isDirectory()
+    {
+        return _urlString.endsWith("/") || exists() && _directory;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the last modified time
+     */
+    @Override
+    public long lastModified()
+    {
+        if (checkConnection() && _file!=null)
+        {
+            if (exists() && _entry!=null)
+                return _entry.getTime();
+            return _file.lastModified();
+        }
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public synchronized String[] list()
+    {
+        if (isDirectory() && _list==null)
+        {
+            List<String> list = null;
+            try
+            {
+                list = listEntries();
+            }
+            catch (Exception e)
+            {
+                //Sun's JarURLConnection impl for jar: protocol will close a JarFile in its connect() method if
+                //useCaches == false (eg someone called URLConnection with defaultUseCaches==true).
+                //As their sun.net.www.protocol.jar package caches JarFiles and/or connections, we can wind up in 
+                //the situation where the JarFile we have remembered in our _jarFile member has actually been closed
+                //by other code.
+                //So, do one retry to drop a connection and get a fresh JarFile
+                LOG.warn("Retrying list:"+e);
+                LOG.debug(e);
+                release();
+                list = listEntries();
+            }
+
+            if (list != null)
+            {
+                _list=new String[list.size()];
+                list.toArray(_list);
+            }  
+        }
+        return _list;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    private List<String> listEntries ()
+    {
+        checkConnection();
+        
+        ArrayList<String> list = new ArrayList<String>(32);
+        JarFile jarFile=_jarFile;
+        if(jarFile==null)
+        {
+            try
+            {
+                JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
+                jc.setUseCaches(getUseCaches());
+                jarFile=jc.getJarFile();
+            }
+            catch(Exception e)
+            {
+
+                e.printStackTrace();
+                 LOG.ignore(e);
+            }
+        }
+        
+        Enumeration<JarEntry> e=jarFile.entries();
+        String dir=_urlString.substring(_urlString.indexOf("!/")+2);
+        while(e.hasMoreElements())
+        {
+            JarEntry entry = e.nextElement();               
+            String name=entry.getName().replace('\\','/');               
+            if(!name.startsWith(dir) || name.length()==dir.length())
+            {
+                continue;
+            }
+            String listName=name.substring(dir.length());               
+            int dash=listName.indexOf('/');
+            if (dash>=0)
+            {
+                //when listing jar:file urls, you get back one
+                //entry for the dir itself, which we ignore
+                if (dash==0 && listName.length()==1)
+                    continue;
+                //when listing jar:file urls, all files and
+                //subdirs have a leading /, which we remove
+                if (dash==0)
+                    listName=listName.substring(dash+1, listName.length());
+                else
+                    listName=listName.substring(0,dash+1);
+                
+                if (list.contains(listName))
+                    continue;
+            }
+            
+            list.add(listName);
+        }
+        
+        return list;
+    }
+    
+    
+    
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Return the length of the resource
+     */
+    @Override
+    public long length()
+    {
+        if (isDirectory())
+            return -1;
+
+        if (_entry!=null)
+            return _entry.getSize();
+        
+        return -1;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Encode according to this resource type.
+     * File URIs are not encoded.
+     * @param uri URI to encode.
+     * @return The uri unchanged.
+     */
+    @Override
+    public String encode(String uri)
+    {
+        return uri;
+    }
+
+    
+    /**
+     * Take a Resource that possibly might use URLConnection caching
+     * and turn it into one that doesn't.
+     * @param resource
+     * @return the non-caching resource
+     */
+    public static Resource getNonCachingResource (Resource resource)
+    {
+        if (!(resource instanceof JarFileResource))
+            return resource;
+        
+        JarFileResource oldResource = (JarFileResource)resource;
+        
+        JarFileResource newResource = new JarFileResource(oldResource.getURL(), false);
+        return newResource;
+        
+    }
+    
+    /**
+     * Check if this jar:file: resource is contained in the
+     * named resource. Eg <code>jar:file:///a/b/c/foo.jar!/x.html</code> isContainedIn <code>file:///a/b/c/foo.jar</code>
+     * @param resource
+     * @return true if resource is contained in the named resource
+     * @throws MalformedURLException
+     */
+    @Override
+    public boolean isContainedIn (Resource resource) 
+    throws MalformedURLException
+    {
+        String string = _urlString;
+        int index = string.indexOf("!/");
+        if (index > 0)
+            string = string.substring(0,index);
+        if (string.startsWith("jar:"))
+            string = string.substring(4);
+        URL url = new URL(string);
+        return url.sameFile(resource.getURL());     
+    }
+}
+
+
+
+
+
+
+
+
diff --git a/src/java/org/eclipse/jetty/util/resource/JarResource.java b/src/java/org/eclipse/jetty/util/resource/JarResource.java
new file mode 100644
index 0000000..bc88e78
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/JarResource.java
@@ -0,0 +1,273 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+public class JarResource extends URLResource
+{
+    private static final Logger LOG = Log.getLogger(JarResource.class);
+    protected JarURLConnection _jarConnection;
+    
+    /* -------------------------------------------------------- */
+    JarResource(URL url)
+    {
+        super(url,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    JarResource(URL url, boolean useCaches)
+    {
+        super(url, null, useCaches);
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public synchronized void release()
+    {
+        _jarConnection=null;
+        super.release();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    protected synchronized boolean checkConnection()
+    {
+        super.checkConnection();
+        try
+        {
+            if (_jarConnection!=_connection)
+                newConnection();
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+            _jarConnection=null;
+        }
+        
+        return _jarConnection!=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @throws IOException Sub-classes of <code>JarResource</code> may throw an IOException (or subclass) 
+     */
+    protected void newConnection() throws IOException
+    {
+        _jarConnection=(JarURLConnection)_connection;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the respresenetd resource exists.
+     */
+    @Override
+    public boolean exists()
+    {
+        if (_urlString.endsWith("!/"))
+            return checkConnection();
+        else
+            return super.exists();
+    }    
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public File getFile()
+        throws IOException
+    {
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public InputStream getInputStream()
+        throws java.io.IOException
+    {     
+        checkConnection();
+        if (!_urlString.endsWith("!/"))
+            return new FilterInputStream(super.getInputStream()) 
+            {
+                @Override
+                public void close() throws IOException {this.in=IO.getClosedStream();}
+            };
+
+        URL url = new URL(_urlString.substring(4,_urlString.length()-2));      
+        InputStream is = url.openStream();
+        return is;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void copyTo(File directory)
+        throws IOException
+    {
+        if (!exists())
+            return;
+        
+        if(LOG.isDebugEnabled())
+            LOG.debug("Extract "+this+" to "+directory);
+        
+        String urlString = this.getURL().toExternalForm().trim();
+        int endOfJarUrl = urlString.indexOf("!/");
+        int startOfJarUrl = (endOfJarUrl >= 0?4:0);
+        
+        if (endOfJarUrl < 0)
+            throw new IOException("Not a valid jar url: "+urlString);
+        
+        URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl));
+        String subEntryName = (endOfJarUrl+2 < urlString.length() ? urlString.substring(endOfJarUrl + 2) : null);
+        boolean subEntryIsDir = (subEntryName != null && subEntryName.endsWith("/")?true:false);
+      
+        if (LOG.isDebugEnabled()) 
+            LOG.debug("Extracting entry = "+subEntryName+" from jar "+jarFileURL);
+        
+        InputStream is = jarFileURL.openConnection().getInputStream();
+        JarInputStream jin = new JarInputStream(is);
+        JarEntry entry;
+        boolean shouldExtract;
+        while((entry=jin.getNextJarEntry())!=null)
+        {
+            String entryName = entry.getName();
+            if ((subEntryName != null) && (entryName.startsWith(subEntryName)))
+            { 
+                // is the subentry really a dir?
+                if (!subEntryIsDir && subEntryName.length()+1==entryName.length() && entryName.endsWith("/"))
+                        subEntryIsDir=true;
+                
+                //if there is a particular subEntry that we are looking for, only
+                //extract it.
+                if (subEntryIsDir)
+                {
+                    //if it is a subdirectory we are looking for, then we
+                    //are looking to extract its contents into the target
+                    //directory. Remove the name of the subdirectory so
+                    //that we don't wind up creating it too.
+                    entryName = entryName.substring(subEntryName.length());
+                    if (!entryName.equals(""))
+                    {
+                        //the entry is 
+                        shouldExtract = true;                   
+                    }
+                    else
+                        shouldExtract = false;
+                }
+                else
+                    shouldExtract = true;
+            }
+            else if ((subEntryName != null) && (!entryName.startsWith(subEntryName)))
+            {
+                //there is a particular entry we are looking for, and this one
+                //isn't it
+                shouldExtract = false;
+            }
+            else
+            {
+                //we are extracting everything
+                shouldExtract =  true;
+            }
+                
+            
+            if (!shouldExtract)
+            {
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("Skipping entry: "+entryName);
+                continue;
+            }
+                
+            String dotCheck = entryName.replace('\\', '/');   
+            dotCheck = URIUtil.canonicalPath(dotCheck);
+            if (dotCheck == null)
+            {
+                if (LOG.isDebugEnabled()) 
+                    LOG.debug("Invalid entry: "+entryName);
+                continue;
+            }
+
+            File file=new File(directory,entryName);
+     
+            if (entry.isDirectory())
+            {
+                // Make directory
+                if (!file.exists())
+                    file.mkdirs();
+            }
+            else
+            {
+                // make directory (some jars don't list dirs)
+                File dir = new File(file.getParent());
+                if (!dir.exists())
+                    dir.mkdirs();
+
+                // Make file
+                FileOutputStream fout = null;
+                try
+                {
+                    fout = new FileOutputStream(file);
+                    IO.copy(jin,fout);
+                }
+                finally
+                {
+                    IO.close(fout);
+                }
+
+                // touch the file.
+                if (entry.getTime()>=0)
+                    file.setLastModified(entry.getTime());
+            }
+        }
+        
+        if ((subEntryName == null) || (subEntryName != null && subEntryName.equalsIgnoreCase("META-INF/MANIFEST.MF")))
+        {
+            Manifest manifest = jin.getManifest();
+            if (manifest != null)
+            {
+                File metaInf = new File (directory, "META-INF");
+                metaInf.mkdir();
+                File f = new File(metaInf, "MANIFEST.MF");
+                FileOutputStream fout = new FileOutputStream(f);
+                manifest.write(fout);
+                fout.close();   
+            }
+        }
+        IO.close(jin);
+    }   
+    
+    public static Resource newJarResource(Resource resource) throws IOException
+    {
+        if (resource instanceof JarResource)
+            return resource;
+        return Resource.newResource("jar:" + resource + "!/");
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/Resource.java b/src/java/org/eclipse/jetty/util/resource/Resource.java
new file mode 100644
index 0000000..e2275bf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/Resource.java
@@ -0,0 +1,678 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** 
+ * Abstract resource class.
+ */
+public abstract class Resource implements ResourceFactory
+{
+    private static final Logger LOG = Log.getLogger(Resource.class);
+    public static boolean __defaultUseCaches = true;
+    volatile Object _associate;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Change the default setting for url connection caches.
+     * Subsequent URLConnections will use this default.
+     * @param useCaches
+     */
+    public static void setDefaultUseCaches (boolean useCaches)
+    {
+        __defaultUseCaches=useCaches;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static boolean getDefaultUseCaches ()
+    {
+        return __defaultUseCaches;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Construct a resource from a uri.
+     * @param uri A URI.
+     * @return A Resource object.
+     * @throws IOException Problem accessing URI
+     */
+    public static Resource newResource(URI uri)
+        throws IOException
+    {
+        return newResource(uri.toURL());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Construct a resource from a url.
+     * @param url A URL.
+     * @return A Resource object.
+     * @throws IOException Problem accessing URL
+     */
+    public static Resource newResource(URL url)
+        throws IOException
+    {
+        return newResource(url, __defaultUseCaches);
+    }
+    
+    /* ------------------------------------------------------------ */   
+    /**
+     * Construct a resource from a url.
+     * @param url the url for which to make the resource
+     * @param useCaches true enables URLConnection caching if applicable to the type of resource
+     * @return
+     */
+    static Resource newResource(URL url, boolean useCaches)
+    {
+        if (url==null)
+            return null;
+
+        String url_string=url.toExternalForm();
+        if( url_string.startsWith( "file:"))
+        {
+            try
+            {
+                FileResource fileResource= new FileResource(url);
+                return fileResource;
+            }
+            catch(Exception e)
+            {
+                LOG.debug(Log.EXCEPTION,e);
+                return new BadResource(url,e.toString());
+            }
+        }
+        else if( url_string.startsWith( "jar:file:"))
+        {
+            return new JarFileResource(url, useCaches);
+        }
+        else if( url_string.startsWith( "jar:"))
+        {
+            return new JarResource(url, useCaches);
+        }
+
+        return new URLResource(url,null,useCaches);
+    }
+
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Construct a resource from a string.
+     * @param resource A URL or filename.
+     * @return A Resource object.
+     */
+    public static Resource newResource(String resource)
+        throws MalformedURLException, IOException
+    {
+        return newResource(resource, __defaultUseCaches);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Construct a resource from a string.
+     * @param resource A URL or filename.
+     * @param useCaches controls URLConnection caching
+     * @return A Resource object.
+     */
+    public static Resource newResource (String resource, boolean useCaches)       
+    throws MalformedURLException, IOException
+    {
+        URL url=null;
+        try
+        {
+            // Try to format as a URL?
+            url = new URL(resource);
+        }
+        catch(MalformedURLException e)
+        {
+            if(!resource.startsWith("ftp:") &&
+               !resource.startsWith("file:") &&
+               !resource.startsWith("jar:"))
+            {
+                try
+                {
+                    // It's a file.
+                    if (resource.startsWith("./"))
+                        resource=resource.substring(2);
+                    
+                    File file=new File(resource).getCanonicalFile();
+                    url=Resource.toURL(file);            
+                    
+                    URLConnection connection=url.openConnection();
+                    connection.setUseCaches(useCaches);
+                    return new FileResource(url,connection,file);
+                }
+                catch(Exception e2)
+                {
+                    LOG.debug(Log.EXCEPTION,e2);
+                    throw e;
+                }
+            }
+            else
+            {
+                LOG.warn("Bad Resource: "+resource);
+                throw e;
+            }
+        }
+
+        return newResource(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    public static Resource newResource (File file)
+    throws MalformedURLException, IOException
+    {
+        file = file.getCanonicalFile();
+        URL url = Resource.toURL(file);
+
+        URLConnection connection = url.openConnection();
+        FileResource fileResource = new FileResource(url, connection, file);
+        return fileResource;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Construct a system resource from a string.
+     * The resource is tried as classloader resource before being
+     * treated as a normal resource.
+     * @param resource Resource as string representation 
+     * @return The new Resource
+     * @throws IOException Problem accessing resource.
+     */
+    public static Resource newSystemResource(String resource)
+        throws IOException
+    {
+        URL url=null;
+        // Try to format as a URL?
+        ClassLoader loader=Thread.currentThread().getContextClassLoader();
+        if (loader!=null)
+        {
+            try
+            {
+                url = loader.getResource(resource);
+                if (url == null && resource.startsWith("/"))
+                    url = loader.getResource(resource.substring(1));
+            }
+            catch (IllegalArgumentException e)
+            {
+                // Catches scenario where a bad Windows path like "C:\dev" is
+                // improperly escaped, which various downstream classloaders
+                // tend to have a problem with
+                url = null;
+            }
+        }
+        if (url==null)
+        {
+            loader=Resource.class.getClassLoader();
+            if (loader!=null)
+            {
+                url=loader.getResource(resource);
+                if (url==null && resource.startsWith("/"))
+                    url=loader.getResource(resource.substring(1));
+            }
+        }
+        
+        if (url==null)
+        {
+            url=ClassLoader.getSystemResource(resource);
+            if (url==null && resource.startsWith("/"))
+                url=ClassLoader.getSystemResource(resource.substring(1));
+        }
+        
+        if (url==null)
+            return null;
+        
+        return newResource(url);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Find a classpath resource.
+     */
+    public static Resource newClassPathResource(String resource)
+    {
+        return newClassPathResource(resource,true,false);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Find a classpath resource.
+     * The {@link java.lang.Class#getResource(String)} method is used to lookup the resource. If it is not
+     * found, then the {@link Loader#getResource(Class, String, boolean)} method is used.
+     * If it is still not found, then {@link ClassLoader#getSystemResource(String)} is used.
+     * Unlike {@link ClassLoader#getSystemResource(String)} this method does not check for normal resources.
+     * @param name The relative name of the resource
+     * @param useCaches True if URL caches are to be used.
+     * @param checkParents True if forced searching of parent Classloaders is performed to work around 
+     * loaders with inverted priorities
+     * @return Resource or null
+     */
+    public static Resource newClassPathResource(String name,boolean useCaches,boolean checkParents)
+    {
+        URL url=Resource.class.getResource(name);
+        
+        if (url==null)
+            url=Loader.getResource(Resource.class,name,checkParents);
+        if (url==null)
+            return null;
+        return newResource(url,useCaches);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static boolean isContainedIn (Resource r, Resource containingResource) throws MalformedURLException
+    {
+        return r.isContainedIn(containingResource);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void finalize()
+    {
+        release();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public abstract boolean isContainedIn (Resource r) throws MalformedURLException;
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Release any temporary resources held by the resource.
+     */
+    public abstract void release();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the respresened resource exists.
+     */
+    public abstract boolean exists();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the respresenetd resource is a container/directory.
+     * If the resource is not a file, resources ending with "/" are
+     * considered directories.
+     */
+    public abstract boolean isDirectory();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the last modified time
+     */
+    public abstract long lastModified();
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Return the length of the resource
+     */
+    public abstract long length();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an URL representing the given resource
+     */
+    public abstract URL getURL();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an URI representing the given resource
+     */
+    public URI getURI()
+    {
+        try
+        {
+            return getURL().toURI();
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an File representing the given resource or NULL if this
+     * is not possible.
+     */
+    public abstract File getFile()
+        throws IOException;
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the name of the resource
+     */
+    public abstract String getName();
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an input stream to the resource
+     */
+    public abstract InputStream getInputStream()
+        throws java.io.IOException;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an output stream to the resource
+     */
+    public abstract OutputStream getOutputStream()
+        throws java.io.IOException, SecurityException;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Deletes the given resource
+     */
+    public abstract boolean delete()
+        throws SecurityException;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Rename the given resource
+     */
+    public abstract boolean renameTo( Resource dest)
+        throws SecurityException;
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns a list of resource names contained in the given resource
+     * The resource names are not URL encoded.
+     */
+    public abstract String[] list();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the resource contained inside the current resource with the
+     * given name.
+     * @param path The path segment to add, which should be encoded by the
+     * encode method. 
+     */
+    public abstract Resource addPath(String path)
+        throws IOException,MalformedURLException;
+
+    /* ------------------------------------------------------------ */
+    /** Get a resource from withing this resource.
+     * <p>
+     * This method is essentially an alias for {@link #addPath(String)}, but without checked exceptions.
+     * This method satisfied the {@link ResourceFactory} interface.
+     * @see org.eclipse.jetty.util.resource.ResourceFactory#getResource(java.lang.String)
+     */
+    public Resource getResource(String path)
+    {
+        try
+        {
+            return addPath(path);
+        }
+        catch(Exception e)
+        {
+            LOG.debug(e);
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Encode according to this resource type.
+     * The default implementation calls URI.encodePath(uri)
+     * @param uri 
+     * @return String encoded for this resource type.
+     */
+    public String encode(String uri)
+    {
+        return URIUtil.encodePath(uri);
+    }
+        
+    /* ------------------------------------------------------------ */
+    public Object getAssociate()
+    {
+        return _associate;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setAssociate(Object o)
+    {
+        _associate=o;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The canonical Alias of this resource or null if none.
+     */
+    public URL getAlias()
+    {
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the resource list as a HTML directory listing.
+     * @param base The base URL
+     * @param parent True if the parent directory should be included
+     * @return String of HTML
+     */
+    public String getListHTML(String base,boolean parent)
+        throws IOException
+    {
+        base=URIUtil.canonicalPath(base);
+        if (base==null || !isDirectory())
+            return null;
+        
+        String[] ls = list();
+        if (ls==null)
+            return null;
+        Arrays.sort(ls);
+        
+        String decodedBase = URIUtil.decodePath(base);
+        String title = "Directory: "+deTag(decodedBase);
+
+        StringBuilder buf=new StringBuilder(4096);
+        buf.append("<HTML><HEAD>");
+        buf.append("<LINK HREF=\"").append("jetty-dir.css").append("\" REL=\"stylesheet\" TYPE=\"text/css\"/><TITLE>");
+        buf.append(title);
+        buf.append("</TITLE></HEAD><BODY>\n<H1>");
+        buf.append(title);
+        buf.append("</H1>\n<TABLE BORDER=0>\n");
+        
+        if (parent)
+        {
+            buf.append("<TR><TD><A HREF=\"");
+            buf.append(URIUtil.addPaths(base,"../"));
+            buf.append("\">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
+        }
+        
+        String encodedBase = hrefEncodeURI(base);
+        
+        DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
+                                                       DateFormat.MEDIUM);
+        for (int i=0 ; i< ls.length ; i++)
+        {
+            Resource item = addPath(ls[i]);
+            
+            buf.append("\n<TR><TD><A HREF=\"");
+            String path=URIUtil.addPaths(encodedBase,URIUtil.encodePath(ls[i]));
+            
+            buf.append(path);
+            
+            if (item.isDirectory() && !path.endsWith("/"))
+                buf.append(URIUtil.SLASH);
+            
+            // URIUtil.encodePath(buf,path);
+            buf.append("\">");
+            buf.append(deTag(ls[i]));
+            buf.append("&nbsp;");
+            buf.append("</A></TD><TD ALIGN=right>");
+            buf.append(item.length());
+            buf.append(" bytes&nbsp;</TD><TD>");
+            buf.append(dfmt.format(new Date(item.lastModified())));
+            buf.append("</TD></TR>");
+        }
+        buf.append("</TABLE>\n");
+	buf.append("</BODY></HTML>\n");
+        
+        return buf.toString();
+    }
+    
+    /**
+     * Encode any characters that could break the URI string in an HREF.
+     * Such as <a href="/path/to;<script>Window.alert("XSS"+'%20'+"here");</script>">Link</a>
+     * 
+     * The above example would parse incorrectly on various browsers as the "<" or '"' characters
+     * would end the href attribute value string prematurely.
+     * 
+     * @param raw the raw text to encode.
+     * @return the defanged text.
+     */
+    private static String hrefEncodeURI(String raw) 
+    {
+        StringBuffer buf = null;
+
+        loop:
+        for (int i=0;i<raw.length();i++)
+        {
+            char c=raw.charAt(i);
+            switch(c)
+            {
+                case '\'':
+                case '"':
+                case '<':
+                case '>':
+                    buf=new StringBuffer(raw.length()<<1);
+                    break loop;
+            }
+        }
+        if (buf==null)
+            return raw;
+
+        for (int i=0;i<raw.length();i++)
+        {
+            char c=raw.charAt(i);       
+            switch(c)
+            {
+              case '"':
+                  buf.append("%22");
+                  continue;
+              case '\'':
+                  buf.append("%27");
+                  continue;
+              case '<':
+                  buf.append("%3C");
+                  continue;
+              case '>':
+                  buf.append("%3E");
+                  continue;
+              default:
+                  buf.append(c);
+                  continue;
+            }
+        }
+
+        return buf.toString();
+    }
+    
+    private static String deTag(String raw) 
+    {
+        return StringUtil.replace( StringUtil.replace(raw,"<","&lt;"), ">", "&gt;");
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @param out 
+     * @param start First byte to write
+     * @param count Bytes to write or -1 for all of them.
+     */
+    public void writeTo(OutputStream out,long start,long count)
+        throws IOException
+    {
+        InputStream in = getInputStream();
+        try
+        {
+            in.skip(start);
+            if (count<0)
+                IO.copy(in,out);
+            else
+                IO.copy(in,out,count);
+        }
+        finally
+        {
+            in.close();
+        }
+    }    
+    
+    /* ------------------------------------------------------------ */
+    public void copyTo(File destination)
+        throws IOException
+    {
+        if (destination.exists())
+            throw new IllegalArgumentException(destination+" exists");
+        writeTo(new FileOutputStream(destination),0,-1);
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getWeakETag()
+    {
+        try
+        {
+            StringBuilder b = new StringBuilder(32);
+            b.append("W/\"");
+            
+            String name=getName();
+            int length=name.length();
+            long lhash=0;
+            for (int i=0; i<length;i++)
+                lhash=31*lhash+name.charAt(i);
+            
+            B64Code.encode(lastModified()^lhash,b);
+            B64Code.encode(length()^lhash,b);
+            b.append('"');
+            return b.toString();
+        } 
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Generate a properly encoded URL from a {@link File} instance.
+     * @param file Target file. 
+     * @return URL of the target file.
+     * @throws MalformedURLException 
+     */
+    public static URL toURL(File file) throws MalformedURLException
+    {
+        return file.toURI().toURL();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/ResourceCollection.java b/src/java/org/eclipse/jetty/util/resource/ResourceCollection.java
new file mode 100644
index 0000000..da36018
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/ResourceCollection.java
@@ -0,0 +1,482 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.util.URIUtil;
+
+/**
+ * A collection of resources (dirs).
+ * Allows webapps to have multiple (static) sources.
+ * The first resource in the collection is the main resource.
+ * If a resource is not found in the main resource, it looks it up in 
+ * the order the resources were constructed.
+ * 
+ * 
+ *
+ */
+public class ResourceCollection extends Resource
+{
+    private Resource[] _resources;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Instantiates an empty resource collection.
+     * 
+     * This constructor is used when configuring jetty-maven-plugin.
+     */
+    public ResourceCollection()
+    {
+        _resources = new Resource[0];
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Instantiates a new resource collection.
+     *
+     * @param resources the resources to be added to collection
+     */
+    public ResourceCollection(Resource... resources)
+    {
+        List<Resource> list = new ArrayList<Resource>();
+        for (Resource r : resources)
+        {
+            if (r==null)
+                continue;
+            if (r instanceof ResourceCollection)
+            {
+                for (Resource r2 : ((ResourceCollection)r).getResources())
+                    list.add(r2);
+            }
+            else
+                list.add(r);
+        }
+        _resources = list.toArray(new Resource[list.size()]);
+        for(Resource r : _resources)
+        {
+            if(!r.exists() || !r.isDirectory())
+                throw new IllegalArgumentException(r + " is not an existing directory.");
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Instantiates a new resource collection.
+     *
+     * @param resources the resource strings to be added to collection
+     */
+    public ResourceCollection(String[] resources)
+    {
+        _resources = new Resource[resources.length];
+        try
+        {
+            for(int i=0; i<resources.length; i++)
+            {
+                _resources[i] = Resource.newResource(resources[i]);
+                if(!_resources[i].exists() || !_resources[i].isDirectory())
+                    throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
+            }
+        }
+        catch(IllegalArgumentException e)
+        {
+            throw e;
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Instantiates a new resource collection.
+     *
+     * @param csvResources the string containing comma-separated resource strings
+     */
+    public ResourceCollection(String csvResources)
+    {
+        setResourcesAsCSV(csvResources);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Retrieves the resource collection's resources.
+     * 
+     * @return the resource array
+     */
+    public Resource[] getResources()
+    {
+        return _resources;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Sets the resource collection's resources.
+     *
+     * @param resources the new resource array
+     */
+    public void setResources(Resource[] resources)
+    {
+        _resources = resources != null ? resources : new Resource[0];
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Sets the resources as string of comma-separated values.
+     * This method should be used when configuring jetty-maven-plugin.
+     *
+     * @param csvResources the comma-separated string containing
+     *                     one or more resource strings.
+     */
+    public void setResourcesAsCSV(String csvResources)
+    {
+        StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;");
+        int len = tokenizer.countTokens();
+        if(len==0)
+        {
+            throw new IllegalArgumentException("ResourceCollection@setResourcesAsCSV(String) " +
+                    " argument must be a string containing one or more comma-separated resource strings.");
+        }
+        
+        _resources = new Resource[len];
+        try
+        {            
+            for(int i=0; tokenizer.hasMoreTokens(); i++)
+            {
+                _resources[i] = Resource.newResource(tokenizer.nextToken().trim());
+                if(!_resources[i].exists() || !_resources[i].isDirectory())
+                    throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
+            }
+        }
+        catch(Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param path The path segment to add
+     * @return The contained resource (found first) in the collection of resources
+     */
+    @Override
+    public Resource addPath(String path) throws IOException, MalformedURLException
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        if(path==null)
+            throw new MalformedURLException();
+        
+        if(path.length()==0 || URIUtil.SLASH.equals(path))
+            return this;
+        
+        Resource resource=null;
+        ArrayList<Resource> resources = null;
+        int i=0;
+        for(; i<_resources.length; i++)
+        {
+            resource = _resources[i].addPath(path);  
+            if (resource.exists())
+            {
+                if (resource.isDirectory())
+                    break;       
+                return resource;
+            }
+        }  
+
+        for(i++; i<_resources.length; i++)
+        {
+            Resource r = _resources[i].addPath(path); 
+            if (r.exists() && r.isDirectory())
+            {
+                if (resource!=null)
+                {
+                    resources = new ArrayList<Resource>();
+                    resources.add(resource);
+                    resource=null;
+                }
+                resources.add(r);
+            }
+        }
+
+        if (resource!=null)
+            return resource;
+        if (resources!=null)
+            return new ResourceCollection(resources.toArray(new Resource[resources.size()]));
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param path
+     * @return the resource(file) if found, returns a list of resource dirs if its a dir, else null.
+     * @throws IOException
+     * @throws MalformedURLException
+     */
+    protected Object findResource(String path) throws IOException, MalformedURLException
+    {        
+        Resource resource=null;
+        ArrayList<Resource> resources = null;
+        int i=0;
+        for(; i<_resources.length; i++)
+        {
+            resource = _resources[i].addPath(path);  
+            if (resource.exists())
+            {
+                if (resource.isDirectory())
+                    break;
+               
+                return resource;
+            }
+        }  
+
+        for(i++; i<_resources.length; i++)
+        {
+            Resource r = _resources[i].addPath(path); 
+            if (r.exists() && r.isDirectory())
+            {
+                if (resource!=null)
+                {
+                    resources = new ArrayList<Resource>();
+                    resources.add(resource);
+                }
+                resources.add(r);
+            }
+        }
+        
+        if (resource!=null)
+            return resource;
+        if (resources!=null)
+            return resources;
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean delete() throws SecurityException
+    {
+        throw new UnsupportedOperationException();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean exists()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public File getFile() throws IOException
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            File f = r.getFile();
+            if(f!=null)
+                return f;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public InputStream getInputStream() throws IOException
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            InputStream is = r.getInputStream();
+            if(is!=null)
+                return is;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public String getName()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            String name = r.getName();
+            if(name!=null)
+                return name;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public OutputStream getOutputStream() throws IOException, SecurityException
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            OutputStream os = r.getOutputStream();
+            if(os!=null)
+                return os;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public URL getURL()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            URL url = r.getURL();
+            if(url!=null)
+                return url;
+        }
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isDirectory()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public long lastModified()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+        {
+            long lm = r.lastModified();
+            if (lm!=-1)
+                return lm;
+        }
+        return -1;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public long length()
+    {
+        return -1;
+    }    
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The list of resource names(merged) contained in the collection of resources.
+     */    
+    @Override
+    public String[] list()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        HashSet<String> set = new HashSet<String>();
+        for(Resource r : _resources)
+        {
+            for(String s : r.list())
+                set.add(s);
+        }
+        String[] result=set.toArray(new String[set.size()]);
+        Arrays.sort(result);
+        return result;
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public void release()
+    {
+        if(_resources==null)
+            throw new IllegalStateException("*resources* not set.");
+        
+        for(Resource r : _resources)
+            r.release();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean renameTo(Resource dest) throws SecurityException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void copyTo(File destination)
+        throws IOException
+    {
+        for (int r=_resources.length;r-->0;)
+            _resources[r].copyTo(destination);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the list of resources separated by a path separator
+     */
+    @Override
+    public String toString()
+    {
+        if(_resources==null)
+            return "[]";
+        
+        return String.valueOf(Arrays.asList(_resources));
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isContainedIn(Resource r) throws MalformedURLException
+    {
+        // TODO could look at implementing the semantic of is this collection a subset of the Resource r?
+        return false;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/ResourceFactory.java b/src/java/org/eclipse/jetty/util/resource/ResourceFactory.java
new file mode 100644
index 0000000..707a672
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/ResourceFactory.java
@@ -0,0 +1,34 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+
+/* ------------------------------------------------------------ */
+/** ResourceFactory.
+ */
+public interface ResourceFactory
+{
+    
+    /* ------------------------------------------------------------ */
+    /** Get a resource for a path.
+     * @param path The path to the resource
+     * @return The resource or null 
+     */
+    Resource getResource(String path);
+}
diff --git a/src/java/org/eclipse/jetty/util/resource/URLResource.java b/src/java/org/eclipse/jetty/util/resource/URLResource.java
new file mode 100644
index 0000000..1e19385
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/resource/URLResource.java
@@ -0,0 +1,321 @@
+//
+//  ========================================================================
+//  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.util.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/** Abstract resource class.
+ */
+public class URLResource extends Resource
+{
+    private static final Logger LOG = Log.getLogger(URLResource.class);
+    protected URL _url;
+    protected String _urlString;
+    
+    protected URLConnection _connection;
+    protected InputStream _in=null;
+    transient boolean _useCaches = Resource.__defaultUseCaches;
+    
+    /* ------------------------------------------------------------ */
+    protected URLResource(URL url, URLConnection connection)
+    {
+        _url = url;
+        _urlString=_url.toString();
+        _connection=connection;
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected URLResource (URL url, URLConnection connection, boolean useCaches)
+    {
+        this (url, connection);
+        _useCaches = useCaches;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected synchronized boolean checkConnection()
+    {
+        if (_connection==null)
+        {
+            try{
+                _connection=_url.openConnection();
+                _connection.setUseCaches(_useCaches);
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+        return _connection!=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Release any resources held by the resource.
+     */
+    @Override
+    public synchronized void release()
+    {
+        if (_in!=null)
+        {
+            try{_in.close();}catch(IOException e){LOG.ignore(e);}
+            _in=null;
+        }
+
+        if (_connection!=null)
+            _connection=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the represented resource exists.
+     */
+    @Override
+    public boolean exists()
+    {
+        try
+        {
+            synchronized(this)
+            {
+                if (checkConnection() && _in==null )
+                    _in = _connection.getInputStream();
+            }
+        }
+        catch (IOException e)
+        {
+            LOG.ignore(e);
+        }
+        return _in!=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns true if the respresenetd resource is a container/directory.
+     * If the resource is not a file, resources ending with "/" are
+     * considered directories.
+     */
+    @Override
+    public boolean isDirectory()
+    {
+        return exists() && _url.toString().endsWith("/");
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the last modified time
+     */
+    @Override
+    public long lastModified()
+    {
+        if (checkConnection())
+            return _connection.getLastModified();
+        return -1;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Return the length of the resource
+     */
+    @Override
+    public long length()
+    {
+        if (checkConnection())
+            return _connection.getContentLength();
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an URL representing the given resource
+     */
+    @Override
+    public URL getURL()
+    {
+        return _url;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an File representing the given resource or NULL if this
+     * is not possible.
+     */
+    @Override
+    public File getFile()
+        throws IOException
+    {
+        // Try the permission hack
+        if (checkConnection())
+        {
+            Permission perm = _connection.getPermission();
+            if (perm instanceof java.io.FilePermission)
+                return new File(perm.getName());
+        }
+
+        // Try the URL file arg
+        try {return new File(_url.getFile());}
+        catch(Exception e) {LOG.ignore(e);}
+
+        // Don't know the file
+        return null;    
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the name of the resource
+     */
+    @Override
+    public String getName()
+    {
+        return _url.toExternalForm();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an input stream to the resource
+     */
+    @Override
+    public synchronized InputStream getInputStream()
+        throws java.io.IOException
+    {
+        if (!checkConnection())
+            throw new IOException( "Invalid resource");
+
+        try
+        {    
+            if( _in != null)
+            {
+                InputStream in = _in;
+                _in=null;
+                return in;
+            }
+            return _connection.getInputStream();
+        }
+        finally
+        {
+            _connection=null;
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns an output stream to the resource
+     */
+    @Override
+    public OutputStream getOutputStream()
+        throws java.io.IOException, SecurityException
+    {
+        throw new IOException( "Output not supported");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Deletes the given resource
+     */
+    @Override
+    public boolean delete()
+        throws SecurityException
+    {
+        throw new SecurityException( "Delete not supported");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Rename the given resource
+     */
+    @Override
+    public boolean renameTo( Resource dest)
+        throws SecurityException
+    {
+        throw new SecurityException( "RenameTo not supported");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns a list of resource names contained in the given resource
+     */
+    @Override
+    public String[] list()
+    {
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the resource contained inside the current resource with the
+     * given name
+     */
+    @Override
+    public Resource addPath(String path)
+        throws IOException,MalformedURLException
+    {
+        if (path==null)
+            return null;
+
+        path = URIUtil.canonicalPath(path);
+
+        return newResource(URIUtil.addPaths(_url.toExternalForm(),path));
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return _urlString;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int hashCode()
+    {
+        return _urlString.hashCode();
+    }
+    
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean equals( Object o)
+    {
+        return o instanceof URLResource && _urlString.equals(((URLResource)o)._urlString);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean getUseCaches ()
+    {
+        return _useCaches;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean isContainedIn (Resource containingResource) throws MalformedURLException
+    {
+        return false; //TODO check this!
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/security/B64Code.java b/src/java/org/eclipse/jetty/util/security/B64Code.java
new file mode 100644
index 0000000..ef67bbf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/B64Code.java
@@ -0,0 +1,33 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * @deprecated use {@link org.eclipse.jetty.util.B64Code}
+ */
+@Deprecated 
+public class B64Code extends org.eclipse.jetty.util.B64Code
+{
+    public B64Code()
+    {
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/security/CertificateUtils.java b/src/java/org/eclipse/jetty/util/security/CertificateUtils.java
new file mode 100644
index 0000000..4ed9ae2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/CertificateUtils.java
@@ -0,0 +1,94 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.CRL;
+import java.security.cert.CertificateFactory;
+import java.util.Collection;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+public class CertificateUtils
+{
+    /* ------------------------------------------------------------ */
+    public static KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
+    {
+        KeyStore keystore = null;
+
+        if (storeStream != null || storePath != null)
+        {
+            InputStream inStream = storeStream;
+            try
+            {
+                if (inStream == null)
+                {
+                    inStream = Resource.newResource(storePath).getInputStream();
+                }
+                
+                if (storeProvider != null)
+                {
+                    keystore = KeyStore.getInstance(storeType, storeProvider);
+                }
+                else
+                {
+                    keystore = KeyStore.getInstance(storeType);
+                }
+    
+                keystore.load(inStream, storePassword == null ? null : storePassword.toCharArray());
+            }
+            finally
+            {
+                if (inStream != null)
+                {
+                    inStream.close();
+                }
+            }
+        }
+        
+        return keystore;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static Collection<? extends CRL> loadCRL(String crlPath) throws Exception
+    {
+        Collection<? extends CRL> crlList = null;
+
+        if (crlPath != null)
+        {
+            InputStream in = null;
+            try
+            {
+                in = Resource.newResource(crlPath).getInputStream();
+                crlList = CertificateFactory.getInstance("X.509").generateCRLs(in);
+            }
+            finally
+            {
+                if (in != null)
+                {
+                    in.close();
+                }
+            }
+        }
+
+        return crlList;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/util/security/CertificateValidator.java b/src/java/org/eclipse/jetty/util/security/CertificateValidator.java
new file mode 100644
index 0000000..2ead387
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/CertificateValidator.java
@@ -0,0 +1,343 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+import java.security.GeneralSecurityException;
+import java.security.InvalidParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CertPathBuilder;
+import java.security.cert.CertPathBuilderResult;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Convenience class to handle validation of certificates, aliases and keystores
+ *
+ * Allows specifying Certificate Revocation List (CRL), as well as enabling
+ * CRL Distribution Points Protocol (CRLDP) certificate extension support,
+ * and also enabling On-Line Certificate Status Protocol (OCSP) support.
+ * 
+ * IMPORTANT: at least one of the above mechanisms *MUST* be configured and
+ * operational, otherwise certificate validation *WILL FAIL* unconditionally.
+ */
+public class CertificateValidator
+{
+    private static final Logger LOG = Log.getLogger(CertificateValidator.class);
+    private static AtomicLong __aliasCount = new AtomicLong();
+    
+    private KeyStore _trustStore;
+    private Collection<? extends CRL> _crls;
+
+    /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
+    private int _maxCertPathLength = -1;
+    /** CRL Distribution Points (CRLDP) support */
+    private boolean _enableCRLDP = false;
+    /** On-Line Certificate Status Protocol (OCSP) support */
+    private boolean _enableOCSP = false;
+    /** Location of OCSP Responder */
+    private String _ocspResponderURL;
+    
+    /**
+     * creates an instance of the certificate validator 
+     *
+     * @param trustStore 
+     * @param crls
+     */
+    public CertificateValidator(KeyStore trustStore, Collection<? extends CRL> crls)
+    {
+        if (trustStore == null)
+        {
+            throw new InvalidParameterException("TrustStore must be specified for CertificateValidator.");
+        }
+        
+        _trustStore = trustStore;
+        _crls = crls;
+    }
+    
+    /**
+     * validates all aliases inside of a given keystore
+     * 
+     * @param keyStore
+     * @throws CertificateException
+     */
+    public void validate( KeyStore keyStore ) throws CertificateException
+    {
+        try
+        {
+            Enumeration<String> aliases = keyStore.aliases();
+            
+            for ( ; aliases.hasMoreElements(); )
+            {
+                String alias = aliases.nextElement();
+                
+                validate(keyStore,alias);
+            }
+            
+        }
+        catch ( KeyStoreException kse )
+        {
+            throw new CertificateException("Unable to retrieve aliases from keystore", kse);
+        }
+    }
+    
+
+    /**
+     * validates a specific alias inside of the keystore being passed in
+     * 
+     * @param keyStore
+     * @param keyAlias
+     * @return the keyAlias if valid
+     * @throws CertificateException
+     */
+    public String validate(KeyStore keyStore, String keyAlias) throws CertificateException
+    {
+        String result = null;
+
+        if (keyAlias != null)
+        {
+            try
+            {
+                validate(keyStore, keyStore.getCertificate(keyAlias));
+            }
+            catch (KeyStoreException kse)
+            {
+                LOG.debug(kse);
+                throw new CertificateException("Unable to validate certificate" +
+                        " for alias [" + keyAlias + "]: " + kse.getMessage(), kse);
+            }
+            result = keyAlias;            
+        }
+        
+        return result;
+    }
+    
+    /**
+     * validates a specific certificate inside of the keystore being passed in
+     * 
+     * @param keyStore
+     * @param cert
+     * @throws CertificateException
+     */
+    public void validate(KeyStore keyStore, Certificate cert) throws CertificateException
+    {
+        Certificate[] certChain = null;
+        
+        if (cert != null && cert instanceof X509Certificate)
+        {
+            ((X509Certificate)cert).checkValidity();
+            
+            String certAlias = null;
+            try
+            {
+                if (keyStore == null)
+                {
+                    throw new InvalidParameterException("Keystore cannot be null");
+                }
+
+                certAlias = keyStore.getCertificateAlias((X509Certificate)cert);
+                if (certAlias == null)
+                {
+                    certAlias = "JETTY" + String.format("%016X",__aliasCount.incrementAndGet());
+                    keyStore.setCertificateEntry(certAlias, cert);
+                }
+                
+                certChain = keyStore.getCertificateChain(certAlias);
+                if (certChain == null || certChain.length == 0)
+                {
+                    throw new IllegalStateException("Unable to retrieve certificate chain");
+                }
+            }
+            catch (KeyStoreException kse)
+            {
+                LOG.debug(kse);
+                throw new CertificateException("Unable to validate certificate" +
+                        (certAlias == null ? "":" for alias [" +certAlias + "]") + ": " + kse.getMessage(), kse);
+            }
+            
+            validate(certChain);
+        } 
+    }
+    
+    public void validate(Certificate[] certChain) throws CertificateException
+    {
+        try
+        {
+            ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
+            for (Certificate item : certChain)
+            {
+                if (item == null)
+                    continue;
+                
+                if (!(item instanceof X509Certificate))
+                {
+                    throw new IllegalStateException("Invalid certificate type in chain");
+                }
+                
+                certList.add((X509Certificate)item);
+            }
+    
+            if (certList.isEmpty())
+            {
+                throw new IllegalStateException("Invalid certificate chain");
+                
+            }
+    
+            X509CertSelector certSelect = new X509CertSelector();
+            certSelect.setCertificate(certList.get(0));
+            
+            // Configure certification path builder parameters
+            PKIXBuilderParameters pbParams = new PKIXBuilderParameters(_trustStore, certSelect);
+            pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)));
+    
+            // Set maximum certification path length
+            pbParams.setMaxPathLength(_maxCertPathLength);
+    
+            // Enable revocation checking
+            pbParams.setRevocationEnabled(true);
+    
+            // Set static Certificate Revocation List
+            if (_crls != null && !_crls.isEmpty())
+            {
+                pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls)));
+            }
+    
+            // Enable On-Line Certificate Status Protocol (OCSP) support
+            if (_enableOCSP)
+            {
+                Security.setProperty("ocsp.enable","true");
+            }
+            // Enable Certificate Revocation List Distribution Points (CRLDP) support
+            if (_enableCRLDP)
+            {
+                System.setProperty("com.sun.security.enableCRLDP","true");
+            }
+    
+            // Build certification path
+            CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams);               
+            
+            // Validate certification path
+            CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams);
+        }
+        catch (GeneralSecurityException gse)
+        {
+            LOG.debug(gse);
+            throw new CertificateException("Unable to validate certificate: " + gse.getMessage(), gse);
+        }
+    }
+
+    public KeyStore getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    public Collection<? extends CRL> getCrls()
+    {
+        return _crls;
+    }
+
+    /**
+     * @return Maximum number of intermediate certificates in
+     * the certification path (-1 for unlimited)
+     */
+    public int getMaxCertPathLength()
+    {
+        return _maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxCertPathLength
+     *            maximum number of intermediate certificates in
+     *            the certification path (-1 for unlimited)
+     */
+    public void setMaxCertPathLength(int maxCertPathLength)
+    {
+        _maxCertPathLength = maxCertPathLength;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return true if CRL Distribution Points support is enabled
+     */
+    public boolean isEnableCRLDP()
+    {
+        return _enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables CRL Distribution Points Support
+     * @param enableCRLDP true - turn on, false - turns off
+     */
+    public void setEnableCRLDP(boolean enableCRLDP)
+    {
+        _enableCRLDP = enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return true if On-Line Certificate Status Protocol support is enabled
+     */
+    public boolean isEnableOCSP()
+    {
+        return _enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables On-Line Certificate Status Protocol support
+     * @param enableOCSP true - turn on, false - turn off
+     */
+    public void setEnableOCSP(boolean enableOCSP)
+    {
+        _enableOCSP = enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Location of the OCSP Responder
+     */
+    public String getOcspResponderURL()
+    {
+        return _ocspResponderURL;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the location of the OCSP Responder.
+     * @param ocspResponderURL location of the OCSP Responder
+     */
+    public void setOcspResponderURL(String ocspResponderURL)
+    {
+        _ocspResponderURL = ocspResponderURL;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/security/Constraint.java b/src/java/org/eclipse/jetty/util/security/Constraint.java
new file mode 100644
index 0000000..779b409
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/Constraint.java
@@ -0,0 +1,226 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+/* ------------------------------------------------------------ */
+/**
+ * Describe an auth and/or data constraint.
+ * 
+ * 
+ */
+public class Constraint implements Cloneable, Serializable
+{
+    /* ------------------------------------------------------------ */
+    public final static String __BASIC_AUTH = "BASIC";
+
+    public final static String __FORM_AUTH = "FORM";
+
+    public final static String __DIGEST_AUTH = "DIGEST";
+
+    public final static String __CERT_AUTH = "CLIENT_CERT";
+
+    public final static String __CERT_AUTH2 = "CLIENT-CERT";
+    
+    public final static String __SPNEGO_AUTH = "SPNEGO";
+    
+    public final static String __NEGOTIATE_AUTH = "NEGOTIATE";
+    
+    public static boolean validateMethod (String method)
+    {
+        if (method == null)
+            return false;
+        method = method.trim();
+        return (method.equals(__FORM_AUTH) 
+                || method.equals(__BASIC_AUTH) 
+                || method.equals (__DIGEST_AUTH) 
+                || method.equals (__CERT_AUTH) 
+                || method.equals(__CERT_AUTH2)
+                || method.equals(__SPNEGO_AUTH)
+                || method.equals(__NEGOTIATE_AUTH));
+    }
+
+    /* ------------------------------------------------------------ */
+    public final static int DC_UNSET = -1, DC_NONE = 0, DC_INTEGRAL = 1, DC_CONFIDENTIAL = 2, DC_FORBIDDEN = 3;
+
+    /* ------------------------------------------------------------ */
+    public final static String NONE = "NONE";
+
+    public final static String ANY_ROLE = "*";
+
+    /* ------------------------------------------------------------ */
+    private String _name;
+
+    private String[] _roles;
+
+    private int _dataConstraint = DC_UNSET;
+
+    private boolean _anyRole = false;
+
+    private boolean _authenticate = false;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructor.
+     */
+    public Constraint()
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Conveniance Constructor.
+     * 
+     * @param name
+     * @param role
+     */
+    public Constraint(String name, String role)
+    {
+        setName(name);
+        setRoles(new String[] { role });
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public Object clone() throws CloneNotSupportedException
+    {
+        return super.clone();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     */
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setRoles(String[] roles)
+    {
+        _roles = roles;
+        _anyRole = false;
+        if (roles != null) 
+            for (int i = roles.length; !_anyRole && i-- > 0;)
+                _anyRole |= ANY_ROLE.equals(roles[i]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if any user role is permitted.
+     */
+    public boolean isAnyRole()
+    {
+        return _anyRole;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return List of roles for this constraint.
+     */
+    public String[] getRoles()
+    {
+        return _roles;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param role
+     * @return True if the constraint contains the role.
+     */
+    public boolean hasRole(String role)
+    {
+        if (_anyRole) return true;
+        if (_roles != null) for (int i = _roles.length; i-- > 0;)
+            if (role.equals(_roles[i])) return true;
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param authenticate True if users must be authenticated
+     */
+    public void setAuthenticate(boolean authenticate)
+    {
+        _authenticate = authenticate;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the constraint requires request authentication
+     */
+    public boolean getAuthenticate()
+    {
+        return _authenticate;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if authentication required but no roles set
+     */
+    public boolean isForbidden()
+    {
+        return _authenticate && !_anyRole && (_roles == null || _roles.length == 0);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param c Data constrain indicator: 0=DC+NONE, 1=DC_INTEGRAL &
+     *                2=DC_CONFIDENTIAL
+     */
+    public void setDataConstraint(int c)
+    {
+        if (c < 0 || c > DC_CONFIDENTIAL) throw new IllegalArgumentException("Constraint out of range");
+        _dataConstraint = c;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Data constrain indicator: 0=DC+NONE, 1=DC_INTEGRAL &
+     *         2=DC_CONFIDENTIAL
+     */
+    public int getDataConstraint()
+    {
+        return _dataConstraint;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if a data constraint has been set.
+     */
+    public boolean hasDataConstraint()
+    {
+        return _dataConstraint >= DC_NONE;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return "SC{" + _name
+               + ","
+               + (_anyRole ? "*" : (_roles == null ? "-" : Arrays.asList(_roles).toString()))
+               + ","
+               + (_dataConstraint == DC_UNSET ? "DC_UNSET}" : (_dataConstraint == DC_NONE ? "NONE}" : (_dataConstraint == DC_INTEGRAL ? "INTEGRAL}" : "CONFIDENTIAL}")));
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/security/Credential.java b/src/java/org/eclipse/jetty/util/security/Credential.java
new file mode 100644
index 0000000..7599bdf
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/Credential.java
@@ -0,0 +1,229 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+import java.io.Serializable;
+import java.security.MessageDigest;
+
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Credentials. The Credential class represents an abstract mechanism for
+ * checking authentication credentials. A credential instance either represents
+ * a secret, or some data that could only be derived from knowing the secret.
+ * <p>
+ * Often a Credential is related to a Password via a one way algorithm, so while
+ * a Password itself is a Credential, a UnixCrypt or MD5 digest of a a password
+ * is only a credential that can be checked against the password.
+ * <p>
+ * This class includes an implementation for unix Crypt an MD5 digest.
+ * 
+ * @see Password
+ * 
+ */
+public abstract class Credential implements Serializable
+{
+    private static final Logger LOG = Log.getLogger(Credential.class);
+
+    private static final long serialVersionUID = -7760551052768181572L;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Check a credential
+     * 
+     * @param credentials The credential to check against. This may either be
+     *                another Credential object, a Password object or a String
+     *                which is interpreted by this credential.
+     * @return True if the credentials indicated that the shared secret is known
+     *         to both this Credential and the passed credential.
+     */
+    public abstract boolean check(Object credentials);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a credential from a String. If the credential String starts with a
+     * known Credential type (eg "CRYPT:" or "MD5:" ) then a Credential of that
+     * type is returned. Else the credential is assumed to be a Password.
+     * 
+     * @param credential String representation of the credential
+     * @return A Credential or Password instance.
+     */
+    public static Credential getCredential(String credential)
+    {
+        if (credential.startsWith(Crypt.__TYPE)) return new Crypt(credential);
+        if (credential.startsWith(MD5.__TYPE)) return new MD5(credential);
+
+        return new Password(credential);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Unix Crypt Credentials
+     */
+    public static class Crypt extends Credential
+    {
+        private static final long serialVersionUID = -2027792997664744210L;
+
+        public static final String __TYPE = "CRYPT:";
+
+        private final String _cooked;
+
+        Crypt(String cooked)
+        {
+            _cooked = cooked.startsWith(Crypt.__TYPE) ? cooked.substring(__TYPE.length()) : cooked;
+        }
+
+        @Override
+        public boolean check(Object credentials)
+        {
+            if (credentials instanceof char[])
+                credentials=new String((char[])credentials);
+            if (!(credentials instanceof String) && !(credentials instanceof Password)) 
+                LOG.warn("Can't check " + credentials.getClass() + " against CRYPT");
+
+            String passwd = credentials.toString();
+            return _cooked.equals(UnixCrypt.crypt(passwd, _cooked));
+        }
+
+        public static String crypt(String user, String pw)
+        {
+            return "CRYPT:" + UnixCrypt.crypt(pw, user);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * MD5 Credentials
+     */
+    public static class MD5 extends Credential
+    {
+        private static final long serialVersionUID = 5533846540822684240L;
+
+        public static final String __TYPE = "MD5:";
+
+        public static final Object __md5Lock = new Object();
+
+        private static MessageDigest __md;
+
+        private final byte[] _digest;
+
+        /* ------------------------------------------------------------ */
+        MD5(String digest)
+        {
+            digest = digest.startsWith(__TYPE) ? digest.substring(__TYPE.length()) : digest;
+            _digest = TypeUtil.parseBytes(digest, 16);
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte[] getDigest()
+        {
+            return _digest;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public boolean check(Object credentials)
+        {
+            try
+            {
+                byte[] digest = null;
+
+                if (credentials instanceof char[])
+                    credentials=new String((char[])credentials);
+                if (credentials instanceof Password || credentials instanceof String)
+                {
+                    synchronized (__md5Lock)
+                    {
+                        if (__md == null) __md = MessageDigest.getInstance("MD5");
+                        __md.reset();
+                        __md.update(credentials.toString().getBytes(StringUtil.__ISO_8859_1));
+                        digest = __md.digest();
+                    }
+                    if (digest == null || digest.length != _digest.length) return false;
+                    for (int i = 0; i < digest.length; i++)
+                        if (digest[i] != _digest[i]) return false;
+                    return true;
+                }
+                else if (credentials instanceof MD5)
+                {
+                    MD5 md5 = (MD5) credentials;
+                    if (_digest.length != md5._digest.length) return false;
+                    for (int i = 0; i < _digest.length; i++)
+                        if (_digest[i] != md5._digest[i]) return false;
+                    return true;
+                }
+                else if (credentials instanceof Credential)
+                {
+                    // Allow credential to attempt check - i.e. this'll work
+                    // for DigestAuthModule$Digest credentials
+                    return ((Credential) credentials).check(this);
+                }
+                else
+                {
+                    LOG.warn("Can't check " + credentials.getClass() + " against MD5");
+                    return false;
+                }
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+                return false;
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public static String digest(String password)
+        {
+            try
+            {
+                byte[] digest;
+                synchronized (__md5Lock)
+                {
+                    if (__md == null)
+                    {
+                        try
+                        {
+                            __md = MessageDigest.getInstance("MD5");
+                        }
+                        catch (Exception e)
+                        {
+                            LOG.warn(e);
+                            return null;
+                        }
+                    }
+
+                    __md.reset();
+                    __md.update(password.getBytes(StringUtil.__ISO_8859_1));
+                    digest = __md.digest();
+                }
+
+                return __TYPE + TypeUtil.toString(digest, 16);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e);
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/security/Password.java b/src/java/org/eclipse/jetty/util/security/Password.java
new file mode 100644
index 0000000..e0fc5d5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/Password.java
@@ -0,0 +1,257 @@
+//
+//  ========================================================================
+//  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.util.security;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Password utility class.
+ * 
+ * This utility class gets a password or pass phrase either by:
+ * 
+ * <PRE>
+ *  + Password is set as a system property.
+ *  + The password is prompted for and read from standard input
+ *  + A program is run to get the password.
+ * </pre>
+ * 
+ * Passwords that begin with OBF: are de obfuscated. Passwords can be obfuscated
+ * by run org.eclipse.util.Password as a main class. Obfuscated password are
+ * required if a system needs to recover the full password (eg. so that it may
+ * be passed to another system). They are not secure, but prevent casual
+ * observation.
+ * <p>
+ * Passwords that begin with CRYPT: are oneway encrypted with UnixCrypt. The
+ * real password cannot be retrieved, but comparisons can be made to other
+ * passwords. A Crypt can be generated by running org.eclipse.util.UnixCrypt as
+ * a main class, passing password and then the username. Checksum passwords are
+ * a secure(ish) way to store passwords that only need to be checked rather than
+ * recovered. Note that it is not strong security - specially if simple
+ * passwords are used.
+ * 
+ * 
+ */
+public class Password extends Credential
+{
+    private static final Logger LOG = Log.getLogger(Password.class);
+
+    private static final long serialVersionUID = 5062906681431569445L;
+
+    public static final String __OBFUSCATE = "OBF:";
+
+    private String _pw;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructor.
+     * 
+     * @param password The String password.
+     */
+    public Password(String password)
+    {
+        _pw = password;
+
+        // expand password
+        while (_pw != null && _pw.startsWith(__OBFUSCATE))
+            _pw = deobfuscate(_pw);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return _pw;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toStarString()
+    {
+        return "*****************************************************".substring(0, _pw.length());
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean check(Object credentials)
+    {
+        if (this == credentials) return true;
+
+        if (credentials instanceof Password) return credentials.equals(_pw);
+
+        if (credentials instanceof String) return credentials.equals(_pw);
+
+        if (credentials instanceof char[]) return Arrays.equals(_pw.toCharArray(), (char[]) credentials);
+
+        if (credentials instanceof Credential) return ((Credential) credentials).check(_pw);
+
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o) 
+            return true;
+
+        if (null == o) 
+            return false;
+
+        if (o instanceof Password)
+        {
+            Password p = (Password) o;
+            //noinspection StringEquality
+            return p._pw == _pw || (null != _pw && _pw.equals(p._pw));
+        }
+
+        if (o instanceof String) 
+            return o.equals(_pw);
+
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public int hashCode()
+    {
+        return null == _pw ? super.hashCode() : _pw.hashCode();
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String obfuscate(String s)
+    {
+        StringBuilder buf = new StringBuilder();
+        byte[] b = s.getBytes();
+
+        buf.append(__OBFUSCATE);
+        for (int i = 0; i < b.length; i++)
+        {
+            byte b1 = b[i];
+            byte b2 = b[s.length() - (i + 1)];
+            int i1 = 127 + b1 + b2;
+            int i2 = 127 + b1 - b2;
+            int i0 = i1 * 256 + i2;
+            String x = Integer.toString(i0, 36);
+
+            switch (x.length())
+            {
+                case 1:
+                    buf.append('0');
+                    buf.append('0');
+                    buf.append('0');
+                    buf.append(x);
+                    break;
+                case 2:
+                    buf.append('0');
+                    buf.append('0');
+                    buf.append(x);
+                    break;
+                case 3:
+                    buf.append('0');
+                    buf.append(x);
+                    break;
+                default:
+                    buf.append(x);
+                    break;
+            }
+        }
+        return buf.toString();
+
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String deobfuscate(String s)
+    {
+        if (s.startsWith(__OBFUSCATE)) s = s.substring(4);
+
+        byte[] b = new byte[s.length() / 2];
+        int l = 0;
+        for (int i = 0; i < s.length(); i += 4)
+        {
+            String x = s.substring(i, i + 4);
+            int i0 = Integer.parseInt(x, 36);
+            int i1 = (i0 / 256);
+            int i2 = (i0 % 256);
+            b[l++] = (byte) ((i1 + i2 - 254) / 2);
+        }
+
+        return new String(b, 0, l);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a password. A password is obtained by trying
+     * <UL>
+     * <LI>Calling <Code>System.getProperty(realm,dft)</Code>
+     * <LI>Prompting for a password
+     * <LI>Using promptDft if nothing was entered.
+     * </UL>
+     * 
+     * @param realm The realm name for the password, used as a SystemProperty
+     *                name.
+     * @param dft The default password.
+     * @param promptDft The default to use if prompting for the password.
+     * @return Password
+     */
+    public static Password getPassword(String realm, String dft, String promptDft)
+    {
+        String passwd = System.getProperty(realm, dft);
+        if (passwd == null || passwd.length() == 0)
+        {
+            try
+            {
+                System.out.print(realm + ((promptDft != null && promptDft.length() > 0) ? " [dft]" : "") + " : ");
+                System.out.flush();
+                byte[] buf = new byte[512];
+                int len = System.in.read(buf);
+                if (len > 0) passwd = new String(buf, 0, len).trim();
+            }
+            catch (IOException e)
+            {
+                LOG.warn(Log.EXCEPTION, e);
+            }
+            if (passwd == null || passwd.length() == 0) passwd = promptDft;
+        }
+        return new Password(passwd);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param arg
+     */
+    public static void main(String[] arg)
+    {
+        if (arg.length != 1 && arg.length != 2)
+        {
+            System.err.println("Usage - java org.eclipse.jetty.security.Password [<user>] <password>");
+            System.err.println("If the password is ?, the user will be prompted for the password");
+            System.exit(1);
+        }
+        String p = arg[arg.length == 1 ? 0 : 1];
+        Password pw = new Password(p);
+        System.err.println(pw.toString());
+        System.err.println(obfuscate(pw.toString()));
+        System.err.println(Credential.MD5.digest(p));
+        if (arg.length == 2) System.err.println(Credential.Crypt.crypt(arg[0], pw.toString()));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/security/UnixCrypt.java b/src/java/org/eclipse/jetty/util/security/UnixCrypt.java
new file mode 100644
index 0000000..e3f98e8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/security/UnixCrypt.java
@@ -0,0 +1,461 @@
+/*
+ * @(#)UnixCrypt.java	0.9 96/11/25
+ *
+ * Copyright (c) 1996 Aki Yoshida. All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software
+ * for non-commercial or commercial purposes and without fee is
+ * hereby granted provided that this copyright notice appears in
+ * all copies.
+ */
+
+/**
+ * Unix crypt(3C) utility
+ *
+ * @version 	0.9, 11/25/96
+ * @author 	Aki Yoshida
+ */
+
+/**
+ * modified April 2001
+ * by Iris Van den Broeke, Daniel Deville
+ */
+
+package org.eclipse.jetty.util.security;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Unix Crypt. Implements the one way cryptography used by Unix systems for
+ * simple password protection.
+ * 
+ * @version $Id: UnixCrypt.java,v 1.1 2005/10/05 14:09:14 janb Exp $
+ * @author Greg Wilkins (gregw)
+ */
+public class UnixCrypt
+{
+
+    /* (mostly) Standard DES Tables from Tom Truscott */
+    private static final byte[] IP = { /* initial permutation */
+    58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1,
+            59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };
+
+    /* The final permutation is the inverse of IP - no table is necessary */
+    private static final byte[] ExpandTr = { /* expansion operation */
+    32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29,
+            28, 29, 30, 31, 32, 1 };
+
+    private static final byte[] PC1 = { /* permuted choice table 1 */
+    57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+
+    63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 };
+
+    private static final byte[] Rotates = { /* PC1 rotation schedule */
+    1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
+
+    private static final byte[] PC2 = { /* permuted choice table 2 */
+    9, 18, 14, 17, 11, 24, 1, 5, 22, 25, 3, 28, 15, 6, 21, 10, 35, 38, 23, 19, 12, 4, 26, 8, 43, 54, 16, 7, 27, 20, 13, 2,
+
+    0, 0, 41, 52, 31, 37, 47, 55, 0, 0, 30, 40, 51, 45, 33, 48, 0, 0, 44, 49, 39, 56, 34, 53, 0, 0, 46, 42, 50, 36, 29, 32 };
+
+    private static final byte[][] S = { /* 48->32 bit substitution tables */
+            /* S[1] */
+            { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9,
+             7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 },
+            /* S[2] */
+            { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12,
+             6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 },
+            /* S[3] */
+            { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2,
+             12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 },
+            /* S[4] */
+            { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3,
+             14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 },
+            /* S[5] */
+            { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12,
+             5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 },
+            /* S[6] */
+            { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4,
+             10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 },
+            /* S[7] */
+            { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15,
+             6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 },
+            /* S[8] */
+            { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10,
+             13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } };
+
+    private static final byte[] P32Tr = { /* 32-bit permutation function */
+    16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
+
+    private static final byte[] CIFP = { /*
+                                             * compressed/interleaved
+                                             * permutation
+                                             */
+    1, 2, 3, 4, 17, 18, 19, 20, 5, 6, 7, 8, 21, 22, 23, 24, 9, 10, 11, 12, 25, 26, 27, 28, 13, 14, 15, 16, 29, 30, 31, 32,
+
+    33, 34, 35, 36, 49, 50, 51, 52, 37, 38, 39, 40, 53, 54, 55, 56, 41, 42, 43, 44, 57, 58, 59, 60, 45, 46, 47, 48, 61, 62, 63, 64 };
+
+    private static final byte[] ITOA64 = { /* 0..63 => ascii-64 */
+    (byte) '.', (byte) '/', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'A',
+            (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M',
+            (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y',
+            (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
+            (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w',
+            (byte) 'x', (byte) 'y', (byte) 'z' };
+
+    /* ===== Tables that are initialized at run time ==================== */
+
+    private static final byte[] A64TOI = new byte[128]; /* ascii-64 => 0..63 */
+
+    /* Initial key schedule permutation */
+    private static final long[][] PC1ROT = new long[16][16];
+
+    /* Subsequent key schedule rotation permutations */
+    private static final long[][][] PC2ROT = new long[2][16][16];
+
+    /* Initial permutation/expansion table */
+    private static final long[][] IE3264 = new long[8][16];
+
+    /* Table that combines the S, P, and E operations. */
+    private static final long[][] SPE = new long[8][64];
+
+    /* compressed/interleaved => final permutation table */
+    private static final long[][] CF6464 = new long[16][16];
+
+    /* ==================================== */
+
+    static
+    {
+        byte[] perm = new byte[64];
+        byte[] temp = new byte[64];
+
+        // inverse table.
+        for (int i = 0; i < 64; i++)
+            A64TOI[ITOA64[i]] = (byte) i;
+
+        // PC1ROT - bit reverse, then PC1, then Rotate, then PC2
+        for (int i = 0; i < 64; i++)
+            perm[i] = (byte) 0;
+        
+        for (int i = 0; i < 64; i++)
+        {
+            int k;
+            if ((k = PC2[i]) == 0) continue;
+            k += Rotates[0] - 1;
+            if ((k % 28) < Rotates[0]) k -= 28;
+            k = PC1[k];
+            if (k > 0)
+            {
+                k--;
+                k = (k | 0x07) - (k & 0x07);
+                k++;
+            }
+            perm[i] = (byte) k;
+        }
+        init_perm(PC1ROT, perm, 8);
+
+        // PC2ROT - PC2 inverse, then Rotate, then PC2
+        for (int j = 0; j < 2; j++)
+        {
+            int k;
+            for (int i = 0; i < 64; i++)
+                perm[i] = temp[i] = 0;
+            for (int i = 0; i < 64; i++)
+            {
+                if ((k = PC2[i]) == 0) continue;
+                temp[k - 1] = (byte) (i + 1);
+            }
+            for (int i = 0; i < 64; i++)
+            {
+                if ((k = PC2[i]) == 0) continue;
+                k += j;
+                if ((k % 28) <= j) k -= 28;
+                perm[i] = temp[k];
+            }
+
+            init_perm(PC2ROT[j], perm, 8);
+        }
+
+        // Bit reverse, intial permupation, expantion
+        for (int i = 0; i < 8; i++)
+        {
+            for (int j = 0; j < 8; j++)
+            {
+                int k = (j < 2) ? 0 : IP[ExpandTr[i * 6 + j - 2] - 1];
+                if (k > 32)
+                    k -= 32;
+                else if (k > 0) k--;
+                if (k > 0)
+                {
+                    k--;
+                    k = (k | 0x07) - (k & 0x07);
+                    k++;
+                }
+                perm[i * 8 + j] = (byte) k;
+            }
+        }
+
+        init_perm(IE3264, perm, 8);
+
+        // Compression, final permutation, bit reverse
+        for (int i = 0; i < 64; i++)
+        {
+            int k = IP[CIFP[i] - 1];
+            if (k > 0)
+            {
+                k--;
+                k = (k | 0x07) - (k & 0x07);
+                k++;
+            }
+            perm[k - 1] = (byte) (i + 1);
+        }
+
+        init_perm(CF6464, perm, 8);
+
+        // SPE table
+        for (int i = 0; i < 48; i++)
+            perm[i] = P32Tr[ExpandTr[i] - 1];
+        for (int t = 0; t < 8; t++)
+        {
+            for (int j = 0; j < 64; j++)
+            {
+                int k = (((j >> 0) & 0x01) << 5) | (((j >> 1) & 0x01) << 3)
+                        | (((j >> 2) & 0x01) << 2)
+                        | (((j >> 3) & 0x01) << 1)
+                        | (((j >> 4) & 0x01) << 0)
+                        | (((j >> 5) & 0x01) << 4);
+                k = S[t][k];
+                k = (((k >> 3) & 0x01) << 0) | (((k >> 2) & 0x01) << 1) | (((k >> 1) & 0x01) << 2) | (((k >> 0) & 0x01) << 3);
+                for (int i = 0; i < 32; i++)
+                    temp[i] = 0;
+                for (int i = 0; i < 4; i++)
+                    temp[4 * t + i] = (byte) ((k >> i) & 0x01);
+                long kk = 0;
+                for (int i = 24; --i >= 0;)
+                    kk = ((kk << 1) | ((long) temp[perm[i] - 1]) << 32 | (temp[perm[i + 24] - 1]));
+
+                SPE[t][j] = to_six_bit(kk);
+            }
+        }
+    }
+
+    /**
+     * You can't call the constructer.
+     */
+    private UnixCrypt()
+    {
+    }
+
+    /**
+     * Returns the transposed and split code of a 24-bit code into a 4-byte
+     * code, each having 6 bits.
+     */
+    private static int to_six_bit(int num)
+    {
+        return (((num << 26) & 0xfc000000) | ((num << 12) & 0xfc0000) | ((num >> 2) & 0xfc00) | ((num >> 16) & 0xfc));
+    }
+
+    /**
+     * Returns the transposed and split code of two 24-bit code into two 4-byte
+     * code, each having 6 bits.
+     */
+    private static long to_six_bit(long num)
+    {
+        return (((num << 26) & 0xfc000000fc000000L) | ((num << 12) & 0xfc000000fc0000L) | ((num >> 2) & 0xfc000000fc00L) | ((num >> 16) & 0xfc000000fcL));
+    }
+
+    /**
+     * Returns the permutation of the given 64-bit code with the specified
+     * permutataion table.
+     */
+    private static long perm6464(long c, long[][] p)
+    {
+        long out = 0L;
+        for (int i = 8; --i >= 0;)
+        {
+            int t = (int) (0x00ff & c);
+            c >>= 8;
+            long tp = p[i << 1][t & 0x0f];
+            out |= tp;
+            tp = p[(i << 1) + 1][t >> 4];
+            out |= tp;
+        }
+        return out;
+    }
+
+    /**
+     * Returns the permutation of the given 32-bit code with the specified
+     * permutataion table.
+     */
+    private static long perm3264(int c, long[][] p)
+    {
+        long out = 0L;
+        for (int i = 4; --i >= 0;)
+        {
+            int t = (0x00ff & c);
+            c >>= 8;
+            long tp = p[i << 1][t & 0x0f];
+            out |= tp;
+            tp = p[(i << 1) + 1][t >> 4];
+            out |= tp;
+        }
+        return out;
+    }
+
+    /**
+     * Returns the key schedule for the given key.
+     */
+    private static long[] des_setkey(long keyword)
+    {
+        long K = perm6464(keyword, PC1ROT);
+        long[] KS = new long[16];
+        KS[0] = K & ~0x0303030300000000L;
+
+        for (int i = 1; i < 16; i++)
+        {
+            KS[i] = K;
+            K = perm6464(K, PC2ROT[Rotates[i] - 1]);
+
+            KS[i] = K & ~0x0303030300000000L;
+        }
+        return KS;
+    }
+
+    /**
+     * Returns the DES encrypted code of the given word with the specified
+     * environment.
+     */
+    private static long des_cipher(long in, int salt, int num_iter, long[] KS)
+    {
+        salt = to_six_bit(salt);
+        long L = in;
+        long R = L;
+        L &= 0x5555555555555555L;
+        R = (R & 0xaaaaaaaa00000000L) | ((R >> 1) & 0x0000000055555555L);
+        L = ((((L << 1) | (L << 32)) & 0xffffffff00000000L) | ((R | (R >> 32)) & 0x00000000ffffffffL));
+
+        L = perm3264((int) (L >> 32), IE3264);
+        R = perm3264((int) (L & 0xffffffff), IE3264);
+
+        while (--num_iter >= 0)
+        {
+            for (int loop_count = 0; loop_count < 8; loop_count++)
+            {
+                long kp;
+                long B;
+                long k;
+
+                kp = KS[(loop_count << 1)];
+                k = ((R >> 32) ^ R) & salt & 0xffffffffL;
+                k |= (k << 32);
+                B = (k ^ R ^ kp);
+
+                L ^= (SPE[0][(int) ((B >> 58) & 0x3f)] ^ SPE[1][(int) ((B >> 50) & 0x3f)]
+                      ^ SPE[2][(int) ((B >> 42) & 0x3f)]
+                      ^ SPE[3][(int) ((B >> 34) & 0x3f)]
+                      ^ SPE[4][(int) ((B >> 26) & 0x3f)]
+                      ^ SPE[5][(int) ((B >> 18) & 0x3f)]
+                      ^ SPE[6][(int) ((B >> 10) & 0x3f)] ^ SPE[7][(int) ((B >> 2) & 0x3f)]);
+
+                kp = KS[(loop_count << 1) + 1];
+                k = ((L >> 32) ^ L) & salt & 0xffffffffL;
+                k |= (k << 32);
+                B = (k ^ L ^ kp);
+
+                R ^= (SPE[0][(int) ((B >> 58) & 0x3f)] ^ SPE[1][(int) ((B >> 50) & 0x3f)]
+                      ^ SPE[2][(int) ((B >> 42) & 0x3f)]
+                      ^ SPE[3][(int) ((B >> 34) & 0x3f)]
+                      ^ SPE[4][(int) ((B >> 26) & 0x3f)]
+                      ^ SPE[5][(int) ((B >> 18) & 0x3f)]
+                      ^ SPE[6][(int) ((B >> 10) & 0x3f)] ^ SPE[7][(int) ((B >> 2) & 0x3f)]);
+            }
+            // swap L and R
+            L ^= R;
+            R ^= L;
+            L ^= R;
+        }
+        L = ((((L >> 35) & 0x0f0f0f0fL) | (((L & 0xffffffff) << 1) & 0xf0f0f0f0L)) << 32 | (((R >> 35) & 0x0f0f0f0fL) | (((R & 0xffffffff) << 1) & 0xf0f0f0f0L)));
+
+        L = perm6464(L, CF6464);
+
+        return L;
+    }
+
+    /**
+     * Initializes the given permutation table with the mapping table.
+     */
+    private static void init_perm(long[][] perm, byte[] p, int chars_out)
+    {
+        for (int k = 0; k < chars_out * 8; k++)
+        {
+
+            int l = p[k] - 1;
+            if (l < 0) continue;
+            int i = l >> 2;
+            l = 1 << (l & 0x03);
+            for (int j = 0; j < 16; j++)
+            {
+                int s = ((k & 0x07) + ((7 - (k >> 3)) << 3));
+                if ((j & l) != 0x00) perm[i][j] |= (1L << s);
+            }
+        }
+    }
+
+    /**
+     * Encrypts String into crypt (Unix) code.
+     * 
+     * @param key the key to be encrypted
+     * @param setting the salt to be used
+     * @return the encrypted String
+     */
+    public static String crypt(String key, String setting)
+    {
+        long constdatablock = 0L; /* encryption constant */
+        byte[] cryptresult = new byte[13]; /* encrypted result */
+        long keyword = 0L;
+        /* invalid parameters! */
+        if (key == null || setting == null) return "*"; // will NOT match under
+        // ANY circumstances!
+
+        int keylen = key.length();
+
+        for (int i = 0; i < 8; i++)
+        {
+            keyword = (keyword << 8) | ((i < keylen) ? 2 * key.charAt(i) : 0);
+        }
+
+        long[] KS = des_setkey(keyword);
+
+        int salt = 0;
+        for (int i = 2; --i >= 0;)
+        {
+            char c = (i < setting.length()) ? setting.charAt(i) : '.';
+            cryptresult[i] = (byte) c;
+            salt = (salt << 6) | (0x00ff & A64TOI[c]);
+        }
+
+        long rsltblock = des_cipher(constdatablock, salt, 25, KS);
+
+        cryptresult[12] = ITOA64[(((int) rsltblock) << 2) & 0x3f];
+        rsltblock >>= 4;
+        for (int i = 12; --i >= 2;)
+        {
+            cryptresult[i] = ITOA64[((int) rsltblock) & 0x3f];
+            rsltblock >>= 6;
+        }
+
+        return new String(cryptresult, 0, 13);
+    }
+
+    public static void main(String[] arg)
+    {
+        if (arg.length != 2)
+        {
+            System.err.println("Usage - java org.eclipse.util.UnixCrypt <key> <salt>");
+            System.exit(1);
+        }
+
+        System.err.println("Crypt=" + crypt(arg[0], arg[1]));
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java b/src/java/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java
new file mode 100644
index 0000000..0eea9ab
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java
@@ -0,0 +1,130 @@
+//
+//  ========================================================================
+//  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.util.ssl;
+
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * KeyManager to select a key with desired alias
+ * while delegating processing to specified KeyManager
+ * Can be used both with server and client sockets
+ */
+public class AliasedX509ExtendedKeyManager extends X509ExtendedKeyManager
+{
+    private String _keyAlias;
+    private X509KeyManager _keyManager;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct KeyManager instance
+     * @param keyAlias Alias of the key to be selected
+     * @param keyManager Instance of KeyManager to be wrapped
+     * @throws Exception
+     */
+    public AliasedX509ExtendedKeyManager(String keyAlias, X509KeyManager keyManager) throws Exception
+    {
+        _keyAlias = keyAlias;
+        _keyManager = keyManager;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket)
+     */
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
+    {
+        return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket)
+     */
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
+    {   
+        return _keyAlias == null ? _keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, java.security.Principal[])
+     */
+    public String[] getClientAliases(String keyType, Principal[] issuers)
+    {
+        return _keyManager.getClientAliases(keyType, issuers);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, java.security.Principal[])
+     */
+    public String[] getServerAliases(String keyType, Principal[] issuers)
+    {
+        return _keyManager.getServerAliases(keyType, issuers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String)
+     */
+    public X509Certificate[] getCertificateChain(String alias)
+    {
+        return _keyManager.getCertificateChain(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String)
+     */
+    public PrivateKey getPrivateKey(String alias)
+    {
+        return _keyManager.getPrivateKey(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineServerAlias(java.lang.String, java.security.Principal[], javax.net.ssl.SSLEngine)
+     */
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
+    {
+        return _keyAlias == null ? super.chooseEngineServerAlias(keyType,issuers,engine) : _keyAlias;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineClientAlias(String[], Principal[], SSLEngine)
+     */
+    @Override
+    public String chooseEngineClientAlias(String keyType[], Principal[] issuers, SSLEngine engine)
+    {
+        return _keyAlias == null ? super.chooseEngineClientAlias(keyType,issuers,engine) : _keyAlias;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ssl/AliasedX509KeyManager.java b/src/java/org/eclipse/jetty/util/ssl/AliasedX509KeyManager.java
new file mode 100644
index 0000000..5da3408
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ssl/AliasedX509KeyManager.java
@@ -0,0 +1,107 @@
+//
+//  ========================================================================
+//  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.util.ssl;
+
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509KeyManager;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * KeyManager to select a key with desired alias
+ * while delegating processing to specified KeyManager
+ * Can be used both with server and client sockets
+ */
+public class AliasedX509KeyManager implements X509KeyManager
+{
+    private String _keyAlias;
+    private X509KeyManager _keyManager;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct KeyManager instance
+     * @param keyAlias Alias of the key to be selected
+     * @param keyManager Instance of KeyManager to be wrapped
+     * @throws Exception
+     */
+    public AliasedX509KeyManager(String keyAlias, X509KeyManager keyManager) throws Exception
+    {
+        _keyAlias = keyAlias;
+        _keyManager = keyManager;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket)
+     */
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
+    {
+        return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket)
+     */
+    public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
+    {   
+        return _keyAlias == null ?_keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, java.security.Principal[])
+     */
+    public String[] getClientAliases(String keyType, Principal[] issuers)
+    {
+        return _keyManager.getClientAliases(keyType, issuers);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, java.security.Principal[])
+     */
+    public String[] getServerAliases(String keyType, Principal[] issuers)
+    {
+        return _keyManager.getServerAliases(keyType, issuers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String)
+     */
+    public X509Certificate[] getCertificateChain(String alias)
+    {
+        return _keyManager.getCertificateChain(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String)
+     */
+    public PrivateKey getPrivateKey(String alias)
+    {
+        return _keyManager.getPrivateKey(alias);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/src/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
new file mode 100644
index 0000000..c304f17
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
@@ -0,0 +1,1537 @@
+//
+//  ========================================================================
+//  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.util.ssl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.security.InvalidParameterException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CertStore;
+import java.security.cert.Certificate;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509KeyManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.CertificateUtils;
+import org.eclipse.jetty.util.security.CertificateValidator;
+import org.eclipse.jetty.util.security.Password;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * SslContextFactory is used to configure SSL connectors
+ * as well as HttpClient. It holds all SSL parameters and
+ * creates SSL context based on these parameters to be
+ * used by the SSL connectors.
+ */
+public class SslContextFactory extends AbstractLifeCycle
+{
+    public final static TrustManager[] TRUST_ALL_CERTS = new X509TrustManager[]{new X509TrustManager()
+    {
+        public java.security.cert.X509Certificate[] getAcceptedIssuers()
+        {
+            return new java.security.cert.X509Certificate[]{};
+        }
+
+        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
+        {
+        }
+
+        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
+        {
+        }
+    }};
+
+    private static final Logger LOG = Log.getLogger(SslContextFactory.class);
+
+    public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
+        (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
+                "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
+    public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM =
+        (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ?
+                "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm"));
+
+    /** Default value for the keystore location path. */
+    public static final String DEFAULT_KEYSTORE_PATH =
+        System.getProperty("user.home") + File.separator + ".keystore";
+
+    /** String name of key password property. */
+    public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";
+
+    /** String name of keystore password property. */
+    public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
+
+    /** Excluded protocols. */
+    private final Set<String> _excludeProtocols = new LinkedHashSet<String>();
+    /** Included protocols. */
+    private Set<String> _includeProtocols = null;
+
+    /** Excluded cipher suites. */
+    private final Set<String> _excludeCipherSuites = new LinkedHashSet<String>();
+    /** Included cipher suites. */
+    private Set<String> _includeCipherSuites = null;
+
+    /** Keystore path. */
+    private String _keyStorePath;
+    /** Keystore provider name */
+    private String _keyStoreProvider;
+    /** Keystore type */
+    private String _keyStoreType = "JKS";
+    /** Keystore input stream */
+    private InputStream _keyStoreInputStream;
+
+    /** SSL certificate alias */
+    private String _certAlias;
+
+    /** Truststore path */
+    private String _trustStorePath;
+    /** Truststore provider name */
+    private String _trustStoreProvider;
+    /** Truststore type */
+    private String _trustStoreType = "JKS";
+    /** Truststore input stream */
+    private InputStream _trustStoreInputStream;
+
+    /** Set to true if client certificate authentication is required */
+    private boolean _needClientAuth = false;
+    /** Set to true if client certificate authentication is desired */
+    private boolean _wantClientAuth = false;
+
+    /** Set to true if renegotiation is allowed */
+    private boolean _allowRenegotiate = true;
+
+    /** Keystore password */
+    private transient Password _keyStorePassword;
+    /** Key manager password */
+    private transient Password _keyManagerPassword;
+    /** Truststore password */
+    private transient Password _trustStorePassword;
+
+    /** SSL provider name */
+    private String _sslProvider;
+    /** SSL protocol name */
+    private String _sslProtocol = "TLS";
+
+    /** SecureRandom algorithm */
+    private String _secureRandomAlgorithm;
+    /** KeyManager factory algorithm */
+    private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM;
+    /** TrustManager factory algorithm */
+    private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM;
+
+    /** Set to true if SSL certificate validation is required */
+    private boolean _validateCerts;
+    /** Set to true if SSL certificate of the peer validation is required */
+    private boolean _validatePeerCerts;
+    /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
+    private int _maxCertPathLength = -1;
+    /** Path to file that contains Certificate Revocation List */
+    private String _crlPath;
+    /** Set to true to enable CRL Distribution Points (CRLDP) support */
+    private boolean _enableCRLDP = false;
+    /** Set to true to enable On-Line Certificate Status Protocol (OCSP) support */
+    private boolean _enableOCSP = false;
+    /** Location of OCSP Responder */
+    private String _ocspResponderURL;
+
+    /** SSL keystore */
+    private KeyStore _keyStore;
+    /** SSL truststore */
+    private KeyStore _trustStore;
+    /** Set to true to enable SSL Session caching */
+    private boolean _sessionCachingEnabled = true;
+    /** SSL session cache size */
+    private int _sslSessionCacheSize;
+    /** SSL session timeout */
+    private int _sslSessionTimeout;
+
+    /** SSL context */
+    private SSLContext _context;
+
+    private boolean _trustAll;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct an instance of SslContextFactory
+     * Default constructor for use in XmlConfiguration files
+     */
+    public SslContextFactory()
+    {
+        _trustAll=true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct an instance of SslContextFactory
+     * Default constructor for use in XmlConfiguration files
+     * @param trustAll whether to blindly trust all certificates
+     * @see #setTrustAll(boolean)
+     */
+    public SslContextFactory(boolean trustAll)
+    {
+        _trustAll=trustAll;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct an instance of SslContextFactory
+     * @param keyStorePath default keystore location
+     */
+    public SslContextFactory(String keyStorePath)
+    {
+        _keyStorePath = keyStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Create the SSLContext object and start the lifecycle
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_context == null)
+        {
+            if (_keyStore==null && _keyStoreInputStream == null && _keyStorePath == null &&
+                _trustStore==null && _trustStoreInputStream == null && _trustStorePath == null )
+            {
+                TrustManager[] trust_managers=null;
+
+                if (_trustAll)
+                {
+                    LOG.debug("No keystore or trust store configured.  ACCEPTING UNTRUSTED CERTIFICATES!!!!!");
+                    // Create a trust manager that does not validate certificate chains
+                    trust_managers = TRUST_ALL_CERTS;
+                }
+
+                SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
+                _context = SSLContext.getInstance(_sslProtocol);
+                _context.init(null, trust_managers, secureRandom);
+            }
+            else
+            {
+                // verify that keystore and truststore
+                // parameters are set up correctly
+                checkKeyStore();
+
+                KeyStore keyStore = loadKeyStore();
+                KeyStore trustStore = loadTrustStore();
+
+                Collection<? extends CRL> crls = loadCRL(_crlPath);
+
+                if (_validateCerts && keyStore != null)
+                {
+                    if (_certAlias == null)
+                    {
+                        List<String> aliases = Collections.list(keyStore.aliases());
+                        _certAlias = aliases.size() == 1 ? aliases.get(0) : null;
+                    }
+
+                    Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias);
+                    if (cert == null)
+                    {
+                        throw new Exception("No certificate found in the keystore" + (_certAlias==null ? "":" for alias " + _certAlias));
+                    }
+
+                    CertificateValidator validator = new CertificateValidator(trustStore, crls);
+                    validator.setMaxCertPathLength(_maxCertPathLength);
+                    validator.setEnableCRLDP(_enableCRLDP);
+                    validator.setEnableOCSP(_enableOCSP);
+                    validator.setOcspResponderURL(_ocspResponderURL);
+                    validator.validate(keyStore, cert);
+                }
+
+                KeyManager[] keyManagers = getKeyManagers(keyStore);
+                TrustManager[] trustManagers = getTrustManagers(trustStore,crls);
+
+                SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
+                _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider);
+                _context.init(keyManagers,trustManagers,secureRandom);
+
+                SSLEngine engine=newSslEngine();
+
+                LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols()));
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Enabled Ciphers   {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites()));
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of protocol names to exclude from
+     * {@link SSLEngine#setEnabledProtocols(String[])}
+     */
+    public String[] getExcludeProtocols()
+    {
+        return _excludeProtocols.toArray(new String[_excludeProtocols.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocols
+     *            The array of protocol names to exclude from
+     *            {@link SSLEngine#setEnabledProtocols(String[])}
+     */
+    public void setExcludeProtocols(String... protocols)
+    {
+        checkNotStarted();
+
+        _excludeProtocols.clear();
+        _excludeProtocols.addAll(Arrays.asList(protocols));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocol Protocol names to add to {@link SSLEngine#setEnabledProtocols(String[])}
+     */
+    public void addExcludeProtocols(String... protocol)
+    {
+        checkNotStarted();
+        _excludeProtocols.addAll(Arrays.asList(protocol));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of protocol names to include in
+     * {@link SSLEngine#setEnabledProtocols(String[])}
+     */
+    public String[] getIncludeProtocols()
+    {
+        return _includeProtocols.toArray(new String[_includeProtocols.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocols
+     *            The array of protocol names to include in
+     *            {@link SSLEngine#setEnabledProtocols(String[])}
+     */
+    public void setIncludeProtocols(String... protocols)
+    {
+        checkNotStarted();
+
+        _includeProtocols = new LinkedHashSet<String>(Arrays.asList(protocols));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of cipher suite names to exclude from
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     */
+    public String[] getExcludeCipherSuites()
+    {
+        return _excludeCipherSuites.toArray(new String[_excludeCipherSuites.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cipherSuites
+     *            The array of cipher suite names to exclude from
+     *            {@link SSLEngine#setEnabledCipherSuites(String[])}
+     */
+    public void setExcludeCipherSuites(String... cipherSuites)
+    {
+        checkNotStarted();
+        _excludeCipherSuites.clear();
+        _excludeCipherSuites.addAll(Arrays.asList(cipherSuites));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])}
+     */
+    public void addExcludeCipherSuites(String... cipher)
+    {
+        checkNotStarted();
+        _excludeCipherSuites.addAll(Arrays.asList(cipher));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The array of cipher suite names to include in
+     * {@link SSLEngine#setEnabledCipherSuites(String[])}
+     */
+    public String[] getIncludeCipherSuites()
+    {
+        return _includeCipherSuites.toArray(new String[_includeCipherSuites.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param cipherSuites
+     *            The array of cipher suite names to include in
+     *            {@link SSLEngine#setEnabledCipherSuites(String[])}
+     */
+    public void setIncludeCipherSuites(String... cipherSuites)
+    {
+        checkNotStarted();
+
+        _includeCipherSuites = new LinkedHashSet<String>(Arrays.asList(cipherSuites));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file or URL of the SSL Key store.
+     */
+    public String getKeyStorePath()
+    {
+        return _keyStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Deprecated
+    public String getKeyStore()
+    {
+        return _keyStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keyStorePath
+     *            The file or URL of the SSL Key store.
+     */
+    public void setKeyStorePath(String keyStorePath)
+    {
+        checkNotStarted();
+
+        _keyStorePath = keyStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keyStorePath the file system path or URL of the keystore
+     * @deprecated Use {@link #setKeyStorePath(String)}
+     */
+    @Deprecated
+    public void setKeyStore(String keyStorePath)
+    {
+        checkNotStarted();
+
+        _keyStorePath = keyStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The provider of the key store
+     */
+    public String getKeyStoreProvider()
+    {
+        return _keyStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keyStoreProvider
+     *            The provider of the key store
+     */
+    public void setKeyStoreProvider(String keyStoreProvider)
+    {
+        checkNotStarted();
+
+        _keyStoreProvider = keyStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the key store (default "JKS")
+     */
+    public String getKeyStoreType()
+    {
+        return (_keyStoreType);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param keyStoreType
+     *            The type of the key store (default "JKS")
+     */
+    public void setKeyStoreType(String keyStoreType)
+    {
+        checkNotStarted();
+
+        _keyStoreType = keyStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the _keyStoreInputStream.
+     * @return the _keyStoreInputStream
+     *
+     * @deprecated
+     */
+    @Deprecated
+    public InputStream getKeyStoreInputStream()
+    {
+        checkKeyStore();
+
+        return _keyStoreInputStream;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the keyStoreInputStream.
+     * @param keyStoreInputStream the InputStream to the KeyStore
+     *
+     * @deprecated Use {@link #setKeyStore(KeyStore)}
+     */
+    @Deprecated
+    public void setKeyStoreInputStream(InputStream keyStoreInputStream)
+    {
+        checkNotStarted();
+
+        _keyStoreInputStream = keyStoreInputStream;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Alias of SSL certificate for the connector
+     */
+    public String getCertAlias()
+    {
+        return _certAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param certAlias
+     *            Alias of SSL certificate for the connector
+     */
+    public void setCertAlias(String certAlias)
+    {
+        checkNotStarted();
+
+        _certAlias = certAlias;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The file name or URL of the trust store location
+     */
+    public String getTrustStore()
+    {
+        return _trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStorePath
+     *            The file name or URL of the trust store location
+     */
+    public void setTrustStore(String trustStorePath)
+    {
+        checkNotStarted();
+
+        _trustStorePath = trustStorePath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The provider of the trust store
+     */
+    public String getTrustStoreProvider()
+    {
+        return _trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreProvider
+     *            The provider of the trust store
+     */
+    public void setTrustStoreProvider(String trustStoreProvider)
+    {
+        checkNotStarted();
+
+        _trustStoreProvider = trustStoreProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The type of the trust store (default "JKS")
+     */
+    public String getTrustStoreType()
+    {
+        return _trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustStoreType
+     *            The type of the trust store (default "JKS")
+     */
+    public void setTrustStoreType(String trustStoreType)
+    {
+        checkNotStarted();
+
+        _trustStoreType = trustStoreType;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the _trustStoreInputStream.
+     * @return the _trustStoreInputStream
+     *
+     * @deprecated
+     */
+    @Deprecated
+    public InputStream getTrustStoreInputStream()
+    {
+        checkKeyStore();
+
+        return _trustStoreInputStream;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the _trustStoreInputStream.
+     * @param trustStoreInputStream the InputStream to the TrustStore
+     *
+     * @deprecated
+     */
+    @Deprecated
+    public void setTrustStoreInputStream(InputStream trustStoreInputStream)
+    {
+        checkNotStarted();
+
+        _trustStoreInputStream = trustStoreInputStream;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL needs client authentication.
+     * @see SSLEngine#getNeedClientAuth()
+     */
+    public boolean getNeedClientAuth()
+    {
+        return _needClientAuth;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param needClientAuth
+     *            True if SSL needs client authentication.
+     * @see SSLEngine#getNeedClientAuth()
+     */
+    public void setNeedClientAuth(boolean needClientAuth)
+    {
+        checkNotStarted();
+
+        _needClientAuth = needClientAuth;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL wants client authentication.
+     * @see SSLEngine#getWantClientAuth()
+     */
+    public boolean getWantClientAuth()
+    {
+        return _wantClientAuth;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param wantClientAuth
+     *            True if SSL wants client authentication.
+     * @see SSLEngine#getWantClientAuth()
+     */
+    public void setWantClientAuth(boolean wantClientAuth)
+    {
+        checkNotStarted();
+
+        _wantClientAuth = wantClientAuth;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if SSL certificate has to be validated
+     * @deprecated
+     */
+    @Deprecated
+    public boolean getValidateCerts()
+    {
+        return _validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if SSL certificate has to be validated
+     */
+    public boolean isValidateCerts()
+    {
+        return _validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param validateCerts
+     *            true if SSL certificates have to be validated
+     */
+    public void setValidateCerts(boolean validateCerts)
+    {
+        checkNotStarted();
+
+        _validateCerts = validateCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if SSL certificates of the peer have to be validated
+     */
+    public boolean isValidatePeerCerts()
+    {
+        return _validatePeerCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param validatePeerCerts
+     *            true if SSL certificates of the peer have to be validated
+     */
+    public void setValidatePeerCerts(boolean validatePeerCerts)
+    {
+        checkNotStarted();
+
+        _validatePeerCerts = validatePeerCerts;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if SSL re-negotiation is allowed (default false)
+     */
+    public boolean isAllowRenegotiate()
+    {
+        return _allowRenegotiate;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
+     * does not have CVE-2009-3555 fixed, then re-negotiation should
+     * not be allowed.  CVE-2009-3555 was fixed in Sun java 1.6 with a ban
+     * of renegotiates in u19 and with RFC5746 in u22.
+     *
+     * @param allowRenegotiate
+     *            true if re-negotiation is allowed (default false)
+     */
+    public void setAllowRenegotiate(boolean allowRenegotiate)
+    {
+        checkNotStarted();
+
+        _allowRenegotiate = allowRenegotiate;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password
+     *            The password for the key store
+     */
+    public void setKeyStorePassword(String password)
+    {
+        checkNotStarted();
+
+        _keyStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password
+     *            The password (if any) for the specific key within the key store
+     */
+    public void setKeyManagerPassword(String password)
+    {
+        checkNotStarted();
+
+        _keyManagerPassword = Password.getPassword(KEYPASSWORD_PROPERTY,password,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param password
+     *            The password for the trust store
+     */
+    public void setTrustStorePassword(String password)
+    {
+        checkNotStarted();
+
+        _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSL provider name, which if set is passed to
+     * {@link SSLContext#getInstance(String, String)}
+     */
+    public String getProvider()
+    {
+        return _sslProvider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param provider
+     *            The SSL provider name, which if set is passed to
+     *            {@link SSLContext#getInstance(String, String)}
+     */
+    public void setProvider(String provider)
+    {
+        checkNotStarted();
+
+        _sslProvider = provider;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSL protocol (default "TLS") passed to
+     * {@link SSLContext#getInstance(String, String)}
+     */
+    public String getProtocol()
+    {
+        return _sslProtocol;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocol
+     *            The SSL protocol (default "TLS") passed to
+     *            {@link SSLContext#getInstance(String, String)}
+     */
+    public void setProtocol(String protocol)
+    {
+        checkNotStarted();
+
+        _sslProtocol = protocol;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name, which if set is passed to
+     * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
+     * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+     */
+    public String getSecureRandomAlgorithm()
+    {
+        return _secureRandomAlgorithm;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm
+     *            The algorithm name, which if set is passed to
+     *            {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
+     *            {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+     */
+    public void setSecureRandomAlgorithm(String algorithm)
+    {
+        checkNotStarted();
+
+        _secureRandomAlgorithm = algorithm;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
+     */
+    public String getSslKeyManagerFactoryAlgorithm()
+    {
+        return (_keyManagerFactoryAlgorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm
+     *            The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
+     */
+    public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+    {
+        checkNotStarted();
+
+        _keyManagerFactoryAlgorithm = algorithm;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+     */
+    public String getTrustManagerFactoryAlgorithm()
+    {
+        return (_trustManagerFactoryAlgorithm);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if all certificates should be trusted if there is no KeyStore or TrustStore
+     */
+    public boolean isTrustAll()
+    {
+        return _trustAll;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param trustAll True if all certificates should be trusted if there is no KeyStore or TrustStore
+     */
+    public void setTrustAll(boolean trustAll)
+    {
+        _trustAll = trustAll;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param algorithm
+     *            The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+     *            Use the string "TrustAll" to install a trust manager that trusts all.
+     */
+    public void setTrustManagerFactoryAlgorithm(String algorithm)
+    {
+        checkNotStarted();
+
+        _trustManagerFactoryAlgorithm = algorithm;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Path to file that contains Certificate Revocation List
+     */
+    public String getCrlPath()
+    {
+        return _crlPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param crlPath
+     *            Path to file that contains Certificate Revocation List
+     */
+    public void setCrlPath(String crlPath)
+    {
+        checkNotStarted();
+
+        _crlPath = crlPath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Maximum number of intermediate certificates in
+     * the certification path (-1 for unlimited)
+     */
+    public int getMaxCertPathLength()
+    {
+        return _maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxCertPathLength
+     *            maximum number of intermediate certificates in
+     *            the certification path (-1 for unlimited)
+     */
+    public void setMaxCertPathLength(int maxCertPathLength)
+    {
+        checkNotStarted();
+
+        _maxCertPathLength = maxCertPathLength;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The SSLContext
+     */
+    public SSLContext getSslContext()
+    {
+        if (!isStarted())
+            throw new IllegalStateException(getState());
+        return _context;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param sslContext
+     *            Set a preconfigured SSLContext
+     */
+    public void setSslContext(SSLContext sslContext)
+    {
+        checkNotStarted();
+
+        _context = sslContext;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Override this method to provide alternate way to load a keystore.
+     *
+     * @return the key store instance
+     * @throws Exception if the keystore cannot be loaded
+     */
+    protected KeyStore loadKeyStore() throws Exception
+    {
+        return _keyStore != null ? _keyStore : getKeyStore(_keyStoreInputStream,
+                _keyStorePath, _keyStoreType, _keyStoreProvider,
+                _keyStorePassword==null? null: _keyStorePassword.toString());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Override this method to provide alternate way to load a truststore.
+     *
+     * @return the key store instance
+     * @throws Exception if the truststore cannot be loaded
+     */
+    protected KeyStore loadTrustStore() throws Exception
+    {
+        return _trustStore != null ? _trustStore : getKeyStore(_trustStoreInputStream,
+                _trustStorePath, _trustStoreType,  _trustStoreProvider,
+                _trustStorePassword==null? null: _trustStorePassword.toString());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads keystore using an input stream or a file path in the same
+     * order of precedence.
+     *
+     * Required for integrations to be able to override the mechanism
+     * used to load a keystore in order to provide their own implementation.
+     *
+     * @param storeStream keystore input stream
+     * @param storePath path of keystore file
+     * @param storeType keystore type
+     * @param storeProvider keystore provider
+     * @param storePassword keystore password
+     * @return created keystore
+     * @throws Exception if the keystore cannot be obtained
+     *
+     * @deprecated
+     */
+    @Deprecated
+    protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
+    {
+        return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Loads certificate revocation list (CRL) from a file.
+     *
+     * Required for integrations to be able to override the mechanism used to
+     * load CRL in order to provide their own implementation.
+     *
+     * @param crlPath path of certificate revocation list file
+     * @return Collection of CRL's
+     * @throws Exception if the certificate revocation list cannot be loaded
+     */
+    protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
+    {
+        return CertificateUtils.loadCRL(crlPath);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
+    {
+        KeyManager[] managers = null;
+
+        if (keyStore != null)
+        {
+            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm);
+            keyManagerFactory.init(keyStore,_keyManagerPassword == null?(_keyStorePassword == null?null:_keyStorePassword.toString().toCharArray()):_keyManagerPassword.toString().toCharArray());
+            managers = keyManagerFactory.getKeyManagers();
+
+            if (_certAlias != null)
+            {
+                for (int idx = 0; idx < managers.length; idx++)
+                {
+                    if (managers[idx] instanceof X509KeyManager)
+                    {
+                        managers[idx] = new AliasedX509ExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]);
+                    }
+                }
+            }
+        }
+
+        return managers;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
+    {
+        TrustManager[] managers = null;
+        if (trustStore != null)
+        {
+            // Revocation checking is only supported for PKIX algorithm
+            if (_validatePeerCerts && _trustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX"))
+            {
+                PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector());
+
+                // Set maximum certification path length
+                pbParams.setMaxPathLength(_maxCertPathLength);
+
+                // Make sure revocation checking is enabled
+                pbParams.setRevocationEnabled(true);
+
+                if (crls != null && !crls.isEmpty())
+                {
+                    pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls)));
+                }
+
+                if (_enableCRLDP)
+                {
+                    // Enable Certificate Revocation List Distribution Points (CRLDP) support
+                    System.setProperty("com.sun.security.enableCRLDP","true");
+                }
+
+                if (_enableOCSP)
+                {
+                    // Enable On-Line Certificate Status Protocol (OCSP) support
+                    Security.setProperty("ocsp.enable","true");
+
+                    if (_ocspResponderURL != null)
+                    {
+                        // Override location of OCSP Responder
+                        Security.setProperty("ocsp.responderURL", _ocspResponderURL);
+                    }
+                }
+
+                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
+                trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));
+
+                managers = trustManagerFactory.getTrustManagers();
+            }
+            else
+            {
+                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
+                trustManagerFactory.init(trustStore);
+
+                managers = trustManagerFactory.getTrustManagers();
+            }
+        }
+
+        return managers;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Check KeyStore Configuration. Ensures that if keystore has been
+     * configured but there's no truststore, that keystore is
+     * used as truststore.
+     * @throws IllegalStateException if SslContextFactory configuration can't be used.
+     */
+    public void checkKeyStore()
+    {
+        if (_context != null)
+            return; //nothing to check if using preconfigured context
+
+
+        if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null)
+            throw new IllegalStateException("SSL doesn't have a valid keystore");
+
+        // if the keystore has been configured but there is no
+        // truststore configured, use the keystore as the truststore
+        if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null)
+        {
+            _trustStore = _keyStore;
+            _trustStorePath = _keyStorePath;
+            _trustStoreInputStream = _keyStoreInputStream;
+            _trustStoreType = _keyStoreType;
+            _trustStoreProvider = _keyStoreProvider;
+            _trustStorePassword = _keyStorePassword;
+            _trustManagerFactoryAlgorithm = _keyManagerFactoryAlgorithm;
+        }
+
+        // It's the same stream we cannot read it twice, so read it once in memory
+        if (_keyStoreInputStream != null && _keyStoreInputStream == _trustStoreInputStream)
+        {
+            try
+            {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                IO.copy(_keyStoreInputStream, baos);
+                _keyStoreInputStream.close();
+
+                _keyStoreInputStream = new ByteArrayInputStream(baos.toByteArray());
+                _trustStoreInputStream = new ByteArrayInputStream(baos.toByteArray());
+            }
+            catch (Exception ex)
+            {
+                throw new IllegalStateException(ex);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Select protocols to be used by the connector
+     * based on configured inclusion and exclusion lists
+     * as well as enabled and supported protocols.
+     * @param enabledProtocols Array of enabled protocols
+     * @param supportedProtocols Array of supported protocols
+     * @return Array of protocols to enable
+     */
+    public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
+    {
+        Set<String> selected_protocols = new LinkedHashSet<String>();
+
+        // Set the starting protocols - either from the included or enabled list
+        if (_includeProtocols!=null)
+        {
+            // Use only the supported included protocols
+            for (String protocol : _includeProtocols)
+                if(Arrays.asList(supportedProtocols).contains(protocol))
+                    selected_protocols.add(protocol);
+        }
+        else
+            selected_protocols.addAll(Arrays.asList(enabledProtocols));
+
+
+        // Remove any excluded protocols
+        if (_excludeProtocols != null)
+            selected_protocols.removeAll(_excludeProtocols);
+
+        return selected_protocols.toArray(new String[selected_protocols.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Select cipher suites to be used by the connector
+     * based on configured inclusion and exclusion lists
+     * as well as enabled and supported cipher suite lists.
+     * @param enabledCipherSuites Array of enabled cipher suites
+     * @param supportedCipherSuites Array of supported cipher suites
+     * @return Array of cipher suites to enable
+     */
+    public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
+    {
+        Set<String> selected_ciphers = new LinkedHashSet<String>();
+
+        // Set the starting ciphers - either from the included or enabled list
+        if (_includeCipherSuites!=null)
+        {
+            // Use only the supported included ciphers
+            for (String cipherSuite : _includeCipherSuites)
+                if(Arrays.asList(supportedCipherSuites).contains(cipherSuite))
+                    selected_ciphers.add(cipherSuite);
+        }
+        else
+            selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
+
+
+        // Remove any excluded ciphers
+        if (_excludeCipherSuites != null)
+            selected_ciphers.removeAll(_excludeCipherSuites);
+        return selected_ciphers.toArray(new String[selected_ciphers.size()]);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Check if the lifecycle has been started and throw runtime exception
+     */
+    protected void checkNotStarted()
+    {
+        if (isStarted())
+            throw new IllegalStateException("Cannot modify configuration when "+getState());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if CRL Distribution Points support is enabled
+     */
+    public boolean isEnableCRLDP()
+    {
+        return _enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables CRL Distribution Points Support
+     * @param enableCRLDP true - turn on, false - turns off
+     */
+    public void setEnableCRLDP(boolean enableCRLDP)
+    {
+        checkNotStarted();
+
+        _enableCRLDP = enableCRLDP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return true if On-Line Certificate Status Protocol support is enabled
+     */
+    public boolean isEnableOCSP()
+    {
+        return _enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Enables On-Line Certificate Status Protocol support
+     * @param enableOCSP true - turn on, false - turn off
+     */
+    public void setEnableOCSP(boolean enableOCSP)
+    {
+        checkNotStarted();
+
+        _enableOCSP = enableOCSP;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Location of the OCSP Responder
+     */
+    public String getOcspResponderURL()
+    {
+        return _ocspResponderURL;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the location of the OCSP Responder.
+     * @param ocspResponderURL location of the OCSP Responder
+     */
+    public void setOcspResponderURL(String ocspResponderURL)
+    {
+        checkNotStarted();
+
+        _ocspResponderURL = ocspResponderURL;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the key store.
+     * @param keyStore the key store to set
+     */
+    public void setKeyStore(KeyStore keyStore)
+    {
+        checkNotStarted();
+
+        _keyStore = keyStore;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the trust store.
+     * @param trustStore the trust store to set
+     */
+    public void setTrustStore(KeyStore trustStore)
+    {
+        checkNotStarted();
+
+        _trustStore = trustStore;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the key store resource.
+     * @param resource the key store resource to set
+     */
+    public void setKeyStoreResource(Resource resource)
+    {
+        checkNotStarted();
+
+        try
+        {
+            _keyStoreInputStream = resource.getInputStream();
+        }
+        catch (IOException e)
+        {
+             throw new InvalidParameterException("Unable to get resource "+
+                     "input stream for resource "+resource.toString());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the trust store resource.
+     * @param resource the trust store resource to set
+     */
+    public void setTrustStoreResource(Resource resource)
+    {
+        checkNotStarted();
+
+        try
+        {
+            _trustStoreInputStream = resource.getInputStream();
+        }
+        catch (IOException e)
+        {
+             throw new InvalidParameterException("Unable to get resource "+
+                     "input stream for resource "+resource.toString());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+    * @return true if SSL Session caching is enabled
+    */
+    public boolean isSessionCachingEnabled()
+    {
+        return _sessionCachingEnabled;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the flag to enable SSL Session caching.
+    * @param enableSessionCaching the value of the flag
+    */
+    public void setSessionCachingEnabled(boolean enableSessionCaching)
+    {
+        _sessionCachingEnabled = enableSessionCaching;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get SSL session cache size.
+     * @return SSL session cache size
+     */
+    public int getSslSessionCacheSize()
+    {
+        return _sslSessionCacheSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** SEt SSL session cache size.
+     * @param sslSessionCacheSize SSL session cache size to set
+     */
+    public void setSslSessionCacheSize(int sslSessionCacheSize)
+    {
+        _sslSessionCacheSize = sslSessionCacheSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get SSL session timeout.
+     * @return SSL session timeout
+     */
+    public int getSslSessionTimeout()
+    {
+        return _sslSessionTimeout;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set SSL session timeout.
+     * @param sslSessionTimeout SSL session timeout to set
+     */
+    public void setSslSessionTimeout(int sslSessionTimeout)
+    {
+        _sslSessionTimeout = sslSessionTimeout;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public SSLServerSocket newSslServerSocket(String host,int port,int backlog) throws IOException
+    {
+        SSLServerSocketFactory factory = _context.getServerSocketFactory();
+
+        SSLServerSocket socket =
+            (SSLServerSocket) (host==null ?
+                        factory.createServerSocket(port,backlog):
+                        factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
+
+        if (getWantClientAuth())
+            socket.setWantClientAuth(getWantClientAuth());
+        if (getNeedClientAuth())
+            socket.setNeedClientAuth(getNeedClientAuth());
+
+        socket.setEnabledCipherSuites(selectCipherSuites(
+                                            socket.getEnabledCipherSuites(),
+                                            socket.getSupportedCipherSuites()));
+        socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
+
+        return socket;
+    }
+
+    /* ------------------------------------------------------------ */
+    public SSLSocket newSslSocket() throws IOException
+    {
+        SSLSocketFactory factory = _context.getSocketFactory();
+
+        SSLSocket socket = (SSLSocket)factory.createSocket();
+
+        if (getWantClientAuth())
+            socket.setWantClientAuth(getWantClientAuth());
+        if (getNeedClientAuth())
+            socket.setNeedClientAuth(getNeedClientAuth());
+
+        socket.setEnabledCipherSuites(selectCipherSuites(
+                                            socket.getEnabledCipherSuites(),
+                                            socket.getSupportedCipherSuites()));
+        socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
+
+        return socket;
+    }
+
+    /* ------------------------------------------------------------ */
+    public SSLEngine newSslEngine(String host,int port)
+    {
+        SSLEngine sslEngine=isSessionCachingEnabled()
+            ?_context.createSSLEngine(host, port)
+            :_context.createSSLEngine();
+
+        customize(sslEngine);
+        return sslEngine;
+    }
+
+    /* ------------------------------------------------------------ */
+    public SSLEngine newSslEngine()
+    {
+        SSLEngine sslEngine=_context.createSSLEngine();
+        customize(sslEngine);
+        return sslEngine;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void customize(SSLEngine sslEngine)
+    {
+        if (getWantClientAuth())
+            sslEngine.setWantClientAuth(getWantClientAuth());
+        if (getNeedClientAuth())
+            sslEngine.setNeedClientAuth(getNeedClientAuth());
+
+        sslEngine.setEnabledCipherSuites(selectCipherSuites(
+                sslEngine.getEnabledCipherSuites(),
+                sslEngine.getSupportedCipherSuites()));
+
+        sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return String.format("%s@%x(%s,%s)",
+                getClass().getSimpleName(),
+                hashCode(),
+                _keyStorePath,
+                _trustStorePath);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/statistic/CounterStatistic.java b/src/java/org/eclipse/jetty/util/statistic/CounterStatistic.java
new file mode 100644
index 0000000..24b0b93
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/statistic/CounterStatistic.java
@@ -0,0 +1,117 @@
+//
+//  ========================================================================
+//  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.util.statistic;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.eclipse.jetty.util.Atomics;
+
+
+/* ------------------------------------------------------------ */
+/** Statistics on a counter value.
+ * <p>
+ * Keep total, current and maximum values of a counter that
+ * can be incremented and decremented. The total refers only
+ * to increments.
+ *
+ */
+public class CounterStatistic
+{
+    protected final AtomicLong _max = new AtomicLong();
+    protected final AtomicLong _curr = new AtomicLong();
+    protected final AtomicLong _total = new AtomicLong();
+
+    /* ------------------------------------------------------------ */
+    public void reset()
+    {
+        reset(0);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void reset(final long value)
+    {
+        _max.set(value);
+        _curr.set(value);
+        _total.set(0); // total always set to 0 to properly calculate cumulative total
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param delta the amount to add to the count
+     */
+    public void add(final long delta)
+    {
+        long value=_curr.addAndGet(delta);
+        if (delta > 0)
+            _total.addAndGet(delta);
+        Atomics.updateMax(_max,value);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param delta the amount to subtract the count by.
+     */
+    public void subtract(final long delta)
+    {
+        add(-delta);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void increment()
+    {
+        add(1);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void decrement()
+    {
+        add(-1);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return max value
+     */
+    public long getMax()
+    {
+        return _max.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return current value
+     */
+    public long getCurrent()
+    {
+        return _curr.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return total value
+     */
+    public long getTotal()
+    {
+        return _total.get();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/statistic/SampleStatistic.java b/src/java/org/eclipse/jetty/util/statistic/SampleStatistic.java
new file mode 100644
index 0000000..abc1ed3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/statistic/SampleStatistic.java
@@ -0,0 +1,109 @@
+//
+//  ========================================================================
+//  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.util.statistic;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.eclipse.jetty.util.Atomics;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * SampledStatistics
+ * <p>
+ * Provides max, total, mean, count, variance, and standard
+ * deviation of continuous sequence of samples.
+ * <p>
+ * Calculates estimates of mean, variance, and standard deviation
+ * characteristics of a sample using a non synchronized
+ * approximation of the on-line algorithm presented
+ * in Donald Knuth's Art of Computer Programming, Volume 2,
+ * Seminumerical Algorithms, 3rd edition, page 232,
+ * Boston: Addison-Wesley. that cites a 1962 paper by B.P. Welford
+ * that can be found by following the link http://www.jstor.org/pss/1266577
+ * <p>
+ * This algorithm is also described in Wikipedia at
+ * http://en.wikipedia.org/w/index.php?title=Algorithms_for_calculating_variance&section=4#On-line_algorithm
+ */
+public class SampleStatistic
+{
+    protected final AtomicLong _max = new AtomicLong();
+    protected final AtomicLong _total = new AtomicLong();
+    protected final AtomicLong _count = new AtomicLong();
+    protected final AtomicLong _totalVariance100 = new AtomicLong();
+
+    public void reset()
+    {
+        _max.set(0);
+        _total.set(0);
+        _count.set(0);
+        _totalVariance100.set(0);
+    }
+
+    public void set(final long sample)
+    {
+        long total = _total.addAndGet(sample);
+        long count = _count.incrementAndGet();
+
+        if (count>1)
+        {
+            long mean10 = total*10/count;
+            long delta10 = sample*10 - mean10;
+            _totalVariance100.addAndGet(delta10*delta10);
+        }
+
+        Atomics.updateMax(_max, sample);
+    }
+
+    /**
+     * @return the max value
+     */
+    public long getMax()
+    {
+        return _max.get();
+    }
+
+    public long getTotal()
+    {
+        return _total.get();
+    }
+
+    public long getCount()
+    {
+        return _count.get();
+    }
+
+    public double getMean()
+    {
+        return (double)_total.get()/_count.get();
+    }
+
+    public double getVariance()
+    {
+        final long variance100 = _totalVariance100.get();
+        final long count = _count.get();
+
+        return count>1?((double)variance100)/100.0/(count-1):0.0;
+    }
+
+    public double getStdDev()
+    {
+        return Math.sqrt(getVariance());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java b/src/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java
new file mode 100644
index 0000000..6ffc8d1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java
@@ -0,0 +1,184 @@
+//
+//  ========================================================================
+//  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.util.thread;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Jetty ThreadPool using java 5 ThreadPoolExecutor
+ * This class wraps a {@link ExecutorService} as a {@link ThreadPool} and
+ * {@link LifeCycle} interfaces so that it may be used by the Jetty <code>org.eclipse.jetty.server.Server</code>
+ */
+public class ExecutorThreadPool extends AbstractLifeCycle implements ThreadPool, LifeCycle
+{
+    private static final Logger LOG = Log.getLogger(ExecutorThreadPool.class);
+    private final ExecutorService _executor;
+
+    /* ------------------------------------------------------------ */
+    public ExecutorThreadPool(ExecutorService executor)
+    {
+        _executor = executor;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Wraps an {@link ThreadPoolExecutor}.
+     * Max pool size is 256, pool thread timeout after 60 seconds and
+     * an unbounded {@link LinkedBlockingQueue} is used for the job queue;
+     */
+    public ExecutorThreadPool()
+    {
+        // Using an unbounded queue makes the maxThreads parameter useless
+        // Refer to ThreadPoolExecutor javadocs for details
+        this(new ThreadPoolExecutor(256, 256, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Wraps an {@link ThreadPoolExecutor}.
+     * Max pool size is 256, pool thread timeout after 60 seconds, and core pool size is 32 when queueSize >= 0.
+     * @param queueSize can be -1 for using an unbounded {@link LinkedBlockingQueue}, 0 for using a
+     * {@link SynchronousQueue}, greater than 0 for using a {@link ArrayBlockingQueue} of the given size.
+     */
+    public ExecutorThreadPool(int queueSize)
+    {
+        this(queueSize < 0 ? new ThreadPoolExecutor(256, 256, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()) :
+                queueSize == 0 ? new ThreadPoolExecutor(32, 256, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()) :
+                        new ThreadPoolExecutor(32, 256, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize)));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Wraps an {@link ThreadPoolExecutor} using
+     * an unbounded {@link LinkedBlockingQueue} is used for the jobs queue;
+     * @param corePoolSize must be equal to maximumPoolSize
+     * @param maximumPoolSize the maximum number of threads to allow in the pool
+     * @param keepAliveTime the max time a thread can remain idle, in milliseconds
+     */
+    public ExecutorThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime)
+    {
+        this(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Wraps an {@link ThreadPoolExecutor} using
+     * an unbounded {@link LinkedBlockingQueue} is used for the jobs queue.
+     * @param corePoolSize must be equal to maximumPoolSize
+     * @param maximumPoolSize the maximum number of threads to allow in the pool
+     * @param keepAliveTime the max time a thread can remain idle
+     * @param unit the unit for the keepAliveTime
+     */
+    public ExecutorThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit)
+    {
+        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, new LinkedBlockingQueue<Runnable>());
+    }
+
+    /* ------------------------------------------------------------ */
+
+    /**
+     * Wraps an {@link ThreadPoolExecutor}
+     * @param corePoolSize the number of threads to keep in the pool, even if they are idle
+     * @param maximumPoolSize the maximum number of threads to allow in the pool
+     * @param keepAliveTime the max time a thread can remain idle
+     * @param unit the unit for the keepAliveTime
+     * @param workQueue the queue to use for holding tasks before they are executed
+     */
+    public ExecutorThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
+    {
+        this(new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue));
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean dispatch(Runnable job)
+    {
+        try
+        {
+            _executor.execute(job);
+            return true;
+        }
+        catch(RejectedExecutionException e)
+        {
+            LOG.warn(e);
+            return false;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getIdleThreads()
+    {
+        if (_executor instanceof ThreadPoolExecutor)
+        {
+            final ThreadPoolExecutor tpe = (ThreadPoolExecutor)_executor;
+            return tpe.getPoolSize() - tpe.getActiveCount();
+        }
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getThreads()
+    {
+        if (_executor instanceof ThreadPoolExecutor)
+        {
+            final ThreadPoolExecutor tpe = (ThreadPoolExecutor)_executor;
+            return tpe.getPoolSize();
+        }
+        return -1;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isLowOnThreads()
+    {
+        if (_executor instanceof ThreadPoolExecutor)
+        {
+            final ThreadPoolExecutor tpe = (ThreadPoolExecutor)_executor;
+            // getActiveCount() locks the thread pool, so execute it last
+            return tpe.getPoolSize() == tpe.getMaximumPoolSize() &&
+                    tpe.getQueue().size() >= tpe.getPoolSize() - tpe.getActiveCount();
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void join() throws InterruptedException
+    {
+        _executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        _executor.shutdownNow();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/src/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
new file mode 100644
index 0000000..da53c03
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
@@ -0,0 +1,678 @@
+//
+//  ========================================================================
+//  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.util.thread;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.eclipse.jetty.util.BlockingArrayQueue;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool;
+
+public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPool, Executor, Dumpable
+{
+    private static final Logger LOG = Log.getLogger(QueuedThreadPool.class);
+
+    private final AtomicInteger _threadsStarted = new AtomicInteger();
+    private final AtomicInteger _threadsIdle = new AtomicInteger();
+    private final AtomicLong _lastShrink = new AtomicLong();
+    private final ConcurrentLinkedQueue<Thread> _threads=new ConcurrentLinkedQueue<Thread>();
+    private final Object _joinLock = new Object();
+    private BlockingQueue<Runnable> _jobs;
+    private String _name;
+    private int _maxIdleTimeMs=60000;
+    private int _maxThreads=254;
+    private int _minThreads=8;
+    private int _maxQueued=-1;
+    private int _priority=Thread.NORM_PRIORITY;
+    private boolean _daemon=false;
+    private int _maxStopTime=100;
+    private boolean _detailedDump=false;
+
+    /* ------------------------------------------------------------------- */
+    /** Construct
+     */
+    public QueuedThreadPool()
+    {
+        _name="qtp"+super.hashCode();
+    }
+
+    /* ------------------------------------------------------------------- */
+    /** Construct
+     */
+    public QueuedThreadPool(int maxThreads)
+    {
+        this();
+        setMaxThreads(maxThreads);
+    }
+
+    /* ------------------------------------------------------------------- */
+    /** Construct
+     */
+    public QueuedThreadPool(BlockingQueue<Runnable> jobQ)
+    {
+        this();
+        _jobs=jobQ;
+        _jobs.clear();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStart() throws Exception
+    {
+        super.doStart();
+        _threadsStarted.set(0);
+
+        if (_jobs==null)
+        {
+            _jobs=_maxQueued>0 ?new ArrayBlockingQueue<Runnable>(_maxQueued)
+                :new BlockingArrayQueue<Runnable>(_minThreads,_minThreads);
+        }
+
+        int threads=_threadsStarted.get();
+        while (isRunning() && threads<_minThreads)
+        {
+            startThread(threads);
+            threads=_threadsStarted.get();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+        long start=System.currentTimeMillis();
+
+        // let jobs complete naturally for a while
+        while (_threadsStarted.get()>0 && (System.currentTimeMillis()-start) < (_maxStopTime/2))
+            Thread.sleep(1);
+
+        // kill queued jobs and flush out idle jobs
+        _jobs.clear();
+        Runnable noop = new Runnable(){public void run(){}};
+        for  (int i=_threadsIdle.get();i-->0;)
+            _jobs.offer(noop);
+        Thread.yield();
+
+        // interrupt remaining threads
+        if (_threadsStarted.get()>0)
+            for (Thread thread : _threads)
+                thread.interrupt();
+
+        // wait for remaining threads to die
+        while (_threadsStarted.get()>0 && (System.currentTimeMillis()-start) < _maxStopTime)
+        {
+            Thread.sleep(1);
+        }
+        Thread.yield();
+        int size=_threads.size();
+        if (size>0)
+        {
+            LOG.warn(size+" threads could not be stopped");
+
+            if (size==1 || LOG.isDebugEnabled())
+            {
+                for (Thread unstopped : _threads)
+                {
+                    LOG.info("Couldn't stop "+unstopped);
+                    for (StackTraceElement element : unstopped.getStackTrace())
+                    {
+                        LOG.info(" at "+element);
+                    }
+                }
+            }
+        }
+
+        synchronized (_joinLock)
+        {
+            _joinLock.notifyAll();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Delegated to the named or anonymous Pool.
+     */
+    public void setDaemon(boolean daemon)
+    {
+        _daemon=daemon;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the maximum thread idle time.
+     * Threads that are idle for longer than this period may be
+     * stopped.
+     * Delegated to the named or anonymous Pool.
+     * @see #getMaxIdleTimeMs
+     * @param maxIdleTimeMs Max idle time in ms.
+     */
+    public void setMaxIdleTimeMs(int maxIdleTimeMs)
+    {
+        _maxIdleTimeMs=maxIdleTimeMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param stopTimeMs maximum total time that stop() will wait for threads to die.
+     */
+    public void setMaxStopTimeMs(int stopTimeMs)
+    {
+        _maxStopTime = stopTimeMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the maximum number of threads.
+     * Delegated to the named or anonymous Pool.
+     * @see #getMaxThreads
+     * @param maxThreads maximum number of threads.
+     */
+    public void setMaxThreads(int maxThreads)
+    {
+        _maxThreads=maxThreads;
+        if (_minThreads>_maxThreads)
+            _minThreads=_maxThreads;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the minimum number of threads.
+     * Delegated to the named or anonymous Pool.
+     * @see #getMinThreads
+     * @param minThreads minimum number of threads
+     */
+    public void setMinThreads(int minThreads)
+    {
+        _minThreads=minThreads;
+
+        if (_minThreads>_maxThreads)
+            _maxThreads=_minThreads;
+
+        int threads=_threadsStarted.get();
+        while (isStarted() && threads<_minThreads)
+        {
+            startThread(threads);
+            threads=_threadsStarted.get();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name Name of the BoundedThreadPool to use when naming Threads.
+     */
+    public void setName(String name)
+    {
+        if (isRunning())
+            throw new IllegalStateException("started");
+        _name= name;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the priority of the pool threads.
+     *  @param priority the new thread priority.
+     */
+    public void setThreadsPriority(int priority)
+    {
+        _priority=priority;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return maximum queue size
+     */
+    public int getMaxQueued()
+    {
+        return _maxQueued;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param max job queue size
+     */
+    public void setMaxQueued(int max)
+    {
+        if (isRunning())
+            throw new IllegalStateException("started");
+        _maxQueued=max;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the maximum thread idle time.
+     * Delegated to the named or anonymous Pool.
+     * @see #setMaxIdleTimeMs
+     * @return Max idle time in ms.
+     */
+    public int getMaxIdleTimeMs()
+    {
+        return _maxIdleTimeMs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return maximum total time that stop() will wait for threads to die.
+     */
+    public int getMaxStopTimeMs()
+    {
+        return _maxStopTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the maximum number of threads.
+     * Delegated to the named or anonymous Pool.
+     * @see #setMaxThreads
+     * @return maximum number of threads.
+     */
+    public int getMaxThreads()
+    {
+        return _maxThreads;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the minimum number of threads.
+     * Delegated to the named or anonymous Pool.
+     * @see #setMinThreads
+     * @return minimum number of threads.
+     */
+    public int getMinThreads()
+    {
+        return _minThreads;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The name of the BoundedThreadPool.
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get the priority of the pool threads.
+     *  @return the priority of the pool threads.
+     */
+    public int getThreadsPriority()
+    {
+        return _priority;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Delegated to the named or anonymous Pool.
+     */
+    public boolean isDaemon()
+    {
+        return _daemon;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isDetailedDump()
+    {
+        return _detailedDump;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setDetailedDump(boolean detailedDump)
+    {
+        _detailedDump = detailedDump;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean dispatch(Runnable job)
+    {
+        if (isRunning())
+        {
+            final int jobQ = _jobs.size();
+            final int idle = getIdleThreads();
+            if(_jobs.offer(job))
+            {
+                // If we had no idle threads or the jobQ is greater than the idle threads
+                if (idle==0 || jobQ>idle)
+                {
+                    int threads=_threadsStarted.get();
+                    if (threads<_maxThreads)
+                        startThread(threads);
+                }
+                return true;
+            }
+        }
+        LOG.debug("Dispatched {} to stopped {}",job,this);
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void execute(Runnable job)
+    {
+        if (!dispatch(job))
+            throw new RejectedExecutionException();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Blocks until the thread pool is {@link LifeCycle#stop stopped}.
+     */
+    public void join() throws InterruptedException
+    {
+        synchronized (_joinLock)
+        {
+            while (isRunning())
+                _joinLock.wait();
+        }
+
+        while (isStopping())
+            Thread.sleep(1);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The total number of threads currently in the pool
+     */
+    public int getThreads()
+    {
+        return _threadsStarted.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The number of idle threads in the pool
+     */
+    public int getIdleThreads()
+    {
+        return _threadsIdle.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the pool is at maxThreads and there are not more idle threads than queued jobs
+     */
+    public boolean isLowOnThreads()
+    {
+        return _threadsStarted.get()==_maxThreads && _jobs.size()>=_threadsIdle.get();
+    }
+
+    /* ------------------------------------------------------------ */
+    private boolean startThread(int threads)
+    {
+        final int next=threads+1;
+        if (!_threadsStarted.compareAndSet(threads,next))
+            return false;
+
+        boolean started=false;
+        try
+        {
+            Thread thread=newThread(_runnable);
+            thread.setDaemon(_daemon);
+            thread.setPriority(_priority);
+            thread.setName(_name+"-"+thread.getId());
+            _threads.add(thread);
+
+            thread.start();
+            started=true;
+        }
+        finally
+        {
+            if (!started)
+                _threadsStarted.decrementAndGet();
+        }
+        return started;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected Thread newThread(Runnable runnable)
+    {
+        return new Thread(runnable);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public String dump()
+    {
+        return AggregateLifeCycle.dump(this);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void dump(Appendable out, String indent) throws IOException
+    {
+        List<Object> dump = new ArrayList<Object>(getMaxThreads());
+        for (final Thread thread: _threads)
+        {
+            final StackTraceElement[] trace=thread.getStackTrace();
+            boolean inIdleJobPoll=false;
+            // trace can be null on early java 6 jvms
+            if (trace != null)
+            {
+                for (StackTraceElement t : trace)
+                {
+                    if ("idleJobPoll".equals(t.getMethodName()))
+                    {
+                        inIdleJobPoll = true;
+                        break;
+                    }
+                }
+            }
+            final boolean idle=inIdleJobPoll;
+
+            if (_detailedDump)
+            {
+                dump.add(new Dumpable()
+                {
+                    public void dump(Appendable out, String indent) throws IOException
+                    {
+                        out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle?" IDLE":"").append('\n');
+                        if (!idle)
+                            AggregateLifeCycle.dump(out,indent,Arrays.asList(trace));
+                    }
+
+                    public String dump()
+                    {
+                        return null;
+                    }
+                });
+            }
+            else
+            {
+                dump.add(thread.getId()+" "+thread.getName()+" "+thread.getState()+" @ "+(trace.length>0?trace[0]:"???")+(idle?" IDLE":""));
+            }
+        }
+
+        AggregateLifeCycle.dumpObject(out,this);
+        AggregateLifeCycle.dump(out,indent,dump);
+
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}";
+    }
+
+    /* ------------------------------------------------------------ */
+    private Runnable idleJobPoll() throws InterruptedException
+    {
+        return _jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS);
+    }
+
+    /* ------------------------------------------------------------ */
+    private Runnable _runnable = new Runnable()
+    {
+        public void run()
+        {
+            boolean shrink=false;
+            try
+            {
+                Runnable job=_jobs.poll();
+                while (isRunning())
+                {
+                    // Job loop
+                    while (job!=null && isRunning())
+                    {
+                        runJob(job);
+                        job=_jobs.poll();
+                    }
+
+                    // Idle loop
+                    try
+                    {
+                        _threadsIdle.incrementAndGet();
+
+                        while (isRunning() && job==null)
+                        {
+                            if (_maxIdleTimeMs<=0)
+                                job=_jobs.take();
+                            else
+                            {
+                                // maybe we should shrink?
+                                final int size=_threadsStarted.get();
+                                if (size>_minThreads)
+                                {
+                                    long last=_lastShrink.get();
+                                    long now=System.currentTimeMillis();
+                                    if (last==0 || (now-last)>_maxIdleTimeMs)
+                                    {
+                                        shrink=_lastShrink.compareAndSet(last,now) &&
+                                        _threadsStarted.compareAndSet(size,size-1);
+                                        if (shrink)
+                                            return;
+                                    }
+                                }
+                                job=idleJobPoll();
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        _threadsIdle.decrementAndGet();
+                    }
+                }
+            }
+            catch(InterruptedException e)
+            {
+                LOG.ignore(e);
+            }
+            catch(Exception e)
+            {
+                LOG.warn(e);
+            }
+            finally
+            {
+                if (!shrink)
+                    _threadsStarted.decrementAndGet();
+                _threads.remove(Thread.currentThread());
+            }
+        }
+    };
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Runs the given job in the {@link Thread#currentThread() current thread}.</p>
+     * <p>Subclasses may override to perform pre/post actions before/after the job is run.</p>
+     *
+     * @param job the job to run
+     */
+    protected void runJob(Runnable job)
+    {
+        job.run();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the job queue
+     */
+    protected BlockingQueue<Runnable> getQueue()
+    {
+        return _jobs;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param id The thread ID to stop.
+     * @return true if the thread was found and stopped.
+     * @deprecated Use {@link #interruptThread(long)} in preference
+     */
+    @Deprecated
+    public boolean stopThread(long id)
+    {
+        for (Thread thread: _threads)
+        {
+            if (thread.getId()==id)
+            {
+                thread.stop();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param id The thread ID to interrupt.
+     * @return true if the thread was found and interrupted.
+     */
+    public boolean interruptThread(long id)
+    {
+        for (Thread thread: _threads)
+        {
+            if (thread.getId()==id)
+            {
+                thread.interrupt();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param id The thread ID to interrupt.
+     * @return true if the thread was found and interrupted.
+     */
+    public String dumpThread(long id)
+    {
+        for (Thread thread: _threads)
+        {
+            if (thread.getId()==id)
+            {
+                StringBuilder buf = new StringBuilder();
+                buf.append(thread.getId()).append(" ").append(thread.getName()).append(" ").append(thread.getState()).append(":\n");
+                for (StackTraceElement element : thread.getStackTrace())
+                    buf.append("  at ").append(element.toString()).append('\n');
+                return buf.toString();
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/thread/ShutdownThread.java b/src/java/org/eclipse/jetty/util/thread/ShutdownThread.java
new file mode 100644
index 0000000..168b444
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/thread/ShutdownThread.java
@@ -0,0 +1,148 @@
+//
+//  ========================================================================
+//  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.util.thread;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.jetty.util.component.Destroyable;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * ShutdownThread is a shutdown hook thread implemented as 
+ * singleton that maintains a list of lifecycle instances
+ * that are registered with it and provides ability to stop
+ * these lifecycles upon shutdown of the Java Virtual Machine 
+ */
+public class ShutdownThread extends Thread
+{
+    private static final Logger LOG = Log.getLogger(ShutdownThread.class);
+    private static final ShutdownThread _thread = new ShutdownThread();
+
+    private boolean _hooked;
+    private final List<LifeCycle> _lifeCycles = new CopyOnWriteArrayList<LifeCycle>();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Default constructor for the singleton
+     * 
+     * Registers the instance as shutdown hook with the Java Runtime
+     */
+    private ShutdownThread()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    private synchronized void hook()
+    {
+        try
+        {
+            if (!_hooked)
+                Runtime.getRuntime().addShutdownHook(this);
+            _hooked=true;
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+            LOG.info("shutdown already commenced");
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    private synchronized void unhook()
+    {
+        try
+        {
+            _hooked=false;
+            Runtime.getRuntime().removeShutdownHook(this);
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+            LOG.debug("shutdown already commenced");
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Returns the instance of the singleton
+     * 
+     * @return the singleton instance of the {@link ShutdownThread}
+     */
+    public static ShutdownThread getInstance()
+    {
+        return _thread;
+    }
+
+    /* ------------------------------------------------------------ */
+    public static synchronized void register(LifeCycle... lifeCycles)
+    {
+        _thread._lifeCycles.addAll(Arrays.asList(lifeCycles));
+        if (_thread._lifeCycles.size()>0)
+            _thread.hook();
+    }
+
+    /* ------------------------------------------------------------ */
+    public static synchronized void register(int index, LifeCycle... lifeCycles)
+    {
+        _thread._lifeCycles.addAll(index,Arrays.asList(lifeCycles));
+        if (_thread._lifeCycles.size()>0)
+            _thread.hook();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public static synchronized void deregister(LifeCycle lifeCycle)
+    {
+        _thread._lifeCycles.remove(lifeCycle);
+        if (_thread._lifeCycles.size()==0)
+            _thread.unhook();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void run()
+    {
+        for (LifeCycle lifeCycle : _thread._lifeCycles)
+        {
+            try
+            {
+                if (lifeCycle.isStarted())
+                {
+                    lifeCycle.stop();
+                    LOG.debug("Stopped {}",lifeCycle);
+                }
+                
+                if (lifeCycle instanceof Destroyable)
+                {
+                    ((Destroyable)lifeCycle).destroy();
+                    LOG.debug("Destroyed {}",lifeCycle);
+                }
+            }
+            catch (Exception ex)
+            {
+                LOG.debug(ex);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/thread/ThreadPool.java b/src/java/org/eclipse/jetty/util/thread/ThreadPool.java
new file mode 100644
index 0000000..99562cc
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/thread/ThreadPool.java
@@ -0,0 +1,67 @@
+//
+//  ========================================================================
+//  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.util.thread;
+
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/* ------------------------------------------------------------ */
+/** ThreadPool.
+ * 
+ *
+ */
+public interface ThreadPool
+{
+    /* ------------------------------------------------------------ */
+    public abstract boolean dispatch(Runnable job);
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Blocks until the thread pool is {@link LifeCycle#stop stopped}.
+     */
+    public void join() throws InterruptedException;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The total number of threads currently in the pool
+     */
+    public int getThreads();
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The number of idle threads in the pool
+     */
+    public int getIdleThreads();
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the pool is low on threads
+     */
+    public boolean isLowOnThreads();
+    
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public interface SizedThreadPool extends ThreadPool
+    {
+        public int getMinThreads();
+        public int getMaxThreads();
+        public void setMinThreads(int threads);
+        public void setMaxThreads(int threads);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/util/thread/Timeout.java b/src/java/org/eclipse/jetty/util/thread/Timeout.java
new file mode 100644
index 0000000..6fabbdd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/util/thread/Timeout.java
@@ -0,0 +1,380 @@
+//
+//  ========================================================================
+//  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.util.thread;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/** Timeout queue.
+ * This class implements a timeout queue for timers that are at least as likely to be cancelled as they are to expire.
+ * Unlike the util timeout class, the duration of the timeouts is shared by all scheduled tasks and if the duration 
+ * is changed, this affects all scheduled tasks.
+ * <p>
+ * The nested class Task should be extended by users of this class to obtain call back notification of 
+ * expires. 
+ */
+public class Timeout
+{
+    private static final Logger LOG = Log.getLogger(Timeout.class);
+    private Object _lock;
+    private long _duration;
+    private volatile long _now=System.currentTimeMillis();
+    private Task _head=new Task();
+
+    /* ------------------------------------------------------------ */
+    public Timeout()
+    {
+        _lock=new Object();
+        _head._timeout=this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Timeout(Object lock)
+    {
+        _lock=lock;
+        _head._timeout=this;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the duration.
+     */
+    public long getDuration()
+    {
+        return _duration;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param duration The duration to set.
+     */
+    public void setDuration(long duration)
+    {
+        _duration = duration;
+    }
+
+    /* ------------------------------------------------------------ */
+    public long setNow()
+    {
+        return _now=System.currentTimeMillis();
+    }
+    
+    /* ------------------------------------------------------------ */
+    public long getNow()
+    {
+        return _now;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setNow(long now)
+    {
+        _now=now;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get an expired tasks.
+     * This is called instead of {@link #tick()} to obtain the next
+     * expired Task, but without calling it's {@link Task#expire()} or
+     * {@link Task#expired()} methods.
+     * 
+     * @return the next expired task or null.
+     */
+    public Task expired()
+    {
+        synchronized (_lock)
+        {
+            long _expiry = _now-_duration;
+
+            if (_head._next!=_head)
+            {
+                Task task = _head._next;
+                if (task._timestamp>_expiry)
+                    return null;
+
+                task.unlink();
+                task._expired=true;
+                return task;
+            }
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void tick()
+    {
+        final long expiry = _now-_duration;
+
+        Task task=null;
+        while (true)
+        {
+            try
+            {
+                synchronized (_lock)
+                {
+                    task= _head._next;
+                    if (task==_head || task._timestamp>expiry)
+                        break;
+                    task.unlink();
+                    task._expired=true;
+                    task.expire();
+                }
+                
+                task.expired();
+            }
+            catch(Throwable th)
+            {
+                LOG.warn(Log.EXCEPTION,th);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void tick(long now)
+    {
+        _now=now;
+        tick();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void schedule(Task task)
+    {
+        schedule(task,0L);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param task
+     * @param delay A delay in addition to the default duration of the timeout
+     */
+    public void schedule(Task task,long delay)
+    {
+        synchronized (_lock)
+        {
+            if (task._timestamp!=0)
+            {
+                task.unlink();
+                task._timestamp=0;
+            }
+            task._timeout=this;
+            task._expired=false;
+            task._delay=delay;
+            task._timestamp = _now+delay;
+
+            Task last=_head._prev;
+            while (last!=_head)
+            {
+                if (last._timestamp <= task._timestamp)
+                    break;
+                last=last._prev;
+            }
+            last.link(task);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void cancelAll()
+    {
+        synchronized (_lock)
+        {
+            _head._next=_head._prev=_head;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isEmpty()
+    {
+        synchronized (_lock)
+        {
+            return _head._next==_head;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public long getTimeToNext()
+    {
+        synchronized (_lock)
+        {
+            if (_head._next==_head)
+                return -1;
+            long to_next = _duration+_head._next._timestamp-_now;
+            return to_next<0?0:to_next;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append(super.toString());
+        
+        Task task = _head._next;
+        while (task!=_head)
+        {
+            buf.append("-->");
+            buf.append(task);
+            task=task._next;
+        }
+        
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /** Task.
+     * The base class for scheduled timeouts.  This class should be
+     * extended to implement the expire() method, which is called if the
+     * timeout expires.
+     * 
+     * 
+     *
+     */
+    public static class Task
+    {
+        Task _next;
+        Task _prev;
+        Timeout _timeout;
+        long _delay;
+        long _timestamp=0;
+        boolean _expired=false;
+
+        /* ------------------------------------------------------------ */
+        protected Task()
+        {
+            _next=_prev=this;
+        }
+
+        /* ------------------------------------------------------------ */
+        public long getTimestamp()
+        {
+            return _timestamp;
+        }
+
+        /* ------------------------------------------------------------ */
+        public long getAge()
+        {
+            final Timeout t = _timeout;
+            if (t!=null)
+            {
+                final long now=t._now;
+                if (now!=0 && _timestamp!=0)
+                    return now-_timestamp;
+            }
+            return 0;
+        }
+
+        /* ------------------------------------------------------------ */
+        private void unlink()
+        {
+            _next._prev=_prev;
+            _prev._next=_next;
+            _next=_prev=this;
+            _expired=false;
+        }
+
+        /* ------------------------------------------------------------ */
+        private void link(Task task)
+        {
+            Task next_next = _next;
+            _next._prev=task;
+            _next=task;
+            _next._next=next_next;
+            _next._prev=this;   
+        }
+        
+        /* ------------------------------------------------------------ */
+        /** Schedule the task on the given timeout.
+         * The task exiry will be called after the timeout duration.
+         * @param timer
+         */
+        public void schedule(Timeout timer)
+        {
+            timer.schedule(this);
+        }
+        
+        /* ------------------------------------------------------------ */
+        /** Schedule the task on the given timeout.
+         * The task exiry will be called after the timeout duration.
+         * @param timer
+         */
+        public void schedule(Timeout timer, long delay)
+        {
+            timer.schedule(this,delay);
+        }
+        
+        /* ------------------------------------------------------------ */
+        /** Reschedule the task on the current timeout.
+         * The task timeout is rescheduled as if it had been cancelled and
+         * scheduled on the current timeout.
+         */
+        public void reschedule()
+        {
+            Timeout timeout = _timeout;
+            if (timeout!=null)
+                timeout.schedule(this,_delay);
+        }
+        
+        /* ------------------------------------------------------------ */
+        /** Cancel the task.
+         * Remove the task from the timeout.
+         */
+        public void cancel()
+        {
+            Timeout timeout = _timeout;
+            if (timeout!=null)
+            {
+                synchronized (timeout._lock)
+                {
+                    unlink();
+                    _timestamp=0;
+                }
+            }
+        }
+        
+        /* ------------------------------------------------------------ */
+        public boolean isExpired() { return _expired; }
+
+        /* ------------------------------------------------------------ */
+	public boolean isScheduled() { return _next!=this; }
+        
+        /* ------------------------------------------------------------ */
+        /** Expire task.
+         * This method is called when the timeout expires. It is called
+         * in the scope of the synchronize block (on this) that sets 
+         * the {@link #isExpired()} state to true.
+         * @see #expired() For an unsynchronized callback.
+         */
+        protected void expire(){}
+
+        /* ------------------------------------------------------------ */
+        /** Expire task.
+         * This method is called when the timeout expires. It is called 
+         * outside of any synchronization scope and may be delayed. 
+         * 
+         */
+        public void expired(){}
+
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/webapp/AbstractConfiguration.java b/src/java/org/eclipse/jetty/webapp/AbstractConfiguration.java
new file mode 100644
index 0000000..3815aa2
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/AbstractConfiguration.java
@@ -0,0 +1,46 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+public class AbstractConfiguration implements Configuration
+{
+    public void preConfigure(WebAppContext context) throws Exception
+    {
+    }
+
+    public void configure(WebAppContext context) throws Exception
+    {
+    }
+
+    public void postConfigure(WebAppContext context) throws Exception
+    {
+    }
+
+    public void deconfigure(WebAppContext context) throws Exception
+    {
+    }
+
+    public void destroy(WebAppContext context) throws Exception
+    {
+    }
+
+    public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
+    {
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/ClasspathPattern.java b/src/java/org/eclipse/jetty/webapp/ClasspathPattern.java
new file mode 100644
index 0000000..c66a540
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/ClasspathPattern.java
@@ -0,0 +1,230 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * ClasspathPattern performs sequential pattern matching of a class name 
+ * against an internal array of classpath pattern entries.
+ * 
+ * When an entry starts with '-' (minus), reverse matching is performed.
+ * When an entry ends with '.' (period), prefix matching is performed.
+ * 
+ * When class is initialized from a classpath pattern string, entries 
+ * in this string should be separated by ':' (semicolon) or ',' (comma).
+ */
+
+public class ClasspathPattern
+{
+    private static class Entry
+    {
+        public String classpath = null;
+        public boolean result = false;
+        public boolean partial = false;      
+    }
+    
+    final private List<String> _patterns = new ArrayList<String>();
+    final private List<Entry> _entries = new ArrayList<Entry>();
+    
+    /* ------------------------------------------------------------ */
+    public ClasspathPattern()
+    {
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ClasspathPattern(String[] patterns)
+    {
+        setPatterns(patterns);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public ClasspathPattern(String pattern)
+    {
+        setPattern(pattern);
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Initialize the matcher by parsing each classpath pattern in an array
+     * 
+     * @param patterns array of classpath patterns
+     */
+    private void setPatterns(String[] patterns)
+    {
+        _patterns.clear();
+        _entries.clear();
+        addPatterns(patterns);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Initialize the matcher by parsing each classpath pattern in an array
+     * 
+     * @param patterns array of classpath patterns
+     */
+    private void addPatterns(String[] patterns)
+    {
+        if (patterns != null)
+        {
+            Entry entry = null; 
+            for (String pattern : patterns)
+            {
+                entry = createEntry(pattern);
+                if (entry != null) {
+                    _patterns.add(pattern);
+                    _entries.add(entry);
+                }
+            }
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Create an entry object containing information about 
+     * a single classpath pattern
+     * 
+     * @param pattern single classpath pattern
+     * @return corresponding Entry object
+     */
+    private Entry createEntry(String pattern)
+    {
+        Entry entry = null;
+        
+        if (pattern != null)
+        {
+            String item = pattern.trim();
+            if (item.length() > 0)
+            {
+                entry = new Entry();
+                entry.result = !item.startsWith("-");
+                entry.partial = item.endsWith(".");
+                entry.classpath = entry.result ? item : item.substring(1).trim();
+            }
+        }
+        return entry;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Initialize the matcher by parsing a classpath pattern string
+     * 
+     * @param pattern classpath pattern string
+     */
+    public void setPattern(String pattern)
+    {
+        _patterns.clear();
+        _entries.clear();
+        addPattern(pattern);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Parse a classpath pattern string and appending the result
+     * to the existing configuration.
+     * 
+     * @param pattern classpath pattern string
+     */
+    public void addPattern(String pattern)
+    {
+        ArrayList<String> patterns = new ArrayList<String>();
+        StringTokenizer entries = new StringTokenizer(pattern, ":,");
+        while (entries.hasMoreTokens())
+        {
+            patterns.add(entries.nextToken());
+        }
+        
+        addPatterns((String[])patterns.toArray(new String[patterns.size()]));
+    }   
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return array of classpath patterns
+     */
+    public String[] getPatterns()
+    {
+        String[] patterns = null;
+        
+        if (_patterns!=null && _patterns.size() > 0)
+        {
+            patterns = _patterns.toArray(new String[_patterns.size()]);
+        }
+        
+        return patterns;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Match the class name against the pattern
+     *
+     * @param name name of the class to match
+     * @return true if class matches the pattern
+     */
+    public boolean match(String name)
+    {       
+        boolean result=false;
+
+        if (_entries != null)
+        {
+            name = name.replace('/','.');
+
+            int startIndex = 0;
+
+            while(startIndex < name.length() && name.charAt(startIndex) == '.') {
+                startIndex++;
+            }
+
+            int dollar = name.indexOf("$");
+
+            int endIndex =  dollar != -1 ? dollar : name.length();
+
+            for (Entry entry : _entries)
+            {
+                if (entry != null)
+                {               
+                    if (entry.partial)
+                    {
+                        if (name.regionMatches(startIndex, entry.classpath, 0, entry.classpath.length()))
+                        {
+                            result = entry.result;
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        int regionLength = endIndex-startIndex;
+                        if (regionLength == entry.classpath.length()
+                                && name.regionMatches(startIndex, entry.classpath, 0, regionLength))
+                        {
+                            result = entry.result;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/CloneConfiguration.java b/src/java/org/eclipse/jetty/webapp/CloneConfiguration.java
new file mode 100644
index 0000000..159d17f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/CloneConfiguration.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+public class CloneConfiguration extends AbstractConfiguration
+{
+    final WebAppContext _template;
+    
+    CloneConfiguration(WebAppContext template)
+    {
+        _template=template;
+    }
+    
+    @Override
+    public void configure(WebAppContext context) throws Exception
+    {
+        for (Configuration configuration : _template.getConfigurations())
+            configuration.cloneConfigure(_template,context);
+    }
+
+
+    @Override
+    public void deconfigure(WebAppContext context) throws Exception
+    {
+        for (Configuration configuration : _template.getConfigurations())
+            configuration.deconfigure(context);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/Configuration.java b/src/java/org/eclipse/jetty/webapp/Configuration.java
new file mode 100644
index 0000000..85bee74
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/Configuration.java
@@ -0,0 +1,87 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+
+/* ------------------------------------------------------------------------------- */
+/** Base Class for WebApplicationContext Configuration.
+ * This class can be extended to customize or extend the configuration
+ * of the WebApplicationContext. 
+ */
+public interface Configuration 
+{
+
+    /* ------------------------------------------------------------------------------- */
+    /** Set up for configuration.
+     * <p>
+     * Typically this step discovers configuration resources
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void preConfigure (WebAppContext context) throws Exception;
+    
+    
+    /* ------------------------------------------------------------------------------- */
+    /** Configure WebApp.
+     * <p>
+     * Typically this step applies the discovered configuration resources to
+     * either the {@link WebAppContext} or the associated {@link MetaData}.
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void configure (WebAppContext context) throws Exception;
+    
+    
+    /* ------------------------------------------------------------------------------- */
+    /** Clear down after configuration.
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void postConfigure (WebAppContext context) throws Exception;
+    
+    /* ------------------------------------------------------------------------------- */
+    /** DeConfigure WebApp.
+     * This method is called to undo all configuration done. This is
+     * called to allow the context to work correctly over a stop/start cycle
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void deconfigure (WebAppContext context) throws Exception;
+
+    /* ------------------------------------------------------------------------------- */
+    /** Destroy WebApp.
+     * This method is called to destroy a webappcontext. It is typically called when a context 
+     * is removed from a server handler hierarchy by the deployer.
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void destroy (WebAppContext context) throws Exception;
+    
+
+    /* ------------------------------------------------------------------------------- */
+    /** Clone configuration instance.
+     * <p>
+     * Configure an instance of a WebAppContext, based on a template WebAppContext that 
+     * has previously been configured by this Configuration.
+     * @param template The template context
+     * @param context The context to configure
+     * @throws Exception
+     */
+    public void cloneConfigure (WebAppContext template, WebAppContext context) throws Exception;
+}
diff --git a/src/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java b/src/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java
new file mode 100644
index 0000000..64a0653
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/DefaultsDescriptor.java
@@ -0,0 +1,33 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * DefaultsDescriptor
+ *
+ */
+public class DefaultsDescriptor extends WebDescriptor
+{
+    public DefaultsDescriptor(Resource xml)
+    {
+        super(xml);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/Descriptor.java b/src/java/org/eclipse/jetty/webapp/Descriptor.java
new file mode 100644
index 0000000..52ab6ce
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/Descriptor.java
@@ -0,0 +1,88 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.net.URL;
+
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlParser;
+
+public abstract class Descriptor
+{
+    protected Resource _xml;
+    protected XmlParser.Node _root;
+    protected XmlParser _parser;
+    protected boolean _validating;
+    
+    public Descriptor (Resource xml)
+    {
+        _xml = xml;
+    }
+    
+    public abstract XmlParser newParser()
+    throws ClassNotFoundException;
+    
+    public abstract void ensureParser()
+    throws ClassNotFoundException;
+    
+    protected void redirect(XmlParser parser, String resource, URL source)
+    {
+        if (source != null) parser.redirectEntity(resource, source);
+    }
+    
+    
+    public void setValidating (boolean validating)
+    {
+       _validating = validating;
+    }
+    
+    public void parse ()
+    throws Exception
+    {
+        if (_parser == null)
+           ensureParser();
+        
+        if (_root == null)
+        {
+            try
+            {
+                _root = _parser.parse(_xml.getInputStream());
+            }
+            finally
+            {
+                _xml.release();
+            }
+        }
+    }
+    
+    public Resource getResource ()
+    {
+        return _xml;
+    }
+    
+    public XmlParser.Node getRoot ()
+    {
+        return _root;
+    }
+    
+    public String toString()
+    {
+        return this.getClass().getSimpleName()+"("+_xml+")";
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/DescriptorProcessor.java b/src/java/org/eclipse/jetty/webapp/DescriptorProcessor.java
new file mode 100644
index 0000000..328f9f5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/DescriptorProcessor.java
@@ -0,0 +1,29 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+/**
+ * DescriptorProcessor
+ *
+ *
+ */
+public interface DescriptorProcessor
+{
+    public void process (WebAppContext context, Descriptor descriptor) throws Exception;
+}
diff --git a/src/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java b/src/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java
new file mode 100644
index 0000000..697e60e
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/DiscoveredAnnotation.java
@@ -0,0 +1,89 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * DiscoveredAnnotation
+ *
+ * Represents an annotation that has been discovered
+ * by scanning source code of WEB-INF/classes and WEB-INF/lib jars.
+ * 
+ */
+public abstract class DiscoveredAnnotation
+{
+    private static final Logger LOG = Log.getLogger(DiscoveredAnnotation.class);
+
+    protected WebAppContext _context;
+    protected String _className;
+    protected Class<?> _clazz;
+    protected Resource _resource; //resource it was discovered on, can be null (eg from WEB-INF/classes)
+    
+    public abstract void apply();
+    
+    public DiscoveredAnnotation (WebAppContext context, String className)
+    {
+        this(context,className, null);
+    } 
+    
+    
+    public DiscoveredAnnotation(WebAppContext context, String className, Resource resource)
+    {
+        _context = context;
+        _className = className;
+        _resource = resource;
+    }
+    
+    public Resource getResource ()
+    {
+        return _resource;
+    }
+    
+    public Class<?> getTargetClass()
+    {
+        if (_clazz != null)
+            return _clazz;
+        
+        loadClass();
+        
+        return _clazz;
+    }
+    
+    private void loadClass ()
+    {
+        if (_clazz != null)
+            return;
+        
+        if (_className == null)
+            return;
+        
+        try
+        {
+            _clazz = Loader.loadClass(null, _className);
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
+    }  
+}
diff --git a/src/java/org/eclipse/jetty/webapp/FragmentConfiguration.java b/src/java/org/eclipse/jetty/webapp/FragmentConfiguration.java
new file mode 100644
index 0000000..05a97e1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/FragmentConfiguration.java
@@ -0,0 +1,89 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.List;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * FragmentConfiguration
+ * 
+ * 
+ * 
+ * Process web-fragments in jars
+ */
+public class FragmentConfiguration extends AbstractConfiguration
+{
+    public final static String FRAGMENT_RESOURCES="org.eclipse.jetty.webFragments";
+    
+    @Override
+    public void preConfigure(WebAppContext context) throws Exception
+    {
+        if (!context.isConfigurationDiscovered())
+            return;
+
+        //find all web-fragment.xmls
+        findWebFragments(context, context.getMetaData());
+        
+    }
+
+    @Override
+    public void configure(WebAppContext context) throws Exception
+    { 
+        if (!context.isConfigurationDiscovered())
+            return;
+        
+        //order the fragments
+        context.getMetaData().orderFragments(); 
+    }
+
+    @Override
+    public void postConfigure(WebAppContext context) throws Exception
+    {
+        context.setAttribute(FRAGMENT_RESOURCES, null);
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Look for any web-fragment.xml fragments in META-INF of jars in WEB-INF/lib
+     * 
+     * @throws Exception
+     */
+    public void findWebFragments (final WebAppContext context, final MetaData metaData) throws Exception
+    {
+        @SuppressWarnings("unchecked")
+        List<Resource> frags = (List<Resource>)context.getAttribute(FRAGMENT_RESOURCES);
+        if (frags!=null)
+        {
+            for (Resource frag : frags)
+            {
+            	if (frag.isDirectory()) //tolerate the case where the library is a directory, not a jar. useful for OSGi for example
+            	{
+                    metaData.addFragment(frag, Resource.newResource(frag.getURL()+"/META-INF/web-fragment.xml"));            		
+            	}
+                else //the standard case: a jar most likely inside WEB-INF/lib
+                {
+                    metaData.addFragment(frag, Resource.newResource("jar:"+frag.getURL()+"!/META-INF/web-fragment.xml"));
+                }
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/FragmentDescriptor.java b/src/java/org/eclipse/jetty/webapp/FragmentDescriptor.java
new file mode 100644
index 0000000..abeb1e4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/FragmentDescriptor.java
@@ -0,0 +1,169 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlParser;
+
+
+/**
+ * Fragment
+ *
+ * A web-fragment.xml descriptor.
+ */
+public class FragmentDescriptor extends WebDescriptor
+{
+    public static final String NAMELESS = "@@-NAMELESS-@@"; //prefix for nameless Fragments
+    protected static int _counter = 0;
+
+    public enum OtherType {None, Before, After};
+    protected OtherType _otherType = OtherType.None;
+   
+    
+    protected List<String> _befores = new ArrayList<String>();
+    protected List<String> _afters = new ArrayList<String>();
+    protected String _name;
+    
+
+    public FragmentDescriptor (Resource xml)
+        throws Exception
+    {
+        super (xml);
+    }       
+    
+    public String getName ()
+    {
+        return _name;
+    }
+    
+    @Override
+    public void parse () 
+        throws Exception
+    {
+        super.parse();
+        processName();
+    }
+    
+    public void processName ()
+    {
+        XmlParser.Node root = getRoot();
+        XmlParser.Node nameNode = root.get("name");
+        _name = NAMELESS+(_counter++);
+        if (nameNode != null)
+        {
+            String tmp = nameNode.toString(false,true);
+            if (tmp!=null && tmp.length()>0)
+                _name = tmp;
+        }
+    }
+    @Override
+    public void processOrdering ()
+    {
+        //Process a fragment jar's web-fragment.xml<ordering> elements
+        XmlParser.Node root = getRoot();       
+        
+        XmlParser.Node ordering = root.get("ordering");
+        if (ordering == null)
+            return; //No ordering for this fragment
+        
+        _isOrdered = true;
+   
+        processBefores(ordering);
+        processAfters(ordering);
+    }
+    
+    
+    public void processBefores (XmlParser.Node ordering)
+    {
+        //Process the <before> elements, looking for an <others/> clause and all of the <name> clauses
+        XmlParser.Node before = ordering.get("before");
+        if (before == null)
+            return;
+
+        Iterator<?> iter = before.iterator();
+        XmlParser.Node node = null;
+        while (iter.hasNext())
+        {
+            Object o = iter.next();
+            if (!(o instanceof XmlParser.Node)) continue;
+            node = (XmlParser.Node) o;
+            if (node.getTag().equalsIgnoreCase("others"))
+            {
+                if (_otherType != OtherType.None)
+                    throw new IllegalStateException("Duplicate <other> clause detected in "+_xml.getURI());
+
+                _otherType = OtherType.Before;
+            }
+            else if (node.getTag().equalsIgnoreCase("name"))
+                _befores.add(node.toString(false,true));
+        }
+    }
+
+    public void processAfters (XmlParser.Node ordering)
+    {
+        //Process the <after> elements, look for an <others/> clause and all of the <name/> clauses
+        XmlParser.Node after = ordering.get("after");
+        if (after == null)
+            return;
+        
+        Iterator<?> iter = after.iterator();
+        XmlParser.Node node = null;
+        while (iter.hasNext())
+        {
+            Object o = iter.next();
+            if (!(o instanceof XmlParser.Node)) continue;
+            node = (XmlParser.Node) o;
+            if (node.getTag().equalsIgnoreCase("others"))
+            {
+                if (_otherType != OtherType.None)
+                    throw new IllegalStateException("Duplicate <other> clause detected in "+_xml.getURI());
+
+                _otherType = OtherType.After;
+
+            }
+            else if (node.getTag().equalsIgnoreCase("name"))
+                _afters.add(node.toString(false,true));
+        }
+    }
+    
+    public List<String> getBefores()
+    {
+        return Collections.unmodifiableList(_befores);
+    }
+    
+    public List<String> getAfters()
+    {
+        return Collections.unmodifiableList(_afters);
+    }
+    
+    public OtherType getOtherType ()
+    {
+        return _otherType;
+    }
+    
+    public List<String> getOrdering()
+    {
+        return null; //only used for absolute-ordering in Descriptor
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java b/src/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java
new file mode 100644
index 0000000..31ef913
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/IterativeDescriptorProcessor.java
@@ -0,0 +1,87 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jetty.xml.XmlParser;
+
+/**
+ * IterativeDescriptorProcessor
+ *
+ *
+ */
+public abstract class IterativeDescriptorProcessor implements DescriptorProcessor
+{
+    public static final Class<?>[] __signature = new Class[]{WebAppContext.class, Descriptor.class, XmlParser.Node.class};
+    protected Map<String, Method> _visitors = new HashMap<String, Method>();
+    public abstract void start(WebAppContext context, Descriptor descriptor);
+    public abstract void end(WebAppContext context, Descriptor descriptor);
+
+    /**
+     * Register a method to be called back when visiting the node with the given name.
+     * The method must exist on a subclass of this class, and must have the signature:
+     * public void method (Descriptor descriptor, XmlParser.Node node)
+     * @param nodeName
+     * @param m
+     */
+    public void registerVisitor(String nodeName, Method m)
+    {
+        _visitors.put(nodeName, m);
+    }
+
+    
+    /** 
+     * {@inheritDoc}
+     */
+    public void process(WebAppContext context, Descriptor descriptor)
+    throws Exception
+    {
+        if (descriptor == null)
+            return;
+
+        start(context,descriptor);
+
+        XmlParser.Node root = descriptor.getRoot();
+        Iterator<?> iter = root.iterator();
+        XmlParser.Node node = null;
+        while (iter.hasNext())
+        {
+            Object o = iter.next();
+            if (!(o instanceof XmlParser.Node)) continue;
+            node = (XmlParser.Node) o;
+            visit(context, descriptor, node);
+        }
+
+        end(context,descriptor);
+    }
+
+
+    protected void visit (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    throws Exception
+    {
+        String name = node.getTag();
+        Method m =  _visitors.get(name);
+        if (m != null)
+            m.invoke(this, new Object[]{context, descriptor, node});
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/JarScanner.java b/src/java/org/eclipse/jetty/webapp/JarScanner.java
new file mode 100644
index 0000000..c5f6263
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/JarScanner.java
@@ -0,0 +1,171 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Locale;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.regex.Pattern;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * JarScannerConfiguration
+ *
+ * Abstract base class for configurations that want to scan jars in
+ * WEB-INF/lib and the classloader hierarchy.
+ * 
+ * Jar name matching based on regexp patterns is provided.
+ * 
+ * Subclasses should implement the processEntry(URL jarUrl, JarEntry entry)
+ * method to handle entries in jar files whose names match the supplied 
+ * pattern.
+ */
+public abstract class JarScanner extends org.eclipse.jetty.util.PatternMatcher
+{
+    private static final Logger LOG = Log.getLogger(JarScanner.class);
+
+
+    public abstract void processEntry (URI jarUri, JarEntry entry);
+    
+    /**
+     * Find jar names from the provided list matching a pattern.
+     * 
+     * If the pattern is null and isNullInclusive is true, then
+     * all jar names will match.
+     * 
+     * A pattern is a set of acceptable jar names. Each acceptable
+     * jar name is a regex. Each regex can be separated by either a
+     * "," or a "|". If you use a "|" this or's together the jar
+     * name patterns. This means that ordering of the matches is
+     * unimportant to you. If instead, you want to match particular
+     * jar names, and you want to match them in order, you should
+     * separate the regexs with "," instead. 
+     * 
+     * Eg "aaa-.*\\.jar|bbb-.*\\.jar"
+     * Will iterate over the jar names and match
+     * in any order.
+     * 
+     * Eg "aaa-*\\.jar,bbb-.*\\.jar"
+     * Will iterate over the jar names, matching
+     * all those starting with "aaa-" first, then "bbb-".
+     *
+     * @param pattern
+     * @param uris
+     * @param isNullInclusive if true, an empty pattern means all names match, if false, none match
+     * @throws Exception
+     */
+    public void scan (Pattern pattern, URI[] uris, boolean isNullInclusive)
+    throws Exception
+    {
+       super.match(pattern, uris, isNullInclusive);
+    }
+    
+    /**
+     * Find jar names from the classloader matching a pattern.
+     * 
+     * If the pattern is null and isNullInclusive is true, then
+     * all jar names in the classloader will match.
+     * 
+     * A pattern is a set of acceptable jar names. Each acceptable
+     * jar name is a regex. Each regex can be separated by either a
+     * "," or a "|". If you use a "|" this or's together the jar
+     * name patterns. This means that ordering of the matches is
+     * unimportant to you. If instead, you want to match particular
+     * jar names, and you want to match them in order, you should
+     * separate the regexs with "," instead. 
+     * 
+     * Eg "aaa-.*\\.jar|bbb-.*\\.jar"
+     * Will iterate over the jar names in the classloader and match
+     * in any order.
+     * 
+     * Eg "aaa-*\\.jar,bbb-.*\\.jar"
+     * Will iterate over the jar names in the classloader, matching
+     * all those starting with "aaa-" first, then "bbb-".
+     * 
+     * If visitParent is true, then the pattern is applied to the
+     * parent loader hierarchy. If false, it is only applied to the
+     * classloader passed in.
+     * 
+     * @param pattern
+     * @param loader
+     * @param isNullInclusive
+     * @param visitParent
+     * @throws Exception
+     */
+    public void scan (Pattern pattern, ClassLoader loader, boolean isNullInclusive, boolean visitParent)
+    throws Exception
+    {
+        while (loader!=null)
+        {
+            if (loader instanceof URLClassLoader)
+            {
+                URL[] urls = ((URLClassLoader)loader).getURLs();
+                if (urls != null)
+                {
+                    URI[] uris = new URI[urls.length];
+                    int i=0;
+                    for (URL u : urls)
+                        uris[i++] = u.toURI();
+                    scan (pattern, uris, isNullInclusive);
+                }
+            }     
+            if (visitParent)
+                loader=loader.getParent();
+            else
+                loader = null;
+        }  
+    }
+    
+    
+    public void matched (URI uri)
+    throws Exception
+    {
+        LOG.debug("Search of {}",uri);
+        if (uri.toString().toLowerCase(Locale.ENGLISH).endsWith(".jar"))
+        {
+         
+            InputStream in = Resource.newResource(uri).getInputStream();
+            if (in==null)
+                return;
+
+            JarInputStream jar_in = new JarInputStream(in);
+            try
+            { 
+                JarEntry entry = jar_in.getNextJarEntry();
+                while (entry!=null)
+                {
+                    processEntry(uri, entry);
+                    entry = jar_in.getNextJarEntry();
+                }
+            }
+            finally
+            {
+                jar_in.close();
+            }   
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java b/src/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java
new file mode 100644
index 0000000..7a62627
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.java
@@ -0,0 +1,146 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlConfiguration;
+
+
+/**
+ * 
+ * JettyWebConfiguration.
+ * 
+ * Looks for Xmlconfiguration files in WEB-INF.  Searches in order for the first of jetty6-web.xml, jetty-web.xml or web-jetty.xml
+ *
+ * 
+ *
+ */
+public class JettyWebXmlConfiguration extends AbstractConfiguration
+{
+    private static final Logger LOG = Log.getLogger(JettyWebXmlConfiguration.class);
+
+    /** The value of this property points to the WEB-INF directory of
+     * the web-app currently installed.
+     * it is passed as a property to the jetty-web.xml file */
+    public static final String PROPERTY_THIS_WEB_INF_URL = "this.web-inf.url";
+
+
+    public static final String XML_CONFIGURATION = "org.eclipse.jetty.webapp.JettyWebXmlConfiguration";
+    public static final String JETTY_WEB_XML = "jetty-web.xml";
+    
+    /** 
+     * Configure
+     * Apply web-jetty.xml configuration
+     * @see Configuration#configure(WebAppContext)
+     */
+    @Override
+    public void configure (WebAppContext context) throws Exception
+    {
+        //cannot configure if the _context is already started
+        if (context.isStarted())
+        {
+            LOG.debug("Cannot configure webapp after it is started");
+            return;
+        }
+        
+        LOG.debug("Configuring web-jetty.xml");
+        
+        Resource web_inf = context.getWebInf();
+        // handle any WEB-INF descriptors
+        if(web_inf!=null&&web_inf.isDirectory())
+        {
+            // do jetty.xml file
+            Resource jetty=web_inf.addPath("jetty8-web.xml");
+            if(!jetty.exists())
+                jetty=web_inf.addPath(JETTY_WEB_XML);
+            if(!jetty.exists())
+                jetty=web_inf.addPath("web-jetty.xml");
+
+            if(jetty.exists())
+            {
+                // No server classes while configuring 
+                String[] old_server_classes = context.getServerClasses();
+                try
+                {
+                    context.setServerClasses(null);
+                    if(LOG.isDebugEnabled())
+                        LOG.debug("Configure: "+jetty);
+                    
+                    XmlConfiguration jetty_config = (XmlConfiguration)context.getAttribute(XML_CONFIGURATION);
+                    
+                    if (jetty_config==null)
+                    {
+                        jetty_config=new XmlConfiguration(jetty.getURL());
+                    }
+                    else
+                    {
+                        context.removeAttribute(XML_CONFIGURATION);
+                    }
+                    setupXmlConfiguration(context,jetty_config, web_inf);
+                    try
+                    {
+                        jetty_config.configure(context);
+                    }
+                    catch (ClassNotFoundException e)
+                    {
+                        LOG.warn("Unable to process jetty-web.xml", e);
+                    }
+                }
+                finally
+                {
+                    if (context.getServerClasses()==null)
+                        context.setServerClasses(old_server_classes);
+                }
+            }
+        }
+    }
+
+    /**
+     * Configures some well-known properties before the XmlConfiguration reads
+     * the configuration.
+     * @param jetty_config The configuration object.
+     */
+    private void setupXmlConfiguration(WebAppContext context, XmlConfiguration jetty_config, Resource web_inf)
+    {
+        setupXmlConfiguration(jetty_config,web_inf);
+    }
+    
+    /**
+     * Configures some well-known properties before the XmlConfiguration reads
+     * the configuration.
+     * @param jetty_config The configuration object.
+     */
+    private void setupXmlConfiguration(XmlConfiguration jetty_config, Resource web_inf)
+    {
+    	Map<String,String> props = jetty_config.getProperties();
+    	if (props == null)
+    	{
+    		props = new HashMap<String, String>();
+    		jetty_config.setProperties(props);
+    	}
+    	
+    	// TODO - should this be an id rather than a property?
+    	props.put(PROPERTY_THIS_WEB_INF_URL, String.valueOf(web_inf.getURL()));
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/MetaData.java b/src/java/org/eclipse/jetty/webapp/MetaData.java
new file mode 100644
index 0000000..f946c59
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/MetaData.java
@@ -0,0 +1,585 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+
+
+
+/**
+ * MetaData
+ *
+ * All data associated with the configuration and deployment of a web application.
+ */
+public class MetaData
+{
+    private static final Logger LOG = Log.getLogger(MetaData.class);
+        
+    public static final String ORDERED_LIBS = "javax.servlet.context.orderedLibs";
+
+    protected Map<String, OriginInfo> _origins  =new HashMap<String,OriginInfo>();
+    protected WebDescriptor _webDefaultsRoot;
+    protected WebDescriptor _webXmlRoot;
+    protected final List<WebDescriptor> _webOverrideRoots=new ArrayList<WebDescriptor>();
+    protected boolean _metaDataComplete;
+    protected final List<DiscoveredAnnotation> _annotations = new ArrayList<DiscoveredAnnotation>();
+    protected final List<DescriptorProcessor> _descriptorProcessors = new ArrayList<DescriptorProcessor>();
+    protected final List<FragmentDescriptor> _webFragmentRoots = new ArrayList<FragmentDescriptor>();
+    protected final Map<String,FragmentDescriptor> _webFragmentNameMap = new HashMap<String,FragmentDescriptor>();
+    protected final Map<Resource, FragmentDescriptor> _webFragmentResourceMap = new HashMap<Resource, FragmentDescriptor>();
+    protected final Map<Resource, List<DiscoveredAnnotation>> _webFragmentAnnotations = new HashMap<Resource, List<DiscoveredAnnotation>>();
+    protected final List<Resource> _webInfJars = new ArrayList<Resource>();
+    protected final List<Resource> _orderedWebInfJars = new ArrayList<Resource>(); 
+    protected final List<Resource> _orderedContainerJars = new ArrayList<Resource>();
+    protected Ordering _ordering;//can be set to RelativeOrdering by web-default.xml, web.xml, web-override.xml
+    protected boolean allowDuplicateFragmentNames = false;
+   
+ 
+    
+  
+
+    public static class OriginInfo
+    {   
+        protected String name;
+        protected Origin origin;
+        protected Descriptor descriptor;
+        
+        public OriginInfo (String n, Descriptor d)
+        {
+            name = n;
+            descriptor = d;           
+            if (d == null)
+                throw new IllegalArgumentException("No descriptor");
+            if (d instanceof FragmentDescriptor)
+                origin = Origin.WebFragment;
+            else if (d instanceof OverrideDescriptor)
+                origin =  Origin.WebOverride;
+            else if (d instanceof DefaultsDescriptor)
+                origin =  Origin.WebDefaults;
+            else
+                origin = Origin.WebXml;
+        }
+        
+        public OriginInfo (String n)
+        {
+            name = n;
+            origin = Origin.Annotation;
+        }
+        
+        public OriginInfo(String n, Origin o)
+        {
+            name = n;
+            origin = o;
+        }
+        
+        public String getName()
+        {
+            return name;
+        }
+        
+        public Origin getOriginType()
+        {
+            return origin;
+        }
+        
+        public Descriptor getDescriptor()
+        {
+            return descriptor;
+        }
+    }
+   
+    public MetaData ()
+    {
+    }
+    
+    /**
+     * Empty ready for reuse
+     */
+    public void clear ()
+    {
+        _webDefaultsRoot = null;
+        _origins.clear();
+        _webXmlRoot = null;
+        _webOverrideRoots.clear();
+        _metaDataComplete = false;
+        _annotations.clear();
+        _descriptorProcessors.clear();
+        _webFragmentRoots.clear();
+        _webFragmentNameMap.clear();
+        _webFragmentResourceMap.clear();
+        _webFragmentAnnotations.clear();
+        _webInfJars.clear();
+        _orderedWebInfJars.clear();
+        _orderedContainerJars.clear();
+        _ordering = null;
+        allowDuplicateFragmentNames = false;
+    }
+    
+    public void setDefaults (Resource webDefaults)
+    throws Exception
+    {
+        _webDefaultsRoot =  new DefaultsDescriptor(webDefaults); 
+        _webDefaultsRoot.parse();
+        if (_webDefaultsRoot.isOrdered())
+        {
+            if (_ordering == null)
+                _ordering = new Ordering.AbsoluteOrdering(this);
+
+            List<String> order = _webDefaultsRoot.getOrdering();
+            for (String s:order)
+            {
+                if (s.equalsIgnoreCase("others"))
+                    ((Ordering.AbsoluteOrdering)_ordering).addOthers();
+                else 
+                    ((Ordering.AbsoluteOrdering)_ordering).add(s);
+            }
+        }    
+    }
+    
+    public void setWebXml (Resource webXml)
+    throws Exception
+    {
+        _webXmlRoot = new WebDescriptor(webXml);
+        _webXmlRoot.parse();
+        _metaDataComplete=_webXmlRoot.getMetaDataComplete() == MetaDataComplete.True;
+        
+        
+        
+        if (_webXmlRoot.isOrdered())
+        {
+            if (_ordering == null)
+                _ordering = new Ordering.AbsoluteOrdering(this);
+
+            List<String> order = _webXmlRoot.getOrdering();
+            for (String s:order)
+            {
+                if (s.equalsIgnoreCase("others"))
+                    ((Ordering.AbsoluteOrdering)_ordering).addOthers();
+                else 
+                    ((Ordering.AbsoluteOrdering)_ordering).add(s);
+            }
+        }    
+    }
+    
+    public void addOverride (Resource override)
+    throws Exception
+    {
+        OverrideDescriptor webOverrideRoot = new OverrideDescriptor(override);
+        webOverrideRoot.setValidating(false);
+        webOverrideRoot.parse();
+        
+        switch(webOverrideRoot.getMetaDataComplete())
+        {
+            case True:
+                _metaDataComplete=true;
+                break;
+            case False:
+                _metaDataComplete=false;
+                break;
+            case NotSet:
+                break;
+        }
+        
+        if (webOverrideRoot.isOrdered())
+        {
+            if (_ordering == null)
+                _ordering = new Ordering.AbsoluteOrdering(this);
+
+            List<String> order = webOverrideRoot.getOrdering();
+            for (String s:order)
+            {
+                if (s.equalsIgnoreCase("others"))
+                    ((Ordering.AbsoluteOrdering)_ordering).addOthers();
+                else 
+                    ((Ordering.AbsoluteOrdering)_ordering).add(s);
+            }
+        }   
+        _webOverrideRoots.add(webOverrideRoot);
+    }
+    
+    
+    /**
+     * Add a web-fragment.xml
+     * 
+     * @param jarResource the jar the fragment is contained in
+     * @param xmlResource the resource representing the xml file
+     * @throws Exception
+     */
+    public void addFragment (Resource jarResource, Resource xmlResource)
+    throws Exception
+    { 
+        if (_metaDataComplete)
+            return; //do not process anything else if web.xml/web-override.xml set metadata-complete
+        
+        //Metadata-complete is not set, or there is no web.xml
+        FragmentDescriptor descriptor = new FragmentDescriptor(xmlResource);
+        _webFragmentResourceMap.put(jarResource, descriptor);
+        _webFragmentRoots.add(descriptor);
+        
+        descriptor.parse();
+        
+        if (descriptor.getName() != null)
+        {
+            Descriptor existing = _webFragmentNameMap.get(descriptor.getName());
+            if (existing != null && !isAllowDuplicateFragmentNames())
+            {
+                throw new IllegalStateException("Duplicate fragment name: "+descriptor.getName()+" for "+existing.getResource()+" and "+descriptor.getResource());
+            }
+            else
+                _webFragmentNameMap.put(descriptor.getName(), descriptor);
+        }
+
+        //If web.xml has specified an absolute ordering, ignore any relative ordering in the fragment
+        if (_ordering != null && _ordering.isAbsolute())
+            return;
+        
+        if (_ordering == null && descriptor.isOrdered())
+            _ordering = new Ordering.RelativeOrdering(this);
+    }
+
+    /**
+     * Annotations not associated with a WEB-INF/lib fragment jar.
+     * These are from WEB-INF/classes or the ??container path??
+     * @param annotations
+     */
+    public void addDiscoveredAnnotations(List<DiscoveredAnnotation> annotations)
+    {
+        if (annotations == null)
+            return;
+        for (DiscoveredAnnotation a:annotations)
+        {
+            Resource r = a.getResource();
+            if (r == null || !_webInfJars.contains(r))
+                _annotations.add(a);
+            else 
+                addDiscoveredAnnotation(a.getResource(), a);
+                
+        }
+    }
+    
+    
+    public void addDiscoveredAnnotation(Resource resource, DiscoveredAnnotation annotation)
+    {
+        List<DiscoveredAnnotation> list = _webFragmentAnnotations.get(resource);
+        if (list == null)
+        {
+            list = new ArrayList<DiscoveredAnnotation>();
+            _webFragmentAnnotations.put(resource, list);
+        }
+        list.add(annotation);
+    }
+    
+
+    public void addDiscoveredAnnotations(Resource resource, List<DiscoveredAnnotation> annotations)
+    {
+        List<DiscoveredAnnotation> list = _webFragmentAnnotations.get(resource);
+        if (list == null)
+        {
+            list = new ArrayList<DiscoveredAnnotation>();
+            _webFragmentAnnotations.put(resource, list);
+        }
+            
+        list.addAll(annotations);
+    }
+    
+    public void addDescriptorProcessor(DescriptorProcessor p)
+    {
+        _descriptorProcessors.add(p);
+    }
+    
+    public void orderFragments ()
+    {
+        //if we have already ordered them don't do it again
+        if (_orderedWebInfJars.size()==_webInfJars.size())
+            return;
+        
+        if (_ordering != null)
+            _orderedWebInfJars.addAll(_ordering.order(_webInfJars));
+        else
+            _orderedWebInfJars.addAll(_webInfJars);
+    }
+    
+    
+    /**
+     * Resolve all servlet/filter/listener metadata from all sources: descriptors and annotations.
+     * 
+     */
+    public void resolve (WebAppContext context)
+    throws Exception
+    {
+        LOG.debug("metadata resolve {}",context);
+        
+        //Ensure origins is fresh
+        _origins.clear();
+        
+        // Set the ordered lib attribute
+        if (_ordering != null)
+        {
+            List<String> orderedLibs = new ArrayList<String>();
+            for (Resource webInfJar:_orderedWebInfJars)
+            {
+                //get just the name of the jar file
+                String fullname = webInfJar.getName();
+                int i = fullname.indexOf(".jar");          
+                int j = fullname.lastIndexOf("/", i);
+                orderedLibs.add(fullname.substring(j+1,i+4));
+            }
+            context.setAttribute(ServletContext.ORDERED_LIBS, orderedLibs);
+        }
+
+        // set the webxml version
+        if (_webXmlRoot != null)
+        {
+            context.getServletContext().setEffectiveMajorVersion(_webXmlRoot.getMajorVersion());
+            context.getServletContext().setEffectiveMinorVersion(_webXmlRoot.getMinorVersion());
+        }
+
+        for (DescriptorProcessor p:_descriptorProcessors)
+        {
+            p.process(context,getWebDefault());
+            p.process(context,getWebXml());
+            for (WebDescriptor wd : getOverrideWebs())   
+            {
+                LOG.debug("process {} {}",context,wd);
+                p.process(context,wd);
+            }
+        }
+        
+        for (DiscoveredAnnotation a:_annotations)
+        {
+            LOG.debug("apply {}",a);
+            a.apply();
+        }
+    
+        
+        List<Resource> resources = getOrderedWebInfJars();
+        for (Resource r:resources)
+        {
+            FragmentDescriptor fd = _webFragmentResourceMap.get(r);
+            if (fd != null)
+            {
+                for (DescriptorProcessor p:_descriptorProcessors)
+                {
+                    LOG.debug("process {} {}",context,fd);
+                    p.process(context,fd);
+                }
+            }
+            
+            List<DiscoveredAnnotation> fragAnnotations = _webFragmentAnnotations.get(r);
+            if (fragAnnotations != null)
+            {
+                for (DiscoveredAnnotation a:fragAnnotations)
+                {
+                    LOG.debug("apply {}",a);
+                    a.apply();
+                }
+            }
+        }
+        
+    }
+    
+    public boolean isDistributable ()
+    {
+        boolean distributable = (
+                (_webDefaultsRoot != null && _webDefaultsRoot.isDistributable()) 
+                || (_webXmlRoot != null && _webXmlRoot.isDistributable()));
+        
+        for (WebDescriptor d : _webOverrideRoots)
+            distributable&=d.isDistributable();
+        
+        List<Resource> orderedResources = getOrderedWebInfJars();
+        for (Resource r: orderedResources)
+        {  
+            FragmentDescriptor d = _webFragmentResourceMap.get(r);
+            if (d!=null)
+                distributable = distributable && d.isDistributable();
+        }
+        return distributable;
+    }
+   
+    
+    public WebDescriptor getWebXml ()
+    {
+        return _webXmlRoot;
+    }
+    
+    public List<WebDescriptor> getOverrideWebs ()
+    {
+        return _webOverrideRoots;
+    }
+    
+    public WebDescriptor getWebDefault ()
+    {
+        return _webDefaultsRoot;
+    }
+    
+    public List<FragmentDescriptor> getFragments ()
+    {
+        return _webFragmentRoots;
+    }
+    
+    public List<Resource> getOrderedWebInfJars()
+    {
+        return _orderedWebInfJars == null? new ArrayList<Resource>(): _orderedWebInfJars;
+    }
+    
+    public List<FragmentDescriptor> getOrderedFragments ()
+    {
+        List<FragmentDescriptor> list = new ArrayList<FragmentDescriptor>();
+        if (_orderedWebInfJars == null)
+            return list;
+
+        for (Resource r:_orderedWebInfJars)
+        {
+            FragmentDescriptor fd = _webFragmentResourceMap.get(r);
+            if (fd != null)
+                list.add(fd);
+        }
+        return list;
+    }
+    
+    public Ordering getOrdering()
+    {
+        return _ordering;
+    }
+    
+    public void setOrdering (Ordering o)
+    {
+        _ordering = o;
+    }
+    
+    public FragmentDescriptor getFragment (Resource jar)
+    {
+        return _webFragmentResourceMap.get(jar);
+    }
+    
+    public FragmentDescriptor getFragment(String name)
+    {
+        return _webFragmentNameMap.get(name);
+    }
+    
+    public Resource getJarForFragment (String name)
+    {
+        FragmentDescriptor f = getFragment(name);
+        if (f == null)
+            return null;
+        
+        Resource jar = null;
+        for (Resource r: _webFragmentResourceMap.keySet())
+        {
+            if (_webFragmentResourceMap.get(r).equals(f))
+                jar = r;
+        }
+        return jar;
+    }
+    
+    public Map<String,FragmentDescriptor> getNamedFragments ()
+    {
+        return Collections.unmodifiableMap(_webFragmentNameMap);
+    }
+    
+    
+    public Origin getOrigin (String name)
+    {
+        OriginInfo x =  _origins.get(name);
+        if (x == null)
+            return Origin.NotSet;
+        
+        return x.getOriginType();
+    }
+  
+ 
+    public Descriptor getOriginDescriptor (String name)
+    {
+        OriginInfo o = _origins.get(name);
+        if (o == null)
+            return null;
+        return o.getDescriptor();
+    }
+    
+    public void setOrigin (String name, Descriptor d)
+    {
+        OriginInfo x = new OriginInfo (name, d);
+        _origins.put(name, x);
+    }
+    
+    public void setOrigin (String name)
+    {
+        if (name == null)
+            return;
+       
+        OriginInfo x = new OriginInfo (name, Origin.Annotation);
+        _origins.put(name, x);
+    }
+    
+    public void setOrigin(String name, Origin origin)
+    {
+        if (name == null)
+            return;
+       
+        OriginInfo x = new OriginInfo (name, origin);
+        _origins.put(name, x);
+    }
+
+    public boolean isMetaDataComplete()
+    {
+        return _metaDataComplete;
+    }
+
+    
+    public void addWebInfJar(Resource newResource)
+    {
+        _webInfJars.add(newResource);
+    }
+
+    public List<Resource> getWebInfJars()
+    {
+        return Collections.unmodifiableList(_webInfJars);
+    }
+    
+    public List<Resource> getOrderedContainerJars()
+    {
+        return _orderedContainerJars;
+    }
+    
+    public void addContainerJar(Resource jar)
+    {
+        _orderedContainerJars.add(jar);
+    }
+    public boolean isAllowDuplicateFragmentNames()
+    {
+        return allowDuplicateFragmentNames;
+    }
+
+    public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames)
+    {
+        this.allowDuplicateFragmentNames = allowDuplicateFragmentNames;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/MetaDataComplete.java b/src/java/org/eclipse/jetty/webapp/MetaDataComplete.java
new file mode 100644
index 0000000..c199f68
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/MetaDataComplete.java
@@ -0,0 +1,21 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+public enum MetaDataComplete {NotSet, True, False}
diff --git a/src/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/src/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
new file mode 100644
index 0000000..dca8da1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
@@ -0,0 +1,152 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.jar.JarEntry;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * MetaInfConfiguration
+ *
+ * Scan META-INF of all jars in WEB-INF/lib to find:
+ * <ul>
+ * <li>tlds
+ * <li>web-fragment.xml
+ * <li>resources
+ * </ul>
+ */
+public class MetaInfConfiguration extends AbstractConfiguration
+{
+    private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class);
+
+    public static final String METAINF_TLDS = TagLibConfiguration.TLD_RESOURCES;
+    public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES;
+    public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_URLS;
+  
+    @Override
+    public void preConfigure(final WebAppContext context) throws Exception
+    {
+       //Merge all container and webinf lib jars to look for META-INF resources
+      
+        ArrayList<Resource> jars = new ArrayList<Resource>();
+        jars.addAll(context.getMetaData().getOrderedContainerJars());
+        jars.addAll(context.getMetaData().getWebInfJars());
+        
+        JarScanner scanner = new JarScanner()
+        {
+            public void processEntry(URI jarUri, JarEntry entry)
+            {
+                try
+                {
+                    MetaInfConfiguration.this.processEntry(context,jarUri,entry);
+                }
+                catch (Exception e)
+                {
+                    LOG.warn("Problem processing jar entry " + entry, e);
+                }
+            }
+        };
+        
+        
+        //Scan jars for META-INF information
+        if (jars != null)
+        {
+            URI[] uris = new URI[jars.size()];
+            int i=0;
+            for (Resource r : jars)
+            {
+                uris[i++] = r.getURI();
+            }
+            scanner.scan(null, uris, true);
+        }
+    }
+    @Override
+    public void configure(WebAppContext context) throws Exception
+    {
+        
+    }
+
+    @Override
+    public void deconfigure(WebAppContext context) throws Exception
+    {
+ 
+    }
+
+    @Override
+    public void postConfigure(WebAppContext context) throws Exception
+    {
+        context.setAttribute(METAINF_FRAGMENTS, null); 
+        context.setAttribute(METAINF_RESOURCES, null);
+        context.setAttribute(METAINF_TLDS, null);
+    }
+
+    public void addResource (WebAppContext context, String attribute, Resource jar)
+    {
+        @SuppressWarnings("unchecked")
+        List<Resource> list = (List<Resource>)context.getAttribute(attribute);
+        if (list==null)
+        {
+            list=new ArrayList<Resource>();
+            context.setAttribute(attribute,list);
+        }
+        if (!list.contains(jar))
+            list.add(jar);
+    }
+    
+    
+    protected void processEntry(WebAppContext context, URI jarUri, JarEntry entry)
+    {
+        String name = entry.getName();
+
+        if (!name.startsWith("META-INF/"))
+            return;
+        
+        try
+        {
+            if (name.equals("META-INF/web-fragment.xml") && context.isConfigurationDiscovered())
+            {
+                addResource(context,METAINF_FRAGMENTS,Resource.newResource(jarUri));     
+            }
+            else if (name.equals("META-INF/resources/") && context.isConfigurationDiscovered())
+            {
+                addResource(context,METAINF_RESOURCES,Resource.newResource("jar:"+jarUri+"!/META-INF/resources"));
+            }
+            else
+            {
+                String lcname = name.toLowerCase(Locale.ENGLISH);
+                if (lcname.endsWith(".tld"))
+                {
+                    addResource(context,METAINF_TLDS,Resource.newResource("jar:"+jarUri+"!/"+name));
+                }
+            }
+        }
+        catch(Exception e)
+        {
+            context.getServletContext().log(jarUri+"!/"+name,e);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/Ordering.java b/src/java/org/eclipse/jetty/webapp/Ordering.java
new file mode 100644
index 0000000..480fc30
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/Ordering.java
@@ -0,0 +1,491 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+
+/**
+ * Ordering
+ *
+ * Ordering options for jars in WEB-INF lib.
+ */
+public interface Ordering
+{  
+
+    public List<Resource> order(List<Resource> fragments);
+    public boolean isAbsolute ();
+    public boolean hasOther();
+
+
+    /**
+     * AbsoluteOrdering
+     *
+     * An &lt;absolute-order&gt; element in web.xml
+     */
+    public static class AbsoluteOrdering implements Ordering
+    {
+        public static final String OTHER = "@@-OTHER-@@";
+        protected List<String> _order = new ArrayList<String>();
+        protected boolean _hasOther = false;
+        protected MetaData _metaData;
+    
+        public AbsoluteOrdering (MetaData metaData)
+        {
+            _metaData = metaData;
+        }
+        
+        /** 
+         * Order the list of jars in WEB-INF/lib according to the ordering declarations in the descriptors
+         * @see org.eclipse.jetty.webapp.Ordering#order(java.util.List)
+         */
+        @Override
+        public List<Resource> order(List<Resource> jars)
+        {           
+            List<Resource> orderedList = new ArrayList<Resource>();
+            List<Resource> tmp = new ArrayList<Resource>(jars);
+          
+            //1. put everything into the list of named others, and take the named ones out of there,
+            //assuming we will want to use the <other> clause
+            Map<String,FragmentDescriptor> others = new HashMap<String,FragmentDescriptor>(_metaData.getNamedFragments());
+            
+            //2. for each name, take out of the list of others, add to tail of list
+            int index = -1;
+            for (String item:_order)
+            {
+                if (!item.equals(OTHER))
+                {
+                    FragmentDescriptor f = others.remove(item);
+                    if (f != null)
+                    {
+                        Resource jar = _metaData.getJarForFragment(item);
+                        orderedList.add(jar); //take from others and put into final list in order, ignoring duplicate names
+                        //remove resource from list for resource matching name of descriptor
+                        tmp.remove(jar);
+                    }
+                }
+                else
+                    index = orderedList.size(); //remember the index at which we want to add in all the others
+            }
+            
+            //3. if <other> was specified, insert rest of the fragments 
+            if (_hasOther)
+            {
+                orderedList.addAll((index < 0? 0: index), tmp);
+            }
+            
+            return orderedList;
+        }
+        
+        @Override
+        public boolean isAbsolute()
+        {
+            return true;
+        }
+        
+        public void add (String name)
+        {
+            _order.add(name); 
+        }
+        
+        public void addOthers ()
+        {
+            if (_hasOther)
+                throw new IllegalStateException ("Duplicate <other> element in absolute ordering");
+            
+            _hasOther = true;
+            _order.add(OTHER);
+        }
+        
+        @Override
+        public boolean hasOther ()
+        {
+            return _hasOther;
+        }
+    }
+    /**
+     * RelativeOrdering
+     *
+     * A set of &lt;order&gt; elements in web-fragment.xmls.
+     */
+    public static class RelativeOrdering implements Ordering
+    {
+        protected MetaData _metaData;
+        protected LinkedList<Resource> _beforeOthers = new LinkedList<Resource>();
+        protected LinkedList<Resource> _afterOthers = new LinkedList<Resource>();
+        protected LinkedList<Resource> _noOthers = new LinkedList<Resource>();
+        
+        public RelativeOrdering (MetaData metaData)
+        {
+            _metaData = metaData;
+        }
+        /** 
+         * Order the list of jars according to the ordering declared
+         * in the various web-fragment.xml files.
+         * @see org.eclipse.jetty.webapp.Ordering#order(java.util.List)
+         */
+        @Override
+        public List<Resource> order(List<Resource> jars)
+        {         
+            //for each jar, put it into the ordering according to the fragment ordering
+            for (Resource jar:jars)
+            {
+                //check if the jar has a fragment descriptor
+                FragmentDescriptor descriptor = _metaData.getFragment(jar);
+                if (descriptor != null)
+                {
+                    switch (descriptor.getOtherType())
+                    {
+                        case None:
+                        {
+                            ((RelativeOrdering)_metaData.getOrdering()).addNoOthers(jar);
+                            break;
+                        }
+                        case Before:
+                        { 
+                            ((RelativeOrdering)_metaData.getOrdering()).addBeforeOthers(jar);
+                            break;
+                        }
+                        case After:
+                        {
+                            ((RelativeOrdering)_metaData.getOrdering()).addAfterOthers(jar);
+                            break;
+                        }
+                    } 
+                }
+                else
+                {
+                    //jar fragment has no descriptor, but there is a relative ordering in place, so it must be part of the others
+                    ((RelativeOrdering)_metaData.getOrdering()).addNoOthers(jar);
+                }
+            }            
+                
+            //now apply the ordering
+            List<Resource> orderedList = new ArrayList<Resource>(); 
+            int maxIterations = 2;
+            boolean done = false;
+            do
+            {
+                //1. order the before-others according to any explicit before/after relationships 
+                boolean changesBefore = orderList(_beforeOthers);
+    
+                //2. order the after-others according to any explicit before/after relationships
+                boolean changesAfter = orderList(_afterOthers);
+    
+                //3. order the no-others according to their explicit before/after relationships
+                boolean changesNone = orderList(_noOthers);
+                
+                //we're finished on a clean pass through with no ordering changes
+                done = (!changesBefore && !changesAfter && !changesNone);
+            }
+            while (!done && (--maxIterations >0));
+            
+            //4. merge before-others + no-others +after-others
+            if (!done)
+                throw new IllegalStateException("Circular references for fragments");
+            
+            for (Resource r: _beforeOthers)
+                orderedList.add(r);
+            for (Resource r: _noOthers)
+                orderedList.add(r);
+            for(Resource r: _afterOthers)
+                orderedList.add(r);
+            
+            return orderedList;
+        }
+        
+        @Override
+        public boolean isAbsolute ()
+        {
+            return false;
+        }
+        
+        @Override
+        public boolean hasOther ()
+        {
+            return !_beforeOthers.isEmpty() || !_afterOthers.isEmpty();
+        }
+        
+        public void addBeforeOthers (Resource r)
+        {
+            _beforeOthers.addLast(r);
+        }
+        
+        public void addAfterOthers (Resource r)
+        {
+            _afterOthers.addLast(r);
+        }
+        
+        public void addNoOthers (Resource r)
+        {
+            _noOthers.addLast(r);
+        }
+        
+       protected boolean orderList (LinkedList<Resource> list)
+       {
+           //Take a copy of the list so we can iterate over it and at the same time do random insertions
+           boolean changes = false;
+           List<Resource> iterable = new ArrayList<Resource>(list);
+           Iterator<Resource> itor = iterable.iterator();
+           
+           while (itor.hasNext())
+           {
+               Resource r = itor.next();
+               FragmentDescriptor f = _metaData.getFragment(r);
+               if (f == null)
+               {
+                   //no fragment for this resource so cannot have any ordering directives
+                   continue;
+               }
+                
+               //Handle any explicit <before> relationships for the fragment we're considering
+               List<String> befores = f.getBefores();
+               if (befores != null && !befores.isEmpty())
+               {
+                   for (String b: befores)
+                   {
+                       //Fragment we're considering must be before b
+                       //Check that we are already before it, if not, move us so that we are.
+                       //If the name does not exist in our list, then get it out of the no-other list
+                       if (!isBefore(list, f.getName(), b))
+                       {
+                           //b is not already before name, move it so that it is
+                           int idx1 = getIndexOf(list, f.getName());
+                           int idx2 = getIndexOf(list, b);
+    
+                           //if b is not in the same list
+                           if (idx2 < 0)
+                           {
+                               changes = true;
+                               // must be in the noOthers list or it would have been an error
+                               Resource bResource = _metaData.getJarForFragment(b);
+                               if (bResource != null)
+                               {
+                                   //If its in the no-others list, insert into this list so that we are before it
+                                   if (_noOthers.remove(bResource))
+                                   {
+                                       insert(list, idx1+1, b);
+                                      
+                                   }
+                               }
+                           }
+                           else
+                           {
+                               //b is in the same list but b is before name, so swap it around
+                               list.remove(idx1);
+                               insert(list, idx2, f.getName());
+                               changes = true;
+                           }
+                       }
+                   }
+               }
+    
+               //Handle any explicit <after> relationships
+               List<String> afters = f.getAfters();
+               if (afters != null && !afters.isEmpty())
+               {
+                   for (String a: afters)
+                   {
+                       //Check that fragment we're considering is after a, moving it if possible if its not
+                       if (!isAfter(list, f.getName(), a))
+                       {
+                           //name is not after a, move it
+                           int idx1 = getIndexOf(list, f.getName());
+                           int idx2 = getIndexOf(list, a);
+                           
+                           //if a is not in the same list as name
+                           if (idx2 < 0)
+                           {
+                               changes = true;
+                               //take it out of the noOthers list and put it in the right place in this list
+                               Resource aResource = _metaData.getJarForFragment(a);
+                               if (aResource != null)
+                               {
+                                   if (_noOthers.remove(aResource))
+                                   {
+                                       insert(list,idx1, aResource);       
+                                   }
+                               }
+                           }
+                           else
+                           {
+                               //a is in the same list as name, but in the wrong place, so move it
+                               list.remove(idx2);
+                               insert(list,idx1, a);
+                               changes = true;
+                           }
+                       }
+                       //Name we're considering must be after this name
+                       //Check we're already after it, if not, move us so that we are.
+                       //If the name does not exist in our list, then get it out of the no-other list
+                   }
+               }
+           }
+    
+           return changes;
+       }
+    
+       /**
+        * Is fragment with name a before fragment with name b?
+        * @param list
+        * @param fragNameA
+        * @param fragNameB
+        * @return true if fragment name A is before fragment name B 
+        */
+       protected boolean isBefore (List<Resource> list, String fragNameA, String fragNameB)
+       {
+           //check if a and b are already in the same list, and b is already
+           //before a 
+           int idxa = getIndexOf(list, fragNameA);
+           int idxb = getIndexOf(list, fragNameB);
+           
+           
+           if (idxb >=0 && idxb < idxa)
+           {
+               //a and b are in the same list but a is not before b
+               return false;
+           }
+           
+           if (idxb < 0)
+           {
+               //a and b are not in the same list, but it is still possible that a is before
+               //b, depending on which list we're examining
+               if (list == _beforeOthers)
+               {
+                   //The list we're looking at is the beforeOthers.If b is in the _afterOthers or the _noOthers, then by
+                   //definition a is before it
+                   return true;
+               }
+               else if (list == _afterOthers)
+               {
+                   //The list we're looking at is the afterOthers, then a will be the tail of
+                   //the final list.  If b is in the beforeOthers list, then b will be before a and an error.
+                   if (_beforeOthers.contains(fragNameB))
+                       throw new IllegalStateException("Incorrect relationship: "+fragNameA+" before "+fragNameB);
+                   else
+                       return false; //b could be moved to the list
+               }
+           }
+          
+           //a and b are in the same list and a is already before b
+           return true;
+       }
+    
+    
+       /**
+        * Is fragment name "a" after fragment name "b"?
+        * @param list
+        * @param fragNameA
+        * @param fragNameB
+        * @return true if fragment name A is after fragment name B
+        */
+       protected boolean isAfter(List<Resource> list, String fragNameA, String fragNameB)
+       {
+           int idxa = getIndexOf(list, fragNameA);
+           int idxb = getIndexOf(list, fragNameB);
+           
+           if (idxb >=0 && idxa < idxb)
+           {
+               //a and b are both in the same list, but a is before b
+               return false;
+           }
+           
+           if (idxb < 0)
+           {
+               //a and b are in different lists. a could still be after b depending on which list it is in.
+    
+               if (list == _afterOthers)
+               {
+                   //The list we're looking at is the afterOthers. If b is in the beforeOthers or noOthers then
+                   //by definition a is after b because a is in the afterOthers list.
+                   return true;
+               }
+               else if (list == _beforeOthers)
+               {
+                   //The list we're looking at is beforeOthers, and contains a and will be before
+                   //everything else in the final ist. If b is in the afterOthers list, then a cannot be before b.
+                   if (_afterOthers.contains(fragNameB))
+                       throw new IllegalStateException("Incorrect relationship: "+fragNameB+" after "+fragNameA);
+                   else
+                       return false; //b could be moved from noOthers list
+               }
+           }
+    
+           return true; //a and b in the same list, a is after b
+       }
+    
+       /**
+        * Insert the resource matching the fragName into the list of resources
+        * at the location indicated by index.
+        * 
+        * @param list
+        * @param index
+        * @param fragName
+        */
+       protected void insert(List<Resource> list, int index, String fragName)
+       {
+           Resource jar = _metaData.getJarForFragment(fragName);
+           if (jar == null)
+               throw new IllegalStateException("No jar for insertion");
+           
+           insert(list, index, jar);
+       }
+    
+       protected void insert(List<Resource> list, int index, Resource resource)
+       {
+           if (list == null)
+               throw new IllegalStateException("List is null for insertion");
+           
+           //add it at the end
+           if (index > list.size())
+               list.add(resource);
+           else
+               list.add(index, resource);
+       }
+    
+       protected void remove (List<Resource> resources, Resource r)
+       {
+           if (resources == null)
+               return;
+           resources.remove(r);
+       }
+    
+       protected int getIndexOf(List<Resource> resources, String fragmentName)
+       {
+          FragmentDescriptor fd = _metaData.getFragment(fragmentName);
+          if (fd == null)
+              return -1;
+          
+          
+          Resource r = _metaData.getJarForFragment(fragmentName);
+          if (r == null)
+              return -1;
+          
+          return resources.indexOf(r);
+       }
+    }
+  
+}
diff --git a/src/java/org/eclipse/jetty/webapp/Origin.java b/src/java/org/eclipse/jetty/webapp/Origin.java
new file mode 100644
index 0000000..dbd70b1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/Origin.java
@@ -0,0 +1,21 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation, API}
diff --git a/src/java/org/eclipse/jetty/webapp/OverrideDescriptor.java b/src/java/org/eclipse/jetty/webapp/OverrideDescriptor.java
new file mode 100644
index 0000000..b67fe5d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/OverrideDescriptor.java
@@ -0,0 +1,34 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import org.eclipse.jetty.util.resource.Resource;
+
+/**
+ * OverrideDescriptor
+ *
+ *
+ */
+public class OverrideDescriptor extends WebDescriptor
+{
+    public OverrideDescriptor(Resource xml)
+    {
+        super(xml);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/src/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
new file mode 100644
index 0000000..43ce722
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
@@ -0,0 +1,1961 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+import javax.servlet.descriptor.JspPropertyGroupDescriptor;
+import javax.servlet.descriptor.TaglibDescriptor;
+
+import org.eclipse.jetty.security.ConstraintAware;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.authentication.FormAuthenticator;
+import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.Holder;
+import org.eclipse.jetty.servlet.JspPropertyGroupServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
+import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
+import org.eclipse.jetty.servlet.ServletContextHandler.TagLib;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletMapping;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.xml.XmlParser;
+
+/**
+ * StandardDescriptorProcessor
+ *
+ * Process a web.xml, web-defaults.xml, web-overrides.xml, web-fragment.xml.
+ */
+public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
+{
+    private static final Logger LOG = Log.getLogger(StandardDescriptorProcessor.class);
+
+    public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
+    
+    
+    
+    public StandardDescriptorProcessor ()
+    {
+ 
+        try
+        {
+            registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature));
+            registerVisitor("display-name", this.getClass().getDeclaredMethod("visitDisplayName", __signature));
+            registerVisitor("servlet", this.getClass().getDeclaredMethod("visitServlet",  __signature));
+            registerVisitor("servlet-mapping", this.getClass().getDeclaredMethod("visitServletMapping",  __signature));
+            registerVisitor("session-config", this.getClass().getDeclaredMethod("visitSessionConfig",  __signature));
+            registerVisitor("mime-mapping", this.getClass().getDeclaredMethod("visitMimeMapping",  __signature)); 
+            registerVisitor("welcome-file-list", this.getClass().getDeclaredMethod("visitWelcomeFileList",  __signature));
+            registerVisitor("locale-encoding-mapping-list", this.getClass().getDeclaredMethod("visitLocaleEncodingList",  __signature));
+            registerVisitor("error-page", this.getClass().getDeclaredMethod("visitErrorPage",  __signature));
+            registerVisitor("taglib", this.getClass().getDeclaredMethod("visitTagLib",  __signature));
+            registerVisitor("jsp-config", this.getClass().getDeclaredMethod("visitJspConfig",  __signature));
+            registerVisitor("security-constraint", this.getClass().getDeclaredMethod("visitSecurityConstraint",  __signature));
+            registerVisitor("login-config", this.getClass().getDeclaredMethod("visitLoginConfig",  __signature));
+            registerVisitor("security-role", this.getClass().getDeclaredMethod("visitSecurityRole",  __signature));
+            registerVisitor("filter", this.getClass().getDeclaredMethod("visitFilter",  __signature));
+            registerVisitor("filter-mapping", this.getClass().getDeclaredMethod("visitFilterMapping",  __signature));
+            registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener",  __signature));
+            registerVisitor("distributable", this.getClass().getDeclaredMethod("visitDistributable",  __signature));
+        }
+        catch (Exception e)
+        {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void start(WebAppContext context, Descriptor descriptor)
+    { 
+    }
+    
+    
+    
+    /** 
+     * {@inheritDoc}
+     */
+    public void end(WebAppContext context, Descriptor descriptor)
+    {
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    public void visitContextParam (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String name = node.getString("param-name", false, true);
+        String value = node.getString("param-value", false, true);
+        Origin o = context.getMetaData().getOrigin("context-param."+name);
+        switch (o)
+        {
+            case NotSet:
+            {
+                //just set it
+                context.getInitParams().put(name, value);
+                context.getMetaData().setOrigin("context-param."+name, descriptor);
+                break;
+            }
+            case WebXml:
+            case WebDefaults:
+            case WebOverride:
+            {
+                //previously set by a web xml, allow other web xml files to override
+                if (!(descriptor instanceof FragmentDescriptor))
+                {
+                    context.getInitParams().put(name, value);
+                    context.getMetaData().setOrigin("context-param."+name, descriptor); 
+                }
+                break;
+            }
+            case WebFragment:
+            {
+                //previously set by a web-fragment, this fragment's value must be the same
+                if (descriptor instanceof FragmentDescriptor)
+                {
+                    if (!((String)context.getInitParams().get(name)).equals(value))
+                        throw new IllegalStateException("Conflicting context-param "+name+"="+value+" in "+descriptor.getResource());
+                }
+                break;
+            }
+        }
+        if (LOG.isDebugEnabled()) 
+            LOG.debug("ContextParam: " + name + "=" + value);
+
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitDisplayName(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        //Servlet Spec 3.0 p. 74 Ignore from web-fragments
+        if (!(descriptor instanceof FragmentDescriptor))
+        {
+            context.setDisplayName(node.toString(false, true));
+            context.getMetaData().setOrigin("display-name", descriptor);
+        }
+    }
+    
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitServlet(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String id = node.getAttribute("id");
+
+        // initialize holder
+        String servlet_name = node.getString("servlet-name", false, true);
+        ServletHolder holder = context.getServletHandler().getServlet(servlet_name);
+          
+        /*
+         * If servlet of that name does not already exist, create it.
+         */
+        if (holder == null)
+        {
+            holder = context.getServletHandler().newServletHolder(Holder.Source.DESCRIPTOR);
+            holder.setName(servlet_name);
+            context.getServletHandler().addServlet(holder);
+        }
+
+        // init params  
+        Iterator<?> iParamsIter = node.iterator("init-param");
+        while (iParamsIter.hasNext())
+        {
+            XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
+            String pname = paramNode.getString("param-name", false, true);
+            String pvalue = paramNode.getString("param-value", false, true);
+            
+            Origin origin = context.getMetaData().getOrigin(servlet_name+".servlet.init-param."+pname);
+            
+            switch (origin)
+            {
+                case NotSet:
+                {
+                    //init-param not already set, so set it
+                    
+                    holder.setInitParameter(pname, pvalue); 
+                    context.getMetaData().setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //previously set by a web xml descriptor, if we're parsing another web xml descriptor allow override
+                    //otherwise just ignore it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setInitParameter(pname, pvalue); 
+                        context.getMetaData().setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //previously set by a web-fragment, make sure that the value matches, otherwise its an error
+                    if (!holder.getInitParameter(pname).equals(pvalue))
+                        throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
+                    break;
+                }
+            }  
+        }
+
+        String servlet_class = node.getString("servlet-class", false, true);
+
+        // Handle JSP
+        String jspServletClass=null;;
+
+        //Handle the default jsp servlet instance
+        if (id != null && id.equals("jsp"))
+        {
+            jspServletClass = servlet_class;
+            try
+            {
+                Loader.loadClass(this.getClass(), servlet_class);
+                
+                //Ensure there is a scratch dir
+                if (holder.getInitParameter("scratchdir") == null)
+                {
+                    File tmp = context.getTempDirectory();
+                    File scratch = new File(tmp, "jsp");
+                    if (!scratch.exists()) scratch.mkdir();
+                    holder.setInitParameter("scratchdir", scratch.getAbsolutePath());
+                }
+            }
+            catch (ClassNotFoundException e)
+            {
+                LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class);
+                jspServletClass = servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
+            }
+        }
+        
+       
+        //Set the servlet-class
+        if (servlet_class != null) 
+        {
+            ((WebDescriptor)descriptor).addClassName(servlet_class);
+            
+            Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.servlet-class");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //the class of the servlet has not previously been set, so set it
+                    holder.setClassName(servlet_class);
+                    context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //the class of the servlet was set by a web xml file, only allow web-override/web-default to change it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setClassName(servlet_class);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //the class was set by another fragment, ensure this fragment's value is the same
+                    if (!servlet_class.equals(holder.getClassName()))
+                        throw new IllegalStateException("Conflicting servlet-class "+servlet_class+" in "+descriptor.getResource());
+                    break;
+                }
+            }          
+        }
+
+        // Handle JSP file
+        String jsp_file = node.getString("jsp-file", false, true);
+        if (jsp_file != null)
+        {
+            holder.setForcedPath(jsp_file);
+            ServletHolder jsp=context.getServletHandler().getServlet("jsp");
+            if (jsp!=null)
+                holder.setClassName(jsp.getClassName());
+        }
+
+        // handle load-on-startup 
+        XmlParser.Node startup = node.get("load-on-startup");
+        if (startup != null)
+        {
+            String s = startup.toString(false, true).toLowerCase(Locale.ENGLISH);
+            int order = 0;
+            if (s.startsWith("t"))
+            {
+                LOG.warn("Deprecated boolean load-on-startup.  Please use integer");
+                order = 1; 
+            }
+            else
+            {
+                try
+                {
+                    if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
+                }
+                catch (Exception e)
+                {
+                    LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer");
+                    LOG.ignore(e);
+                }
+            }
+
+            Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.load-on-startup");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //not already set, so set it now
+                    holder.setInitOrder(order);
+                    context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //if it was already set by a web xml descriptor and we're parsing another web xml descriptor, then override it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setInitOrder(order);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //it was already set by another fragment, if we're parsing a fragment, the values must match
+                    if (order != holder.getInitOrder())
+                        throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource());
+                    break;
+                }
+            } 
+        }
+
+        Iterator sRefsIter = node.iterator("security-role-ref");
+        while (sRefsIter.hasNext())
+        {
+            XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
+            String roleName = securityRef.getString("role-name", false, true);
+            String roleLink = securityRef.getString("role-link", false, true);
+            if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
+            {
+                if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
+                Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.role-name."+roleName);
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //set it
+                        holder.setUserRoleLink(roleName, roleLink);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //only another web xml descriptor (web-default,web-override web.xml) can override an already set value
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            holder.setUserRoleLink(roleName, roleLink);
+                            context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        if (!holder.getUserRoleLink(roleName).equals(roleLink))
+                            throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                LOG.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
+            }
+        }
+
+        
+        XmlParser.Node run_as = node.get("run-as");
+        if (run_as != null)
+        { 
+            String roleName = run_as.getString("role-name", false, true);
+
+            if (roleName != null)
+            {
+                Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.run-as");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //run-as not set, so set it
+                        holder.setRunAsRole(roleName);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //run-as was set by a web xml, only allow it to be changed if we're currently parsing another web xml(override/default)
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            holder.setRunAsRole(roleName);
+                            context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //run-as was set by another fragment, this fragment must show the same value
+                        if (!holder.getRunAsRole().equals(roleName))
+                            throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
+                        break;
+                    }    
+                }
+            }
+        }
+
+        String async=node.getString("async-supported",false,true);
+        if (async!=null)
+        {
+            boolean val = async.length()==0||Boolean.valueOf(async);
+            Origin o =context.getMetaData().getOrigin(servlet_name+".servlet.async-supported");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //set it
+                    holder.setAsyncSupported(val);
+                    context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setAsyncSupported(val);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);  
+                    }             
+                    break;
+                }
+                case WebFragment:
+                {
+                    //async-supported set by another fragment, this fragment's value must match
+                    if (holder.isAsyncSupported() != val)
+                        throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+servlet_name+" in "+descriptor.getResource());
+                    break;
+                }
+            }
+        }
+
+        String enabled = node.getString("enabled", false, true);
+        if (enabled!=null)
+        {
+            boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);     
+            Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.enabled");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //hasn't been set yet, so set it                
+                    holder.setEnabled(is_enabled);
+                    context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //was set in a web xml descriptor, only allow override from another web xml descriptor
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setEnabled(is_enabled);   
+                        context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //was set by another fragment, this fragment's value must match
+                    if (holder.isEnabled() != is_enabled)
+                        throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+servlet_name+" in "+descriptor.getResource());
+                    break;
+                }
+            }
+        }
+        
+        /*
+         * If multipart config not set, then set it and record it was by the web.xml or fragment.
+         * If it was set by web.xml then if this is a fragment, ignore the settings.
+         * If it was set by a fragment, if this is a fragment and the values are different, error!
+         */
+        XmlParser.Node multipart = node.get("multipart-config");
+        if (multipart != null)
+        {
+            String location = multipart.getString("location", false, true);
+            String maxFile = multipart.getString("max-file-size", false, true);
+            String maxRequest = multipart.getString("max-request-size", false, true);
+            String threshold = multipart.getString("file-size-threshold",false,true);
+            MultipartConfigElement element = new MultipartConfigElement(location,
+                                                                        (maxFile==null||"".equals(maxFile)?-1L:Long.parseLong(maxFile)),
+                                                                        (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
+                                                                        (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
+            
+            Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.multipart-config");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //hasn't been set, so set it
+                    holder.getRegistration().setMultipartConfig(element);
+                    context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //was set in a web xml, only allow changes if we're parsing another web xml (web.xml/web-default.xml/web-override.xml)
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.getRegistration().setMultipartConfig(element);
+                        context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);  
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //another fragment set the value, this fragment's values must match exactly or it is an error
+                    MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
+                    
+                    if (cfg.getMaxFileSize() != element.getMaxFileSize())
+                        throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+servlet_name+" in "+descriptor.getResource());
+                    if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
+                        throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+servlet_name+" in "+descriptor.getResource());
+                    if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
+                        throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+servlet_name+" in "+descriptor.getResource());
+                    if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
+                            || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
+                        throw new IllegalStateException("Conflicting multipart-config location for servlet "+servlet_name+" in "+descriptor.getResource());
+                    break;
+                }
+            } 
+        }
+    }
+    
+    
+
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitServletMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        //Servlet Spec 3.0, p74
+        //servlet-mappings are always additive, whether from web xml descriptors (web.xml/web-default.xml/web-override.xml) or web-fragments.
+        //Maintenance update 3.0a to spec:
+        //  Updated 8.2.3.g.v to say <servlet-mapping> elements are additive across web-fragments. 
+        //  <servlet-mapping> declared in web.xml overrides the mapping for the servlet specified in the web-fragment.xml
+
+        String servlet_name = node.getString("servlet-name", false, true); 
+        Origin origin = context.getMetaData().getOrigin(servlet_name+".servlet.mappings");
+        
+        switch (origin)
+        {
+            case NotSet:
+            {
+                //no servlet mappings
+                context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor);
+                ServletMapping mapping = addServletMapping(servlet_name, node, context, descriptor);
+                mapping.setDefault(context.getMetaData().getOrigin(servlet_name+".servlet.mappings") == Origin.WebDefaults);
+                break;
+            }
+            case WebXml:
+            case WebDefaults:
+            case WebOverride:
+            {
+                //previously set by a web xml descriptor, if we're parsing another web xml descriptor allow override
+                //otherwise just ignore it
+                if (!(descriptor instanceof FragmentDescriptor))
+                {
+                   addServletMapping(servlet_name, node, context, descriptor);
+                }
+                break;
+            }
+            case WebFragment:
+            {
+                //mappings previously set by another web-fragment, so merge in this web-fragment's mappings
+                addServletMapping(servlet_name, node, context, descriptor);
+                break;
+            }
+        }        
+    }
+    
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitSessionConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        XmlParser.Node tNode = node.get("session-timeout");
+        if (tNode != null)
+        {
+            int timeout = Integer.parseInt(tNode.toString(false, true));
+            context.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout * 60);
+        }
+        
+        //Servlet Spec 3.0 
+        // <tracking-mode>
+        // this is additive across web-fragments
+        Iterator iter = node.iterator("tracking-mode");
+        if (iter.hasNext())
+        { 
+            Set<SessionTrackingMode> modes = null;
+            Origin o = context.getMetaData().getOrigin("session.tracking-mode");
+            switch (o)
+            {
+                case NotSet://not previously set, starting fresh
+                case WebDefaults://previously set in web defaults, allow this descriptor to start fresh
+                {
+                    
+                    modes = new HashSet<SessionTrackingMode>();
+                    context.getMetaData().setOrigin("session.tracking-mode", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebFragment:
+                case WebOverride:
+                {
+                    //if setting from an override descriptor, start afresh, otherwise add-in tracking-modes
+                    if (descriptor instanceof OverrideDescriptor)
+                        modes = new HashSet<SessionTrackingMode>();
+                    else
+                        modes = new HashSet<SessionTrackingMode>(context.getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes());
+                    context.getMetaData().setOrigin("session.tracking-mode", descriptor);
+                    break;
+                }       
+            }
+            
+            while (iter.hasNext())
+            {
+                XmlParser.Node mNode = (XmlParser.Node) iter.next();
+                String trackMode = mNode.toString(false, true);
+                modes.add(SessionTrackingMode.valueOf(trackMode));
+            }
+            context.getSessionHandler().getSessionManager().setSessionTrackingModes(modes);   
+        }
+       
+        
+        //Servlet Spec 3.0 
+        //<cookie-config>
+        XmlParser.Node cookieConfig = node.get("cookie-config");
+        if (cookieConfig != null)
+        {
+            //  <name>
+            String name = cookieConfig.getString("name", false, true);
+            if (name != null)
+            {
+                Origin o = context.getMetaData().getOrigin("cookie-config.name");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><name> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
+                        context.getMetaData().setOrigin("cookie-config.name", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><name> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
+                            context.getMetaData().setOrigin("cookie-config.name", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getName().equals(name))                  
+                            throw new IllegalStateException("Conflicting cookie-config name "+name+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <domain>
+            String domain = cookieConfig.getString("domain", false, true);
+            if (domain != null)
+            {
+                Origin o = context.getMetaData().getOrigin("cookie-config.domain");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><domain> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
+                        context.getMetaData().setOrigin("cookie-config.domain", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><domain> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
+                            context.getMetaData().setOrigin("cookie-config.domain", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getDomain().equals(domain))                  
+                            throw new IllegalStateException("Conflicting cookie-config domain "+domain+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <path>
+            String path = cookieConfig.getString("path", false, true);
+            if (path != null)
+            {
+                Origin o = context.getMetaData().getOrigin("cookie-config.path");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><domain> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
+                        context.getMetaData().setOrigin("cookie-config.path", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><domain> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
+                            context.getMetaData().setOrigin("cookie-config.path", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getPath().equals(path))                  
+                            throw new IllegalStateException("Conflicting cookie-config path "+path+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <comment>
+            String comment = cookieConfig.getString("comment", false, true);
+            if (comment != null)
+            {
+                Origin o = context.getMetaData().getOrigin("cookie-config.comment");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><comment> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
+                        context.getMetaData().setOrigin("cookie-config.comment", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><comment> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
+                            context.getMetaData().setOrigin("cookie-config.comment", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getComment().equals(comment))                  
+                            throw new IllegalStateException("Conflicting cookie-config comment "+comment+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <http-only>true/false
+            tNode = cookieConfig.get("http-only");
+            if (tNode != null)
+            {
+                boolean httpOnly = Boolean.parseBoolean(tNode.toString(false,true));           
+                Origin o = context.getMetaData().getOrigin("cookie-config.http-only");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><http-only> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
+                        context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><http-only> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
+                            context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isHttpOnly() != httpOnly)       
+                            throw new IllegalStateException("Conflicting cookie-config http-only "+httpOnly+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <secure>true/false
+            tNode = cookieConfig.get("secure");
+            if (tNode != null)
+            {
+                boolean secure = Boolean.parseBoolean(tNode.toString(false,true));
+                Origin o = context.getMetaData().getOrigin("cookie-config.secure");
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no <cookie-config><secure> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
+                        context.getMetaData().setOrigin("cookie-config.secure", descriptor);
+                        break;
+                    }                   
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //<cookie-config><secure> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
+                            context.getMetaData().setOrigin("cookie-config.secure", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isSecure() != secure)       
+                            throw new IllegalStateException("Conflicting cookie-config secure "+secure+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+            
+            //  <max-age>
+            tNode = cookieConfig.get("max-age");
+            if (tNode != null)
+            {
+                int maxAge = Integer.parseInt(tNode.toString(false,true));
+                Origin o = context.getMetaData().getOrigin("cookie-config.max-age");
+                switch (o)
+                {
+                    case NotSet:
+                    { 
+                        //no <cookie-config><max-age> set yet, accept it
+                        context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
+                        context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {   
+                        //<cookie-config><max-age> set in a web xml, only allow web-default/web-override to change
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
+                            context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a web-fragment set the value, all web-fragments must have the same value
+                        if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().getMaxAge() != maxAge)
+                            throw new IllegalStateException("Conflicting cookie-config max-age "+maxAge+" in "+descriptor.getResource());
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    
+    
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitMimeMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String extension = node.getString("extension", false, true);
+        if (extension != null && extension.startsWith(".")) 
+            extension = extension.substring(1);
+        String mimeType = node.getString("mime-type", false, true);
+        if (extension != null)
+        {
+            Origin o = context.getMetaData().getOrigin("extension."+extension);
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //no mime-type set for the extension yet
+                    context.getMimeTypes().addMimeMapping(extension, mimeType);
+                    context.getMetaData().setOrigin("extension."+extension, descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //a mime-type was set for the extension in a web xml, only allow web-default/web-override to change
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        context.getMimeTypes().addMimeMapping(extension, mimeType);
+                        context.getMetaData().setOrigin("extension."+extension, descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //a web-fragment set the value, all web-fragments must have the same value
+                    if (!context.getMimeTypes().getMimeByExtension("."+extension).equals(context.getMimeTypes().CACHE.lookup(mimeType)))
+                        throw new IllegalStateException("Conflicting mime-type "+mimeType+" for extension "+extension+" in "+descriptor.getResource());
+                    break;
+                }
+            }
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitWelcomeFileList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        Origin o = context.getMetaData().getOrigin("welcome-file-list");
+        switch (o)
+        {
+            case NotSet:
+            {
+                context.getMetaData().setOrigin("welcome-file-list", descriptor);
+                addWelcomeFiles(context,node);
+                break;
+            }
+            case WebXml:
+            {
+                //web.xml set the welcome-file-list, all other descriptors then just merge in
+                addWelcomeFiles(context,node);
+                break;
+            }
+            case WebDefaults:
+            {
+                //if web-defaults set the welcome-file-list first and
+                //we're processing web.xml then reset the welcome-file-list
+                if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof FragmentDescriptor))
+                {
+                    context.setWelcomeFiles(new String[0]);
+                }
+                addWelcomeFiles(context,node);
+                break;
+            }
+            case WebOverride:
+            {
+                //web-override set the list, all other descriptors just merge in
+                addWelcomeFiles(context,node);
+                break;
+            }
+            case WebFragment:
+            {
+                //A web-fragment first set the welcome-file-list. Other descriptors just add. 
+                addWelcomeFiles(context,node);
+                break;
+            }
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitLocaleEncodingList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        Iterator<XmlParser.Node> iter = node.iterator("locale-encoding-mapping");
+        while (iter.hasNext())
+        {
+            XmlParser.Node mapping = iter.next();
+            String locale = mapping.getString("locale", false, true);
+            String encoding = mapping.getString("encoding", false, true);
+            
+            if (encoding != null)
+            {
+                Origin o = context.getMetaData().getOrigin("locale-encoding."+locale);
+                switch (o)
+                {
+                    case NotSet:
+                    {
+                        //no mapping for the locale yet, so set it
+                        context.addLocaleEncoding(locale, encoding);
+                        context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    {
+                        //a value was set in a web descriptor, only allow another web descriptor to change it (web-default/web-override)
+                        if (!(descriptor instanceof FragmentDescriptor))
+                        {
+                            context.addLocaleEncoding(locale, encoding);
+                            context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
+                        }
+                        break;
+                    }
+                    case WebFragment:
+                    {
+                        //a value was set by a web-fragment, all fragments must have the same value
+                        if (!encoding.equals(context.getLocaleEncoding(locale)))
+                            throw new IllegalStateException("Conflicting loacle-encoding mapping for locale "+locale+" in "+descriptor.getResource());
+                        break;                    
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitErrorPage(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String error = node.getString("error-code", false, true);
+        int code=0;
+        if (error == null || error.length() == 0) 
+        {
+            error = node.getString("exception-type", false, true);
+            if (error == null || error.length() == 0)
+                error = ErrorPageErrorHandler.GLOBAL_ERROR_PAGE;
+        }
+        else
+            code=Integer.valueOf(error);
+        
+        String location = node.getString("location", false, true);
+        ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler();
+        Origin o = context.getMetaData().getOrigin("error."+error);
+        
+        switch (o)
+        {
+            case NotSet:
+            {
+                //no error page setup for this code or exception yet
+                if (code>0)
+                    handler.addErrorPage(code,location);
+                else
+                    handler.addErrorPage(error,location);
+                context.getMetaData().setOrigin("error."+error, descriptor);
+                break;
+            }
+            case WebXml:
+            case WebDefaults:
+            case WebOverride:
+            {
+                //an error page setup was set in web.xml, only allow other web xml descriptors to override it
+                if (!(descriptor instanceof FragmentDescriptor))
+                {
+                    if (descriptor instanceof OverrideDescriptor || descriptor instanceof DefaultsDescriptor)
+                    {
+                        if (code>0)
+                            handler.addErrorPage(code,location);
+                        else
+                            handler.addErrorPage(error,location);
+                        context.getMetaData().setOrigin("error."+error, descriptor);
+                    }
+                    else
+                        throw new IllegalStateException("Duplicate global error-page "+location);
+                }
+                break;
+            }
+            case WebFragment:
+            {
+                //another web fragment set the same error code or exception, if its different its an error
+                if (!handler.getErrorPages().get(error).equals(location))
+                    throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource());
+                break;
+            }
+        }
+       
+    }
+    
+    /**
+     * @param context
+     * @param node
+     */
+    protected void addWelcomeFiles(WebAppContext context, XmlParser.Node node)
+    {
+        Iterator<XmlParser.Node> iter = node.iterator("welcome-file");
+        while (iter.hasNext())
+        {
+            XmlParser.Node indexNode = (XmlParser.Node) iter.next();
+            String welcome = indexNode.toString(false, true);
+            
+            //Servlet Spec 3.0 p. 74 welcome files are additive
+            if (welcome != null && welcome.trim().length() > 0)
+                context.setWelcomeFiles((String[])LazyList.addToArray(context.getWelcomeFiles(),welcome,String.class));
+        }
+    }
+    
+    
+    /**
+     * @param servletName
+     * @param node
+     * @param context
+     */
+    protected ServletMapping addServletMapping (String servletName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
+    {
+        ServletMapping mapping = new ServletMapping();
+        mapping.setServletName(servletName);
+        
+        List<String> paths = new ArrayList<String>();
+        Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
+        while (iter.hasNext())
+        {
+            String p = iter.next().toString(false, true);
+            p = normalizePattern(p);
+            paths.add(p);
+            context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor);
+        }
+        mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
+        context.getServletHandler().addServletMapping(mapping);
+        return mapping;
+    }
+    
+    /**
+     * @param filterName
+     * @param node
+     * @param context
+     */
+    protected void addFilterMapping (String filterName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
+    {
+        FilterMapping mapping = new FilterMapping();
+        mapping.setFilterName(filterName);
+
+        List<String> paths = new ArrayList<String>();
+        Iterator<XmlParser.Node>  iter = node.iterator("url-pattern");
+        while (iter.hasNext())
+        {
+            String p = iter.next().toString(false, true);
+            p = normalizePattern(p);
+            paths.add(p);
+            context.getMetaData().setOrigin(filterName+".filter.mapping."+p, descriptor);
+        }
+        mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
+
+        List<String> names = new ArrayList<String>();
+        iter = node.iterator("servlet-name");
+        while (iter.hasNext())
+        {
+            String n = ((XmlParser.Node) iter.next()).toString(false, true);
+            names.add(n);
+        }
+        mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
+
+        
+        List<DispatcherType> dispatches = new ArrayList<DispatcherType>();
+        iter=node.iterator("dispatcher");
+        while(iter.hasNext())
+        {
+            String d=((XmlParser.Node)iter.next()).toString(false,true);
+            dispatches.add(FilterMapping.dispatch(d));
+        }
+        
+        if (dispatches.size()>0)
+            mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
+
+        context.getServletHandler().addFilterMapping(mapping);
+    }
+    
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitTagLib(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        //Additive across web.xml and web-fragment.xml
+        String uri = node.getString("taglib-uri", false, true);
+        String location = node.getString("taglib-location", false, true);
+
+        context.setResourceAlias(uri, location);
+        
+        JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
+        if (config == null)
+        {
+            config = new JspConfig();
+            context.getServletContext().setJspConfigDescriptor(config);
+        }
+        
+        TagLib tl = new TagLib();
+        tl.setTaglibLocation(location);
+        tl.setTaglibURI(uri);
+        config.addTaglibDescriptor(tl);
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitJspConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {   
+        //Additive across web.xml and web-fragment.xml
+        JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
+        if (config == null)
+        {
+           config = new JspConfig();
+           context.getServletContext().setJspConfigDescriptor(config);
+        }
+        
+        
+        for (int i = 0; i < node.size(); i++)
+        {
+            Object o = node.get(i);
+            if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag())) 
+                visitTagLib(context,descriptor, (XmlParser.Node) o);
+        }
+
+        // Map URLs from jsp property groups to JSP servlet.
+        // this is more JSP stupidness creeping into the servlet spec
+        Iterator<XmlParser.Node> iter = node.iterator("jsp-property-group");
+        List<String> paths = new ArrayList<String>();
+        while (iter.hasNext())
+        {
+            JspPropertyGroup jpg = new JspPropertyGroup();
+            config.addJspPropertyGroup(jpg);
+            XmlParser.Node group = iter.next();
+            
+            //url-patterns
+            Iterator<XmlParser.Node> iter2 = group.iterator("url-pattern");
+            while (iter2.hasNext())
+            {
+                String url = iter2.next().toString(false, true);
+                url = normalizePattern(url);
+                paths.add( url);
+                jpg.addUrlPattern(url);
+            }
+            
+            jpg.setElIgnored(group.getString("el-ignored", false, true));
+            jpg.setPageEncoding(group.getString("page-encoding", false, true));
+            jpg.setScriptingInvalid(group.getString("scripting-invalid", false, true));
+            jpg.setIsXml(group.getString("is-xml", false, true));
+            jpg.setDeferredSyntaxAllowedAsLiteral(group.getString("deferred-syntax-allowed-as-literal", false, true));
+            jpg.setTrimDirectiveWhitespaces(group.getString("trim-directive-whitespaces", false, true));
+            jpg.setDefaultContentType(group.getString("default-content-type", false, true));
+            jpg.setBuffer(group.getString("buffer", false, true));
+            jpg.setErrorOnUndeclaredNamespace(group.getString("error-on-undeclared-namespace", false, true));
+            
+            //preludes
+            Iterator<XmlParser.Node> preludes = group.iterator("include-prelude");
+            while (preludes.hasNext())
+            {
+                String prelude = preludes.next().toString(false, true);
+                jpg.addIncludePrelude(prelude);
+            }
+            //codas
+            Iterator<XmlParser.Node> codas = group.iterator("include-coda");
+            while (codas.hasNext())
+            {
+                String coda = codas.next().toString(false, true);
+                jpg.addIncludeCoda(coda);
+            }
+            
+            if (LOG.isDebugEnabled()) LOG.debug(config.toString());
+        }
+
+        if (paths.size() > 0)
+        {
+            ServletHandler handler = context.getServletHandler();
+            ServletHolder jsp_pg_servlet = handler.getServlet(JspPropertyGroupServlet.NAME);
+            if (jsp_pg_servlet==null)
+            {
+                jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler));
+                handler.addServlet(jsp_pg_servlet);
+            }
+
+            ServletMapping mapping = new ServletMapping();
+            mapping.setServletName(JspPropertyGroupServlet.NAME);
+            mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
+            context.getServletHandler().addServletMapping(mapping);
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitSecurityConstraint(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        Constraint scBase = new Constraint();
+
+        //ServletSpec 3.0, p74 security-constraints, as minOccurs > 1, are additive 
+        //across fragments
+        
+        //TODO: need to remember origin of the constraints
+        try
+        {
+            XmlParser.Node auths = node.get("auth-constraint");
+
+            if (auths != null)
+            {
+                scBase.setAuthenticate(true);
+                // auth-constraint
+                Iterator<XmlParser.Node> iter = auths.iterator("role-name");
+                List<String> roles = new ArrayList<String>();
+                while (iter.hasNext())
+                {
+                    String role = iter.next().toString(false, true);
+                    roles.add(role);
+                }
+                scBase.setRoles(roles.toArray(new String[roles.size()]));
+            }
+
+            XmlParser.Node data = node.get("user-data-constraint");
+            if (data != null)
+            {
+                data = data.get("transport-guarantee");
+                String guarantee = data.toString(false, true).toUpperCase(Locale.ENGLISH);
+                if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
+                    scBase.setDataConstraint(Constraint.DC_NONE);
+                else if ("INTEGRAL".equals(guarantee))
+                    scBase.setDataConstraint(Constraint.DC_INTEGRAL);
+                else if ("CONFIDENTIAL".equals(guarantee))
+                    scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
+                else
+                {
+                    LOG.warn("Unknown user-data-constraint:" + guarantee);
+                    scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
+                }
+            }
+            Iterator<XmlParser.Node> iter = node.iterator("web-resource-collection");
+            while (iter.hasNext())
+            {
+                XmlParser.Node collection =  iter.next();
+                String name = collection.getString("web-resource-name", false, true);
+                Constraint sc = (Constraint) scBase.clone();
+                sc.setName(name);
+
+                Iterator<XmlParser.Node> iter2 = collection.iterator("url-pattern");
+                while (iter2.hasNext())
+                {
+                    String url = iter2.next().toString(false, true);
+                    url = normalizePattern(url);
+                    //remember origin so we can process ServletRegistration.Dynamic.setServletSecurityElement() correctly
+                    context.getMetaData().setOrigin("constraint.url."+url, descriptor);
+                    
+                    Iterator<XmlParser.Node> iter3 = collection.iterator("http-method");
+                    Iterator<XmlParser.Node> iter4 = collection.iterator("http-method-omission");
+                   
+                    if (iter3.hasNext())
+                    {
+                        if (iter4.hasNext())
+                            throw new IllegalStateException ("web-resource-collection cannot contain both http-method and http-method-omission");
+                        
+                        //configure all the http-method elements for each url
+                        while (iter3.hasNext())
+                        {
+                            String method = ((XmlParser.Node) iter3.next()).toString(false, true);
+                            ConstraintMapping mapping = new ConstraintMapping();
+                            mapping.setMethod(method);
+                            mapping.setPathSpec(url);
+                            mapping.setConstraint(sc);                                                      
+                            ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
+                        }
+                    }
+                    else if (iter4.hasNext())
+                    {
+                        //configure all the http-method-omission elements for each url
+                        while (iter4.hasNext())
+                        {
+                            String method = ((XmlParser.Node)iter4.next()).toString(false, true);
+                            ConstraintMapping mapping = new ConstraintMapping();
+                            mapping.setMethodOmissions(new String[]{method});
+                            mapping.setPathSpec(url);
+                            mapping.setConstraint(sc);
+                            ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
+                        }
+                    }
+                    else
+                    {
+                        //No http-methods or http-method-omissions specified, the constraint applies to all
+                        ConstraintMapping mapping = new ConstraintMapping();
+                        mapping.setPathSpec(url);
+                        mapping.setConstraint(sc);
+                        ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
+                    }
+                } 
+            }
+        }
+        catch (CloneNotSupportedException e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     * @throws Exception
+     */
+    protected void visitLoginConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception
+    {
+        //ServletSpec 3.0 p74 says elements present 0/1 time if specified in web.xml take
+        //precendece over any web-fragment. If not specified in web.xml, then if specified
+        //in a web-fragment must be the same across all web-fragments.
+        XmlParser.Node method = node.get("auth-method");
+        if (method != null)
+        {
+            //handle auth-method merge
+            Origin o = context.getMetaData().getOrigin("auth-method");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //not already set, so set it now
+                    context.getSecurityHandler().setAuthMethod(method.toString(false, true));
+                    context.getMetaData().setOrigin("auth-method", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //if it was already set by a web xml descriptor and we're parsing another web xml descriptor, then override it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        context.getSecurityHandler().setAuthMethod(method.toString(false, true));
+                        context.getMetaData().setOrigin("auth-method", descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //it was already set by another fragment, if we're parsing a fragment, the values must match
+                    if (!context.getSecurityHandler().getAuthMethod().equals(method.toString(false, true)))
+                        throw new IllegalStateException("Conflicting auth-method value in "+descriptor.getResource());
+                    break;
+                }
+            } 
+            
+            //handle realm-name merge
+            XmlParser.Node name = node.get("realm-name");
+            String nameStr = (name == null ? "default" : name.toString(false, true));
+            o = context.getMetaData().getOrigin("realm-name");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //no descriptor has set the realm-name yet, so set it
+                    context.getSecurityHandler().setRealmName(nameStr);
+                    context.getMetaData().setOrigin("realm-name", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //set by a web xml file (web.xml/web-default.xm/web-override.xml), only allow it to be changed by another web xml file
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        context.getSecurityHandler().setRealmName(nameStr);
+                        context.getMetaData().setOrigin("realm-name", descriptor); 
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //a fragment set it, and we must be parsing another fragment, so the values must match
+                    if (!context.getSecurityHandler().getRealmName().equals(nameStr))
+                        throw new IllegalStateException("Conflicting realm-name value in "+descriptor.getResource());
+                    break;
+                }
+            }
+ 
+            if (Constraint.__FORM_AUTH.equals(context.getSecurityHandler().getAuthMethod()))
+            {  
+                XmlParser.Node formConfig = node.get("form-login-config");
+                if (formConfig != null)
+                {
+                    String loginPageName = null;
+                    XmlParser.Node loginPage = formConfig.get("form-login-page");
+                    if (loginPage != null) 
+                        loginPageName = loginPage.toString(false, true);
+                    String errorPageName = null;
+                    XmlParser.Node errorPage = formConfig.get("form-error-page");
+                    if (errorPage != null) 
+                        errorPageName = errorPage.toString(false, true);
+                    
+                    //handle form-login-page
+                    o = context.getMetaData().getOrigin("form-login-page");
+                    switch (o)
+                    {
+                        case NotSet:
+                        {
+                            //Never been set before, so accept it
+                            context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
+                            context.getMetaData().setOrigin("form-login-page",descriptor);
+                            break;
+                        }
+                        case WebXml:
+                        case WebDefaults:
+                        case WebOverride:
+                        {
+                            //a web xml descriptor previously set it, only allow another one to change it (web.xml/web-default.xml/web-override.xml)
+                            if (!(descriptor instanceof FragmentDescriptor))
+                            {
+                                context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
+                                context.getMetaData().setOrigin("form-login-page",descriptor);
+                            }
+                            break;
+                        }
+                        case WebFragment:
+                        {
+                            //a web-fragment previously set it. We must be parsing yet another web-fragment, so the values must agree
+                            if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE).equals(loginPageName))
+                                throw new IllegalStateException("Conflicting form-login-page value in "+descriptor.getResource());
+                            break;
+                        }
+                    }
+                    
+                    //handle form-error-page
+                    o = context.getMetaData().getOrigin("form-error-page");
+                    switch (o)
+                    {
+                        case NotSet:
+                        {
+                            //Never been set before, so accept it
+                            context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
+                            context.getMetaData().setOrigin("form-error-page",descriptor);
+                            break;
+                        }
+                        case WebXml:
+                        case WebDefaults:
+                        case WebOverride:
+                        {
+                            //a web xml descriptor previously set it, only allow another one to change it (web.xml/web-default.xml/web-override.xml)
+                            if (!(descriptor instanceof FragmentDescriptor))
+                            {
+                                context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
+                                context.getMetaData().setOrigin("form-error-page",descriptor);
+                            }
+                            break;
+                        }
+                        case WebFragment:
+                        {
+                            //a web-fragment previously set it. We must be parsing yet another web-fragment, so the values must agree
+                            if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE).equals(errorPageName))
+                                throw new IllegalStateException("Conflicting form-error-page value in "+descriptor.getResource());
+                            break;
+                        }
+                    }              
+                }
+                else
+                {
+                    throw new IllegalStateException("!form-login-config");
+                }
+            }
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitSecurityRole(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        //ServletSpec 3.0, p74 elements with multiplicity >1 are additive when merged
+        XmlParser.Node roleNode = node.get("role-name");
+        String role = roleNode.toString(false, true);
+        ((ConstraintAware)context.getSecurityHandler()).addRole(role);
+    }
+    
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String name = node.getString("filter-name", false, true);
+        FilterHolder holder = context.getServletHandler().getFilter(name);
+        if (holder == null)
+        {
+            holder = context.getServletHandler().newFilterHolder(Holder.Source.DESCRIPTOR);
+            holder.setName(name);
+            context.getServletHandler().addFilter(holder);
+        }
+
+        String filter_class = node.getString("filter-class", false, true);
+        if (filter_class != null) 
+        {
+            ((WebDescriptor)descriptor).addClassName(filter_class);
+            
+            Origin o = context.getMetaData().getOrigin(name+".filter.filter-class");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //no class set yet
+                    holder.setClassName(filter_class);
+                    context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //filter class was set in web.xml, only allow other web xml descriptors (override/default) to change it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setClassName(filter_class);
+                        context.getMetaData().setOrigin(name+".filter.filter-class", descriptor); 
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //the filter class was set up by a web fragment, all fragments must be the same
+                    if (!holder.getClassName().equals(filter_class))
+                        throw new IllegalStateException("Conflicting filter-class for filter "+name+" in "+descriptor.getResource());
+                    break;
+                }
+            }
+           
+        }
+
+        Iterator<XmlParser.Node>  iter = node.iterator("init-param");
+        while (iter.hasNext())
+        {
+            XmlParser.Node paramNode = iter.next();
+            String pname = paramNode.getString("param-name", false, true);
+            String pvalue = paramNode.getString("param-value", false, true);
+            
+            Origin origin = context.getMetaData().getOrigin(name+".filter.init-param."+pname);
+            switch (origin)
+            {
+                case NotSet:
+                {
+                    //init-param not already set, so set it
+                    holder.setInitParameter(pname, pvalue); 
+                    context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //previously set by a web xml descriptor, if we're parsing another web xml descriptor allow override
+                    //otherwise just ignore it
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setInitParameter(pname, pvalue); 
+                        context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
+                    }
+                    break;
+                }
+                case WebFragment:
+                {
+                    //previously set by a web-fragment, make sure that the value matches, otherwise its an error
+                    if (!holder.getInitParameter(pname).equals(pvalue))
+                        throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
+                    break;
+                }
+            }  
+        }
+
+        String async=node.getString("async-supported",false,true);
+        if (async!=null)
+            holder.setAsyncSupported(async.length()==0||Boolean.valueOf(async));
+        if (async!=null)
+        {
+            boolean val = async.length()==0||Boolean.valueOf(async);
+            Origin o = context.getMetaData().getOrigin(name+".filter.async-supported");
+            switch (o)
+            {
+                case NotSet:
+                {
+                    //set it
+                    holder.setAsyncSupported(val);
+                    context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
+                    break;
+                }
+                case WebXml:
+                case WebDefaults:
+                case WebOverride:
+                {
+                    //async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
+                    if (!(descriptor instanceof FragmentDescriptor))
+                    {
+                        holder.setAsyncSupported(val);
+                        context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);  
+                    }             
+                    break;
+                }
+                case WebFragment:
+                {
+                    //async-supported set by another fragment, this fragment's value must match
+                    if (holder.isAsyncSupported() != val)
+                        throw new IllegalStateException("Conflicting async-supported="+async+" for filter "+name+" in "+descriptor.getResource());
+                    break;
+                }
+            }
+        }
+        
+    }
+
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitFilterMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        //Servlet Spec 3.0, p74
+        //filter-mappings are always additive, whether from web xml descriptors (web.xml/web-default.xml/web-override.xml) or web-fragments.
+        //Maintenance update 3.0a to spec:
+        //  Updated 8.2.3.g.v to say <servlet-mapping> elements are additive across web-fragments. 
+      
+        
+        String filter_name = node.getString("filter-name", false, true);
+        
+        Origin origin = context.getMetaData().getOrigin(filter_name+".filter.mappings");
+        
+        switch (origin)
+        {
+            case NotSet:
+            {
+                //no filtermappings for this filter yet defined
+                context.getMetaData().setOrigin(filter_name+".filter.mappings", descriptor);
+                addFilterMapping(filter_name, node, context, descriptor);
+                break;
+            }
+            case WebDefaults:
+            case WebOverride:
+            case WebXml:
+            {
+                //filter mappings defined in a web xml file. If we're processing a fragment, we ignore filter mappings.
+                if (!(descriptor instanceof FragmentDescriptor))
+                {
+                   addFilterMapping(filter_name, node, context, descriptor);
+                }
+                break;
+            }
+            case WebFragment:
+            {
+                //filter mappings first defined in a web-fragment, allow other fragments to add
+                addFilterMapping(filter_name, node, context, descriptor);
+                break;
+            }
+        }
+    }
+
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitListener(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        String className = node.getString("listener-class", false, true);
+        EventListener listener = null;
+        try
+        {
+            if (className != null && className.length()> 0)
+            {
+                //Servlet Spec 3.0 p 74
+                //Duplicate listener declarations don't result in duplicate listener instances
+                EventListener[] listeners=context.getEventListeners();
+                if (listeners!=null)
+                {
+                    for (EventListener l : listeners)
+                    {
+                        if (l.getClass().getName().equals(className))
+                            return;
+                    }
+                }
+                
+                ((WebDescriptor)descriptor).addClassName(className);
+
+                Class<? extends EventListener> listenerClass = (Class<? extends EventListener>)context.loadClass(className);
+                listener = newListenerInstance(context,listenerClass);
+                if (!(listener instanceof EventListener))
+                {
+                    LOG.warn("Not an EventListener: " + listener);
+                    return;
+                }
+                context.addEventListener(listener);
+                context.getMetaData().setOrigin(className+".listener", descriptor);
+                
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.warn("Could not instantiate listener " + className, e);
+            return;
+        }
+    }
+    
+    /**
+     * @param context
+     * @param descriptor
+     * @param node
+     */
+    protected void visitDistributable(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+    {
+        // the element has no content, so its simple presence
+        // indicates that the webapp is distributable...
+        //Servlet Spec 3.0 p.74  distributable only if all fragments are distributable
+        ((WebDescriptor)descriptor).setDistributable(true);
+    }
+    
+    /**
+     * @param context
+     * @param clazz
+     * @return the new event listener
+     * @throws ServletException
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     */
+    protected EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws ServletException, InstantiationException, IllegalAccessException
+    {
+        try
+        {
+            return context.getServletContext().createListener(clazz);
+        }
+        catch (ServletException se)
+        {
+            Throwable cause = se.getRootCause();
+            if (cause instanceof InstantiationException)
+                throw (InstantiationException)cause;
+            if (cause instanceof IllegalAccessException)
+                throw (IllegalAccessException)cause;
+            throw se;
+        }
+    }
+    
+    /**
+     * @param p
+     * @return the normalized pattern
+     */
+    protected String normalizePattern(String p)
+    {
+        if (p != null && p.length() > 0 && !p.startsWith("/") && !p.startsWith("*")) return "/" + p;
+        return p;
+    }
+
+  
+}
diff --git a/src/java/org/eclipse/jetty/webapp/TagLibConfiguration.java b/src/java/org/eclipse/jetty/webapp/TagLibConfiguration.java
new file mode 100644
index 0000000..b545530
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/TagLibConfiguration.java
@@ -0,0 +1,530 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlParser;
+
+/* ------------------------------------------------------------ */
+/** TagLibConfiguration.
+ * 
+ * The class searches for TLD descriptors found in web.xml, in WEB-INF/*.tld files of the web app
+ * or *.tld files within jars found in WEB-INF/lib of the webapp.   Any listeners defined in these
+ * tld's are added to the context.
+ * 
+ * &lt;bile&gt;This is total rubbish special case for JSPs! If there was a general use-case for web app
+ * frameworks to register listeners directly, then a generic mechanism could have been added to the servlet
+ * spec.  Instead some special purpose JSP support is required that breaks all sorts of encapsulation rules as
+ * the servlet container must go searching for and then parsing the descriptors for one particular framework.
+ * It only appears to be used by JSF, which is being developed by the same developer who implemented this
+ * feature in the first place!
+ * &lt;/bile&gt;
+ * 
+ * 
+ * Note- this has been superceded by the new TldScanner in jasper which uses ServletContainerInitializer to
+ * find all the listeners in tag libs and register them.
+ */
+public class TagLibConfiguration extends AbstractConfiguration
+{
+    private static final Logger LOG = Log.getLogger(TagLibConfiguration.class);
+
+    public static final String TLD_RESOURCES = "org.eclipse.jetty.tlds";
+    
+  
+    /**
+     * TagLibListener
+     *
+     * A listener that does the job of finding .tld files that contain
+     * (other) listeners that need to be called by the servlet container.
+     * 
+     * This implementation is necessitated by the fact that it is only
+     * after all the Configuration classes have run that we will
+     * parse web.xml/fragments etc and thus find tlds mentioned therein.
+     * 
+     * Note: TagLibConfiguration is not used in jetty-8 as jasper (JSP engine)
+     * uses the new TldScanner class - a ServletContainerInitializer from
+     * Servlet Spec 3 - to find all listeners in taglibs and register them
+     * with the servlet container.
+     */
+    public  class TagLibListener implements ServletContextListener {
+        private List<EventListener> _tldListeners;
+        private WebAppContext _context;       
+        
+        public TagLibListener (WebAppContext context) {
+            _context = context;
+        }
+
+        public void contextDestroyed(ServletContextEvent sce)
+        {
+            if (_tldListeners == null)
+                return;
+            
+            for (int i=_tldListeners.size()-1; i>=0; i--) {
+                EventListener l = _tldListeners.get(i);
+                if (l instanceof ServletContextListener) {
+                    ((ServletContextListener)l).contextDestroyed(sce);
+                }
+            }
+        }
+
+        public void contextInitialized(ServletContextEvent sce)
+        {
+            try 
+            {
+                //For jasper 2.1: 
+                //Get the system classpath tlds and tell jasper about them, if jasper is on the classpath
+                try
+                {
+
+                    ClassLoader loader = _context.getClassLoader();
+                    if (loader == null || loader.getParent() == null)
+                        loader = getClass().getClassLoader();
+                    else
+                        loader = loader.getParent();
+                    Class<?> clazz = loader.loadClass("org.apache.jasper.compiler.TldLocationsCache");
+                    assert clazz!=null;
+                    Collection<Resource> tld_resources = (Collection<Resource>)_context.getAttribute(TLD_RESOURCES);
+                   
+                    Map<URI, List<String>> tldMap = new HashMap<URI, List<String>>();
+                    
+                    if (tld_resources != null)
+                    {
+                        //get the jar file names of the files
+                        for (Resource r:tld_resources)
+                        {
+                            Resource jarResource = extractJarResource(r);
+                            //jasper is happy with an empty list of tlds
+                            if (!tldMap.containsKey(jarResource.getURI()))
+                                tldMap.put(jarResource.getURI(), null);
+
+                        }
+                        //set the magic context attribute that tells jasper about the system tlds
+                        sce.getServletContext().setAttribute("com.sun.appserv.tld.map", tldMap);
+                    }
+                }
+                catch (ClassNotFoundException e)
+                {
+                    LOG.ignore(e);
+                }
+               
+                //find the tld files and parse them to get out their
+                //listeners
+                Set<Resource> tlds = findTldResources();
+                List<TldDescriptor> descriptors = parseTlds(tlds);
+                processTlds(descriptors);
+                
+                if (_tldListeners == null)
+                    return;
+                
+                //call the listeners that are ServletContextListeners, put the
+                //rest into the context's list of listeners to call at the appropriate
+                //moment
+                for (EventListener l:_tldListeners) {
+                    if (l instanceof ServletContextListener) {
+                        ((ServletContextListener)l).contextInitialized(sce);
+                    } else {
+                        _context.addEventListener(l);
+                    }
+                }
+                
+            } 
+            catch (Exception e) {
+                LOG.warn(e);
+            }
+        }
+
+
+        
+        
+        private Resource extractJarResource (Resource r)
+        {
+            if (r == null)
+                return null;
+            
+            try
+            {
+                String url = r.getURI().toURL().toString();
+                int idx = url.lastIndexOf("!/");
+                if (idx >= 0)
+                    url = url.substring(0, idx);
+                if (url.startsWith("jar:"))
+                    url = url.substring(4);
+                return Resource.newResource(url);
+            }
+            catch (IOException e)
+            {
+                LOG.warn(e);
+                return null;
+            }
+        }
+    
+        /**
+         * Find all the locations that can harbour tld files that may contain
+         * a listener which the web container is supposed to instantiate and
+         * call.
+         * 
+         * @return
+         * @throws IOException
+         */
+        private Set<Resource> findTldResources () throws IOException {
+            
+            Set<Resource> tlds = new HashSet<Resource>();
+            
+            // Find tld's from web.xml
+            // When web.xml was processed, it should have created aliases for all TLDs.  So search resources aliases
+            // for aliases ending in tld
+            if (_context.getResourceAliases()!=null && 
+                    _context.getBaseResource()!=null && 
+                    _context.getBaseResource().exists())
+            {
+                Iterator<String> iter=_context.getResourceAliases().values().iterator();
+                while(iter.hasNext())
+                {
+                    String location = iter.next();
+                    if (location!=null && location.toLowerCase(Locale.ENGLISH).endsWith(".tld"))
+                    {
+                        if (!location.startsWith("/"))
+                            location="/WEB-INF/"+location;
+                        Resource l=_context.getBaseResource().addPath(location);
+                        tlds.add(l);
+                    }
+                }
+            }
+            
+            // Look for any tlds in WEB-INF directly.
+            Resource web_inf = _context.getWebInf();
+            if (web_inf!=null)
+            {
+                String[] contents = web_inf.list();
+                for (int i=0;contents!=null && i<contents.length;i++)
+                {
+                    if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld"))
+                    {
+                        Resource l=web_inf.addPath(contents[i]);
+                        tlds.add(l);
+                    }
+                }
+            }
+            
+            //Look for tlds in common location of WEB-INF/tlds
+            if (web_inf != null) {
+                Resource web_inf_tlds = _context.getWebInf().addPath("/tlds/");
+                if (web_inf_tlds.exists() && web_inf_tlds.isDirectory()) {
+                    String[] contents = web_inf_tlds.list();
+                    for (int i=0;contents!=null && i<contents.length;i++)
+                    {
+                        if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld"))
+                        {
+                            Resource l=web_inf_tlds.addPath(contents[i]);
+                            tlds.add(l);
+                        }
+                    }
+                } 
+            }
+
+            // Add in tlds found in META-INF of jars. The jars that will be scanned are controlled by
+            // the patterns defined in the context attributes: org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern,
+            // and org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern
+            @SuppressWarnings("unchecked")
+            Collection<Resource> tld_resources=(Collection<Resource>)_context.getAttribute(TLD_RESOURCES);
+            if (tld_resources!=null)
+                tlds.addAll(tld_resources);
+            
+            return tlds;
+        }
+        
+        
+        /**
+         * Parse xml into in-memory tree
+         * @param tlds
+         * @return
+         */
+        private List<TldDescriptor> parseTlds (Set<Resource> tlds) {         
+            List<TldDescriptor> descriptors = new ArrayList<TldDescriptor>();
+            
+            Resource tld = null;
+            Iterator<Resource> iter = tlds.iterator();
+            while (iter.hasNext())
+            {
+                try
+                {
+                    tld = iter.next();
+                    if (LOG.isDebugEnabled()) LOG.debug("TLD="+tld);
+                   
+                    TldDescriptor d = new TldDescriptor(tld);
+                    d.parse();
+                    descriptors.add(d);
+                }
+                catch(Exception e)
+                {
+                    LOG.warn("Unable to parse TLD: " + tld,e);
+                }
+            }
+            return descriptors;
+        }
+        
+        
+        /**
+         * Create listeners from the parsed tld trees
+         * @param descriptors
+         * @throws Exception
+         */
+        private void processTlds (List<TldDescriptor> descriptors) throws Exception {
+
+            TldProcessor processor = new TldProcessor();
+            for (TldDescriptor d:descriptors)
+                processor.process(_context, d); 
+            
+            _tldListeners = new ArrayList<EventListener>(processor.getListeners());
+        }
+    }
+    
+    
+    
+    
+    /**
+     * TldDescriptor
+     *
+     *
+     */
+    public static class TldDescriptor extends Descriptor
+    {
+        protected static XmlParser __parserSingleton;
+
+        public TldDescriptor(Resource xml)
+        {
+            super(xml);
+        }
+
+        @Override
+        public void ensureParser() throws ClassNotFoundException
+        {
+           if (__parserSingleton == null)
+               __parserSingleton = newParser();
+            _parser = __parserSingleton;
+        }
+
+        @Override
+        public XmlParser newParser() throws ClassNotFoundException
+        {
+            // Create a TLD parser
+            XmlParser parser = new XmlParser(false);
+            
+            URL taglib11=null;
+            URL taglib12=null;
+            URL taglib20=null;
+            URL taglib21=null;
+
+            try
+            {
+                Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
+                taglib11=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd");
+                taglib12=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd");
+                taglib20=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd");
+                taglib21=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd");
+            }
+            catch(Exception e)
+            {
+                LOG.ignore(e);
+            }
+            finally
+            {
+                if(taglib11==null)
+                    taglib11=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd",true);
+                if(taglib12==null)
+                    taglib12=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd",true);
+                if(taglib20==null)
+                    taglib20=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd",true);
+                if(taglib21==null)
+                    taglib21=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd",true);
+            }
+            
+
+            if(taglib11!=null)
+            {
+                redirect(parser, "web-jsptaglib_1_1.dtd",taglib11);  
+                redirect(parser, "web-jsptaglibrary_1_1.dtd",taglib11);
+            }
+            if(taglib12!=null)
+            {
+                redirect(parser, "web-jsptaglib_1_2.dtd",taglib12);
+                redirect(parser, "web-jsptaglibrary_1_2.dtd",taglib12);
+            }
+            if(taglib20!=null)
+            {
+                redirect(parser, "web-jsptaglib_2_0.xsd",taglib20);
+                redirect(parser, "web-jsptaglibrary_2_0.xsd",taglib20);
+            }
+            if(taglib21!=null)
+            {
+                redirect(parser, "web-jsptaglib_2_1.xsd",taglib21);
+                redirect(parser, "web-jsptaglibrary_2_1.xsd",taglib21);
+            }
+            
+            parser.setXpath("/taglib/listener/listener-class");
+            return parser;
+        }
+        
+        public void parse ()
+        throws Exception
+        {
+            ensureParser();
+            try
+            {
+                //xerces on apple appears to sometimes close the zip file instead
+                //of the inputstream, so try opening the input stream, but if
+                //that doesn't work, fallback to opening a new url
+                _root = _parser.parse(_xml.getInputStream());
+            }
+            catch (Exception e)
+            {
+                _root = _parser.parse(_xml.getURL().toString());
+            }
+
+            if (_root==null)
+            {
+                LOG.warn("No TLD root in {}",_xml);
+            }
+        }
+    }
+    
+    
+    /**
+     * TldProcessor
+     *
+     * Process TldDescriptors representing tag libs to find listeners.
+     */
+    public class TldProcessor extends IterativeDescriptorProcessor
+    {
+        public static final String TAGLIB_PROCESSOR = "org.eclipse.jetty.tagLibProcessor";
+        XmlParser _parser;
+        List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>();
+        List<EventListener> _listeners;
+        
+        
+        public TldProcessor ()
+        throws Exception
+        {  
+            _listeners = new ArrayList<EventListener>();
+            registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener", __signature));
+        }
+      
+
+        public void visitListener (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
+        {     
+            String className=node.getString("listener-class",false,true);
+            if (LOG.isDebugEnabled()) 
+                LOG.debug("listener="+className);
+
+            try
+            {
+                Class<?> listenerClass = context.loadClass(className);
+                EventListener l = (EventListener)listenerClass.newInstance();
+                _listeners.add(l);
+            }
+            catch(Exception e)
+            {
+                LOG.warn("Could not instantiate listener "+className+": "+e);
+                LOG.debug(e);
+            }
+            catch(Error e)
+            {
+                LOG.warn("Could not instantiate listener "+className+": "+e);
+                LOG.debug(e);
+            }
+
+        }
+
+        @Override
+        public void end(WebAppContext context, Descriptor descriptor)
+        {
+        }
+
+        @Override
+        public void start(WebAppContext context, Descriptor descriptor)
+        {  
+        }
+        
+        public List<EventListener> getListeners() {
+            return _listeners;
+        }
+    }
+
+
+    @Override
+    public void preConfigure(WebAppContext context) throws Exception
+    {
+        try
+        {
+            Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
+        }
+        catch (Exception e)
+        {
+            //no jsp available, don't parse TLDs
+            return;
+        }
+
+        TagLibListener tagLibListener = new TagLibListener(context);
+        context.addEventListener(tagLibListener);
+    }
+    
+
+    @Override
+    public void configure (WebAppContext context) throws Exception
+    {         
+    }
+
+    @Override
+    public void postConfigure(WebAppContext context) throws Exception
+    {     
+    }
+
+
+    @Override
+    public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
+    {
+    }
+
+
+    @Override
+    public void deconfigure(WebAppContext context) throws Exception
+    {
+    } 
+}
diff --git a/src/java/org/eclipse/jetty/webapp/WebAppClassLoader.java b/src/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
new file mode 100644
index 0000000..c4abbc8
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/WebAppClassLoader.java
@@ -0,0 +1,449 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+
+
+/* ------------------------------------------------------------ */
+/** ClassLoader for HttpContext.
+ * Specializes URLClassLoader with some utility and file mapping
+ * methods.
+ *
+ * This loader defaults to the 2.3 servlet spec behavior where non
+ * system classes are loaded from the classpath in preference to the
+ * parent loader.  Java2 compliant loading, where the parent loader
+ * always has priority, can be selected with the 
+ * {@link org.eclipse.jetty.webapp.WebAppContext#setParentLoaderPriority(boolean)} 
+ * method and influenced with {@link WebAppContext#isServerClass(String)} and 
+ * {@link WebAppContext#isSystemClass(String)}.
+ *
+ * If no parent class loader is provided, then the current thread 
+ * context classloader will be used.  If that is null then the 
+ * classloader that loaded this class is used as the parent.
+ * 
+ */
+public class WebAppClassLoader extends URLClassLoader
+{
+    private static final Logger LOG = Log.getLogger(WebAppClassLoader.class);
+
+    private final Context _context;
+    private final ClassLoader _parent;
+    private final Set<String> _extensions=new HashSet<String>();
+    private String _name=String.valueOf(hashCode());
+    
+    /* ------------------------------------------------------------ */
+    /** The Context in which the classloader operates.
+     */
+    public interface Context
+    {
+        /* ------------------------------------------------------------ */
+        /** Convert a URL or path to a Resource.
+         * The default implementation
+         * is a wrapper for {@link Resource#newResource(String)}.
+         * @param urlOrPath The URL or path to convert
+         * @return The Resource for the URL/path
+         * @throws IOException The Resource could not be created.
+         */
+        Resource newResource(String urlOrPath) throws IOException;
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @return Returns the permissions.
+         */
+        PermissionCollection getPermissions();
+
+        /* ------------------------------------------------------------ */
+        /** Is the class a System Class.
+         * A System class is a class that is visible to a webapplication,
+         * but that cannot be overridden by the contents of WEB-INF/lib or
+         * WEB-INF/classes 
+         * @param clazz The fully qualified name of the class.
+         * @return True if the class is a system class.
+         */
+        boolean isSystemClass(String clazz);
+
+        /* ------------------------------------------------------------ */
+        /** Is the class a Server Class.
+         * A Server class is a class that is part of the implementation of 
+         * the server and is NIT visible to a webapplication. The web
+         * application may provide it's own implementation of the class,
+         * to be loaded from WEB-INF/lib or WEB-INF/classes 
+         * @param clazz The fully qualified name of the class.
+         * @return True if the class is a server class.
+         */
+        boolean isServerClass(String clazz);
+
+        /* ------------------------------------------------------------ */
+        /**
+         * @return True if the classloader should delegate first to the parent 
+         * classloader (standard java behaviour) or false if the classloader 
+         * should first try to load from WEB-INF/lib or WEB-INF/classes (servlet 
+         * spec recommendation).
+         */
+        boolean isParentLoaderPriority();
+        
+        /* ------------------------------------------------------------ */
+        String getExtraClasspath();
+        
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     */
+    public WebAppClassLoader(Context context)
+        throws IOException
+    {
+        this(null,context);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor.
+     */
+    public WebAppClassLoader(ClassLoader parent, Context context)
+        throws IOException
+    {
+        super(new URL[]{},parent!=null?parent
+                :(Thread.currentThread().getContextClassLoader()!=null?Thread.currentThread().getContextClassLoader()
+                        :(WebAppClassLoader.class.getClassLoader()!=null?WebAppClassLoader.class.getClassLoader()
+                                :ClassLoader.getSystemClassLoader())));
+        _parent=getParent();
+        _context=context;
+        if (_parent==null)
+            throw new IllegalArgumentException("no parent classloader!");
+        
+        _extensions.add(".jar");
+        _extensions.add(".zip");
+        
+        // TODO remove this system property
+        String extensions = System.getProperty(WebAppClassLoader.class.getName() + ".extensions");
+        if(extensions!=null)
+        {
+            StringTokenizer tokenizer = new StringTokenizer(extensions, ",;");
+            while(tokenizer.hasMoreTokens())
+                _extensions.add(tokenizer.nextToken().trim());
+        }
+        
+        if (context.getExtraClasspath()!=null)
+            addClassPath(context.getExtraClasspath());
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the name of the classloader
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name the name of the classloader
+     */
+    public void setName(String name)
+    {
+        _name=name;
+    }
+    
+
+    /* ------------------------------------------------------------ */
+    public Context getContext()
+    {
+        return _context;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param resource Comma or semicolon separated path of filenames or URLs
+     * pointing to directories or jar files. Directories should end
+     * with '/'.
+     */
+    public void addClassPath(Resource resource)
+        throws IOException
+    {
+        if (resource instanceof ResourceCollection)
+        {
+            for (Resource r : ((ResourceCollection)resource).getResources())
+                addClassPath(r);
+        }
+        else
+        {
+            addClassPath(resource.toString());
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param classPath Comma or semicolon separated path of filenames or URLs
+     * pointing to directories or jar files. Directories should end
+     * with '/'.
+     */
+    public void addClassPath(String classPath)
+    	throws IOException
+    {
+        if (classPath == null)
+            return;
+            
+        StringTokenizer tokenizer= new StringTokenizer(classPath, ",;");
+        while (tokenizer.hasMoreTokens())
+        {
+            Resource resource= _context.newResource(tokenizer.nextToken().trim());
+            if (LOG.isDebugEnabled())
+                LOG.debug("Path resource=" + resource);
+
+            // Add the resource
+            if (resource.isDirectory() && resource instanceof ResourceCollection)
+                addClassPath(resource);
+            else
+            {
+                // Resolve file path if possible
+                File file= resource.getFile();
+                if (file != null)
+                {
+                    URL url= resource.getURL();
+                    addURL(url);
+                }
+                else if (resource.isDirectory())
+                    addURL(resource.getURL());
+                else
+                    throw new IllegalArgumentException("!file: "+resource);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param file Checks if this file type can be added to the classpath.
+     */
+    private boolean isFileSupported(String file)
+    {
+        int dot = file.lastIndexOf('.');
+        return dot!=-1 && _extensions.contains(file.substring(dot));
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add elements to the class path for the context from the jar and zip files found
+     *  in the specified resource.
+     * @param lib the resource that contains the jar and/or zip files.
+     */
+    public void addJars(Resource lib)
+    {
+        if (lib.exists() && lib.isDirectory())
+        {
+            String[] files=lib.list();
+            for (int f=0;files!=null && f<files.length;f++)
+            {
+                try 
+                {
+                    Resource fn=lib.addPath(files[f]);
+                    String fnlc=fn.getName().toLowerCase(Locale.ENGLISH);
+                    // don't check if this is a directory, see Bug 353165
+                    if (isFileSupported(fnlc))
+                    {
+                        String jar=fn.toString();
+                        jar=StringUtil.replace(jar, ",", "%2C");
+                        jar=StringUtil.replace(jar, ";", "%3B");
+                        addClassPath(jar);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LOG.warn(Log.EXCEPTION,ex);
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public PermissionCollection getPermissions(CodeSource cs)
+    {
+        // TODO check CodeSource
+        PermissionCollection permissions=_context.getPermissions();
+        PermissionCollection pc= (permissions == null) ? super.getPermissions(cs) : permissions;
+        return pc;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Enumeration<URL> getResources(String name) throws IOException
+    {
+        boolean system_class=_context.isSystemClass(name);
+        boolean server_class=_context.isServerClass(name);
+        
+        List<URL> from_parent = toList(server_class?null:_parent.getResources(name));
+        List<URL> from_webapp = toList((system_class&&!from_parent.isEmpty())?null:this.findResources(name));
+            
+        if (_context.isParentLoaderPriority())
+        {
+            from_parent.addAll(from_webapp);
+            return Collections.enumeration(from_parent);
+        }
+        from_webapp.addAll(from_parent);
+        return Collections.enumeration(from_webapp);
+    }
+
+    /* ------------------------------------------------------------ */
+    private List<URL> toList(Enumeration<URL> e)
+    {
+        if (e==null)
+            return new ArrayList<URL>();
+        return Collections.list(e);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a resource from the classloader
+     * 
+     * NOTE: this method provides a convenience of hacking off a leading /
+     * should one be present. This is non-standard and it is recommended 
+     * to not rely on this behavior
+     */
+    public URL getResource(String name)
+    {
+        URL url= null;
+        boolean tried_parent= false;
+        boolean system_class=_context.isSystemClass(name);
+        boolean server_class=_context.isServerClass(name);
+        
+        if (system_class && server_class)
+            return null;
+        
+        if (_parent!=null &&(_context.isParentLoaderPriority() || system_class ) && !server_class)
+        {
+            tried_parent= true;
+            
+            if (_parent!=null)
+                url= _parent.getResource(name);
+        }
+
+        if (url == null)
+        {
+            url= this.findResource(name);
+
+            if (url == null && name.startsWith("/"))
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("HACK leading / off " + name);
+                url= this.findResource(name.substring(1));
+            }
+        }
+
+        if (url == null && !tried_parent && !server_class )
+        {
+            if (_parent!=null)
+                url= _parent.getResource(name);
+        }
+
+        if (url != null)
+            if (LOG.isDebugEnabled())
+                LOG.debug("getResource("+name+")=" + url);
+
+        return url;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public Class<?> loadClass(String name) throws ClassNotFoundException
+    {
+        return loadClass(name, false);
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
+    {
+        Class<?> c= findLoadedClass(name);
+        ClassNotFoundException ex= null;
+        boolean tried_parent= false;
+        
+        boolean system_class=_context.isSystemClass(name);
+        boolean server_class=_context.isServerClass(name);
+        
+        if (system_class && server_class)
+        {
+            return null;
+        }
+        
+        if (c == null && _parent!=null && (_context.isParentLoaderPriority() || system_class) && !server_class)
+        {
+            tried_parent= true;
+            try
+            {
+                c= _parent.loadClass(name);
+                if (LOG.isDebugEnabled())
+                    LOG.debug("loaded " + c);
+            }
+            catch (ClassNotFoundException e)
+            {
+                ex= e;
+            }
+        }
+
+        if (c == null)
+        {
+            try
+            {
+                c= this.findClass(name);
+            }
+            catch (ClassNotFoundException e)
+            {
+                ex= e;
+            }
+        }
+
+        if (c == null && _parent!=null && !tried_parent && !server_class )
+            c= _parent.loadClass(name);
+
+        if (c == null)
+            throw ex;
+
+        if (resolve)
+            resolveClass(c);
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("loaded " + c+ " from "+c.getClassLoader());
+        
+        return c;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String toString()
+    {
+        return "WebAppClassLoader=" + _name+"@"+Long.toHexString(hashCode());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/WebAppContext.java b/src/java/org/eclipse/jetty/webapp/WebAppContext.java
new file mode 100644
index 0000000..0caec5b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/WebAppContext.java
@@ -0,0 +1,1377 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.HttpMethodConstraintElement;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRegistration.Dynamic;
+import javax.servlet.ServletSecurityElement;
+import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
+import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.eclipse.jetty.security.ConstraintAware;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HandlerContainer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.MultiException;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+import org.eclipse.jetty.util.security.Constraint;
+
+/* ------------------------------------------------------------ */
+/** Web Application Context Handler.
+ * The WebAppContext handler is an extension of ContextHandler that
+ * coordinates the construction and configuration of nested handlers:
+ * {@link org.eclipse.jetty.security.ConstraintSecurityHandler}, {@link org.eclipse.jetty.server.session.SessionHandler}
+ * and {@link org.eclipse.jetty.servlet.ServletHandler}.
+ * The handlers are configured by pluggable configuration classes, with
+ * the default being  {@link org.eclipse.jetty.webapp.WebXmlConfiguration} and
+ * {@link org.eclipse.jetty.webapp.JettyWebXmlConfiguration}.
+ *
+ * @org.apache.xbean.XBean description="Creates a servlet web application at a given context from a resource base"
+ *
+ */
+public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
+{
+    private static final Logger LOG = Log.getLogger(WebAppContext.class);
+
+    public static final String TEMPDIR = "javax.servlet.context.tempdir";
+    public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
+    public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
+    public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
+    public final static String SERVER_CONFIG = "org.eclipse.jetty.webapp.configuration";
+    public final static String SERVER_SYS_CLASSES = "org.eclipse.jetty.webapp.systemClasses";
+    public final static String SERVER_SRV_CLASSES = "org.eclipse.jetty.webapp.serverClasses";
+    
+    private String[] __dftProtectedTargets = {"/web-inf", "/meta-inf"};
+    
+    private static String[] __dftConfigurationClasses =
+    {
+        "org.eclipse.jetty.webapp.WebInfConfiguration",
+        "org.eclipse.jetty.webapp.WebXmlConfiguration",
+        "org.eclipse.jetty.webapp.MetaInfConfiguration",
+        "org.eclipse.jetty.webapp.FragmentConfiguration",
+        "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"//,
+        //"org.eclipse.jetty.webapp.TagLibConfiguration"
+    } ;
+
+    // System classes are classes that cannot be replaced by
+    // the web application, and they are *always* loaded via
+    // system classloader.
+    public final static String[] __dftSystemClasses =
+    {
+        "java.",                            // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+        "javax.",                           // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
+        "org.xml.",                         // needed by javax.xml
+        "org.w3c.",                         // needed by javax.xml
+        "org.apache.commons.logging.",      // TODO: review if special case still needed
+        "org.eclipse.jetty.continuation.",  // webapp cannot change continuation classes
+        "org.eclipse.jetty.jndi.",          // webapp cannot change naming classes
+        "org.eclipse.jetty.plus.jaas.",     // webapp cannot change jaas classes
+        "org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension
+        "org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension
+        "org.eclipse.jetty.websocket.WebSocketServlet", // webapp cannot change WebSocketServlet
+        "org.eclipse.jetty.servlet.DefaultServlet" // webapp cannot change default servlets
+    } ;
+
+    // Server classes are classes that are hidden from being
+    // loaded by the web application using system classloader,
+    // so if web application needs to load any of such classes,
+    // it has to include them in its distribution.
+    public final static String[] __dftServerClasses =
+    {
+        "-org.eclipse.jetty.continuation.", // don't hide continuation classes
+        "-org.eclipse.jetty.jndi.",         // don't hide naming classes
+        "-org.eclipse.jetty.plus.jaas.",    // don't hide jaas classes
+        "-org.eclipse.jetty.websocket.WebSocket", // WebSocket is a jetty extension
+        "-org.eclipse.jetty.websocket.WebSocketFactory", // WebSocket is a jetty extension
+        "-org.eclipse.jetty.websocket.WebSocketServlet", // don't hide WebSocketServlet
+        "-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet
+        "-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners
+        "org.eclipse.jetty."                // hide other jetty classes
+    } ;
+
+    private String[] _configurationClasses = __dftConfigurationClasses;
+    private ClasspathPattern _systemClasses = null;
+    private ClasspathPattern _serverClasses = null;
+
+    private Configuration[] _configurations;
+    private String _defaultsDescriptor=WEB_DEFAULTS_XML;
+    private String _descriptor=null;
+    private final List<String> _overrideDescriptors = new ArrayList<String>();
+    private boolean _distributable=false;
+    private boolean _extractWAR=true;
+    private boolean _copyDir=false;
+    private boolean _copyWebInf=false; // TODO change to true?
+    private boolean _logUrlOnStart =false;
+    private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
+    private PermissionCollection _permissions;
+
+    private String[] _contextWhiteList = null;
+
+    private File _tmpDir;
+    private String _war;
+    private String _extraClasspath;
+    private Throwable _unavailableException;
+
+    private Map<String, String> _resourceAliases;
+    private boolean _ownClassLoader=false;
+    private boolean _configurationDiscovered=true;
+    private boolean _configurationClassesSet=false;
+    private boolean _configurationsSet=false;
+    private boolean _allowDuplicateFragmentNames = false;
+    private boolean _throwUnavailableOnStartupException = false;
+    
+    
+
+    private MetaData _metadata=new MetaData();
+
+    public static WebAppContext getCurrentWebAppContext()
+    {
+        ContextHandler.Context context=ContextHandler.getCurrentContext();
+        if (context!=null)
+        {
+            ContextHandler handler = context.getContextHandler();
+            if (handler instanceof WebAppContext)
+                return (WebAppContext)handler;
+        }
+        return null;
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebAppContext()
+    {
+        super(SESSIONS|SECURITY);
+        _scontext=new Context();
+        setErrorHandler(new ErrorPageErrorHandler());
+        setProtectedTargets(__dftProtectedTargets);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param contextPath The context path
+     * @param webApp The URL or filename of the webapp directory or war file.
+     */
+    public WebAppContext(String webApp,String contextPath)
+    {
+        super(null,contextPath,SESSIONS|SECURITY);
+        _scontext=new Context();
+        setContextPath(contextPath);
+        setWar(webApp);
+        setErrorHandler(new ErrorPageErrorHandler());
+        setProtectedTargets(__dftProtectedTargets);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param parent The parent HandlerContainer.
+     * @param contextPath The context path
+     * @param webApp The URL or filename of the webapp directory or war file.
+     */
+    public WebAppContext(HandlerContainer parent, String webApp, String contextPath)
+    {
+        super(parent,contextPath,SESSIONS|SECURITY);
+        _scontext=new Context();
+        setWar(webApp);
+        setErrorHandler(new ErrorPageErrorHandler());
+        setProtectedTargets(__dftProtectedTargets);
+    }
+
+    /* ------------------------------------------------------------ */
+
+    /**
+     * This constructor is used in the geronimo integration.
+     *
+     * @param sessionHandler SessionHandler for this web app
+     * @param securityHandler SecurityHandler for this web app
+     * @param servletHandler ServletHandler for this web app
+     * @param errorHandler ErrorHandler for this web app
+     */
+    public WebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler) {
+        super(null, sessionHandler, securityHandler, servletHandler, errorHandler);
+        _scontext = new Context();
+        setErrorHandler(errorHandler != null ? errorHandler : new ErrorPageErrorHandler());
+        setProtectedTargets(__dftProtectedTargets);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param servletContextName The servletContextName to set.
+     */
+    @Override
+    public void setDisplayName(String servletContextName)
+    {
+        super.setDisplayName(servletContextName);
+        ClassLoader cl = getClassLoader();
+        if (cl!=null && cl instanceof WebAppClassLoader && servletContextName!=null)
+            ((WebAppClassLoader)cl).setName(servletContextName);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get an exception that caused the webapp to be unavailable
+     * @return A throwable if the webapp is unavailable or null
+     */
+    public Throwable getUnavailableException()
+    {
+        return _unavailableException;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Set Resource Alias.
+     * Resource aliases map resource uri's within a context.
+     * They may optionally be used by a handler when looking for
+     * a resource.
+     * @param alias
+     * @param uri
+     */
+    public void setResourceAlias(String alias, String uri)
+    {
+        if (_resourceAliases == null)
+            _resourceAliases= new HashMap<String, String>(5);
+        _resourceAliases.put(alias, uri);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Map<String, String> getResourceAliases()
+    {
+        if (_resourceAliases == null)
+            return null;
+        return _resourceAliases;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void setResourceAliases(Map<String, String> map)
+    {
+        _resourceAliases = map;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getResourceAlias(String path)
+    {
+        if (_resourceAliases == null)
+            return null;
+        String alias = _resourceAliases.get(path);
+        
+        int slash=path.length();
+        while (alias==null)
+        {
+            slash=path.lastIndexOf("/",slash-1);
+            if (slash<0)
+                break;
+            String match=_resourceAliases.get(path.substring(0,slash+1));
+            if (match!=null)
+                alias=match+path.substring(slash+1);            
+        }
+        return alias;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String removeResourceAlias(String alias)
+    {
+        if (_resourceAliases == null)
+            return null;
+        return _resourceAliases.remove(alias);
+    }
+
+    /* ------------------------------------------------------------ */
+    /* (non-Javadoc)
+     * @see org.eclipse.jetty.server.server.handler.ContextHandler#setClassLoader(java.lang.ClassLoader)
+     */
+    @Override
+    public void setClassLoader(ClassLoader classLoader)
+    {
+        super.setClassLoader(classLoader);
+
+//        if ( !(classLoader instanceof WebAppClassLoader) )
+//        {
+//            LOG.info("NOTE: detected a classloader which is not an instance of WebAppClassLoader being set on WebAppContext, some typical class and resource locations may be missing on: " + toString() );
+//        }
+
+        if (classLoader!=null && classLoader instanceof WebAppClassLoader && getDisplayName()!=null)
+            ((WebAppClassLoader)classLoader).setName(getDisplayName());
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public Resource getResource(String uriInContext) throws MalformedURLException
+    {
+        if (uriInContext==null || !uriInContext.startsWith(URIUtil.SLASH))
+            throw new MalformedURLException(uriInContext);
+
+        IOException ioe= null;
+        Resource resource= null;
+        int loop=0;
+        while (uriInContext!=null && loop++<100)
+        {
+            try
+            {
+                resource= super.getResource(uriInContext);
+                if (resource != null && resource.exists())
+                    return resource;
+
+                uriInContext = getResourceAlias(uriInContext);
+            }
+            catch (IOException e)
+            {
+                LOG.ignore(e);
+                if (ioe==null)
+                    ioe= e;
+            }
+        }
+
+        if (ioe != null && ioe instanceof MalformedURLException)
+            throw (MalformedURLException)ioe;
+
+        return resource;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Is the context Automatically configured.
+     *
+     * @return true if configuration discovery.
+     */
+    public boolean isConfigurationDiscovered()
+    {
+        return _configurationDiscovered;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the configuration discovery mode.
+     * If configuration discovery is set to true, then the JSR315
+     * servlet 3.0 discovered configuration features are enabled.
+     * These are:<ul>
+     * <li>Web Fragments</li>
+     * <li>META-INF/resource directories</li>
+     * </ul>
+     * @param discovered true if configuration discovery is enabled for automatic configuration from the context
+     */
+    public void setConfigurationDiscovered(boolean discovered)
+    {
+        _configurationDiscovered = discovered;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Pre configure the web application.
+     * <p>
+     * The method is normally called from {@link #start()}. It performs
+     * the discovery of the configurations to be applied to this context,
+     * specifically:<ul>
+     * <li>Instantiate the {@link Configuration} instances with a call to {@link #loadConfigurations()}.
+     * <li>Setup the default System classes by calling {@link #loadSystemClasses()}
+     * <li>Setup the default Server classes by calling <code>loadServerClasses()</code>
+     * <li>Instantiates a classload (if one is not already set)
+     * <li>Calls the {@link Configuration#preConfigure(WebAppContext)} method of all
+     * Configuration instances.
+     * </ul>
+     * @throws Exception
+     */
+    public void preConfigure() throws Exception
+    {
+        // Setup configurations
+        loadConfigurations();
+
+        // Setup system classes
+        loadSystemClasses();
+
+        // Setup server classes
+        loadServerClasses();
+
+        // Configure classloader
+        _ownClassLoader=false;
+        if (getClassLoader()==null)
+        {
+            WebAppClassLoader classLoader = new WebAppClassLoader(this);
+            setClassLoader(classLoader);
+            _ownClassLoader=true;
+        }
+
+        if (LOG.isDebugEnabled())
+        {
+            ClassLoader loader = getClassLoader();
+            LOG.debug("Thread Context classloader {}",loader);
+            loader=loader.getParent();
+            while(loader!=null)
+            {
+                LOG.debug("Parent class loader: {} ",loader);
+                loader=loader.getParent();
+            }
+        }
+
+        // Prepare for configuration
+        for (int i=0;i<_configurations.length;i++)
+        {
+            LOG.debug("preConfigure {} with {}",this,_configurations[i]);
+            _configurations[i].preConfigure(this);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void configure() throws Exception
+    {
+        // Configure webapp
+        for (int i=0;i<_configurations.length;i++)
+        {
+            LOG.debug("configure {} with {}",this,_configurations[i]);
+            _configurations[i].configure(this);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void postConfigure() throws Exception
+    {
+        // Clean up after configuration
+        for (int i=0;i<_configurations.length;i++)
+        {
+            LOG.debug("postConfigure {} with {}",this,_configurations[i]);
+            _configurations[i].postConfigure(this);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        try
+        {
+            _metadata.setAllowDuplicateFragmentNames(isAllowDuplicateFragmentNames());
+            preConfigure();
+            super.doStart();
+            postConfigure();
+
+            if (isLogUrlOnStart())
+                dumpUrl();
+        }
+        catch (Exception e)
+        {
+            //start up of the webapp context failed, make sure it is not started
+            LOG.warn("Failed startup of context "+this, e);
+            _unavailableException=e;
+            setAvailable(false);
+            if (isThrowUnavailableOnStartupException())
+                throw e;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.thread.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+
+        try
+        {
+            for (int i=_configurations.length;i-->0;)
+                _configurations[i].deconfigure(this);
+
+            if (_metadata != null)
+                _metadata.clear();
+            _metadata=new MetaData();
+
+        }
+        finally
+        {
+            if (_ownClassLoader)
+                setClassLoader(null);
+
+            setAvailable(true);
+            _unavailableException=null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroy()
+    {
+        // Prepare for configuration
+        MultiException mx=new MultiException();
+        if (_configurations!=null)
+        {
+            for (int i=_configurations.length;i-->0;)
+            {
+                try
+                {
+                    _configurations[i].destroy(this);
+                }
+                catch(Exception e)
+                {
+                    mx.add(e);
+                }
+            }
+        }
+        _configurations=null;
+        super.destroy();
+        mx.ifExceptionThrowRuntime();
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * Dumps the current web app name and URL to the log
+     */
+    private void dumpUrl()
+    {
+        Connector[] connectors = getServer().getConnectors();
+        for (int i=0;i<connectors.length;i++)
+        {
+            String connectorName = connectors[i].getName();
+            String displayName = getDisplayName();
+            if (displayName == null)
+                displayName = "WebApp@"+connectors.hashCode();
+
+            LOG.info(displayName + " at http://" + connectorName + getContextPath());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the configurations.
+     */
+    public String[] getConfigurationClasses()
+    {
+        return _configurationClasses;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the configurations.
+     */
+    public Configuration[] getConfigurations()
+    {
+        return _configurations;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The default descriptor is a web.xml format file that is applied to the context before the standard WEB-INF/web.xml
+     * @return Returns the defaultsDescriptor.
+     */
+    public String getDefaultsDescriptor()
+    {
+        return _defaultsDescriptor;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
+     * @return Returns the Override Descriptor.
+     * @deprecated use {@link #getOverrideDescriptors()}
+     */
+    @Deprecated
+    public String getOverrideDescriptor()
+    {
+        if (_overrideDescriptors.size()!=1)
+            return null;
+        return _overrideDescriptors.get(0);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * An override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
+     * @return Returns the Override Descriptor list
+     */
+    public List<String> getOverrideDescriptors()
+    {
+        return Collections.unmodifiableList(_overrideDescriptors);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the permissions.
+     */
+    public PermissionCollection getPermissions()
+    {
+        return _permissions;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see #setServerClasses(String[])
+     * @return Returns the serverClasses.
+     */
+    public String[] getServerClasses()
+    {
+        if (_serverClasses == null)
+            loadServerClasses();
+
+        return _serverClasses.getPatterns();
+    }
+
+    public void addServerClass(String classname)
+    {
+        if (_serverClasses == null)
+            loadServerClasses();
+
+        _serverClasses.addPattern(classname);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see #setSystemClasses(String[])
+     * @return Returns the systemClasses.
+     */
+    public String[] getSystemClasses()
+    {
+        if (_systemClasses == null)
+            loadSystemClasses();
+
+        return _systemClasses.getPatterns();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void addSystemClass(String classname)
+    {
+        if (_systemClasses == null)
+            loadSystemClasses();
+
+        _systemClasses.addPattern(classname);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isServerClass(String name)
+    {
+        if (_serverClasses == null)
+            loadServerClasses();
+
+        return _serverClasses.match(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSystemClass(String name)
+    {
+        if (_systemClasses == null)
+            loadSystemClasses();
+
+        return _systemClasses.match(name);
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void loadSystemClasses()
+    {
+        if (_systemClasses != null)
+            return;
+
+        //look for a Server attribute with the list of System classes
+        //to apply to every web application. If not present, use our defaults.
+        Server server = getServer();
+        if (server != null)
+        {
+            Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
+            if (systemClasses != null && systemClasses instanceof String[])
+                _systemClasses = new ClasspathPattern((String[])systemClasses);
+        }
+
+        if (_systemClasses == null)
+            _systemClasses = new ClasspathPattern(__dftSystemClasses);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void loadServerClasses()
+    {
+        if (_serverClasses != null)
+        {
+            return;
+        }
+
+        // look for a Server attribute with the list of Server classes
+        // to apply to every web application. If not present, use our defaults.
+        Server server = getServer();
+        if (server != null)
+        {
+            Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
+            if (serverClasses != null && serverClasses instanceof String[])
+            {
+                _serverClasses = new ClasspathPattern((String[])serverClasses);
+            }
+        }
+
+        if (_serverClasses == null)
+        {
+            _serverClasses = new ClasspathPattern(__dftServerClasses);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the war as a file or URL string (Resource)
+     */
+    public String getWar()
+    {
+        if (_war==null)
+            _war=getResourceBase();
+        return _war;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Resource getWebInf() throws IOException
+    {
+        if (super.getBaseResource() == null)
+            return null;
+
+        // Iw there a WEB-INF directory?
+        Resource web_inf= super.getBaseResource().addPath("WEB-INF/");
+        if (!web_inf.exists() || !web_inf.isDirectory())
+            return null;
+
+        return web_inf;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the distributable.
+     */
+    public boolean isDistributable()
+    {
+        return _distributable;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the extractWAR.
+     */
+    public boolean isExtractWAR()
+    {
+        return _extractWAR;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the webdir is copied (to allow hot replacement of jars on windows)
+     */
+    public boolean isCopyWebDir()
+    {
+        return _copyDir;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the web-inf lib and classes directories are copied (to allow hot replacement of jars on windows)
+     */
+    public boolean isCopyWebInf()
+    {
+        return _copyWebInf;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if the classloader should delegate first to the parent
+     * classloader (standard java behaviour) or false if the classloader
+     * should first try to load from WEB-INF/lib or WEB-INF/classes (servlet
+     * spec recommendation).
+     */
+    public boolean isParentLoaderPriority()
+    {
+        return _parentLoaderPriority;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public String[] getDefaultConfigurationClasses ()
+    {
+        return __dftConfigurationClasses;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String[] getDefaultServerClasses ()
+    {
+        return __dftServerClasses;
+    }
+
+    /* ------------------------------------------------------------ */
+    public String[] getDefaultSystemClasses ()
+    {
+        return __dftSystemClasses;
+    }
+
+    /* ------------------------------------------------------------ */
+    protected void loadConfigurations()
+    	throws Exception
+    {
+        //if the configuration instances have been set explicitly, use them
+        if (_configurations!=null)
+            return;
+
+        //if the configuration classnames have been set explicitly use them
+        if (!_configurationClassesSet)
+            _configurationClasses=__dftConfigurationClasses;
+
+        _configurations = new Configuration[_configurationClasses.length];
+        for (int i = 0; i < _configurationClasses.length; i++)
+        {
+            _configurations[i]=(Configuration)Loader.loadClass(this.getClass(), _configurationClasses[i]).newInstance();
+        }
+    }
+
+  
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return super.toString()+(_war==null?"":(","+_war));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param configurations The configuration class names.  If setConfigurations is not called
+     * these classes are used to create a configurations array.
+     */
+    public void setConfigurationClasses(String[] configurations)
+    {
+        if (isRunning())
+            throw new IllegalStateException();
+        _configurationClasses = configurations==null?null:(String[])configurations.clone();
+        _configurationClassesSet = true;
+        _configurations=null;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param configurations The configurations to set.
+     */
+    public void setConfigurations(Configuration[] configurations)
+    {
+        if (isRunning())
+            throw new IllegalStateException();
+        _configurations = configurations==null?null:(Configuration[])configurations.clone();
+        _configurationsSet = true;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The default descriptor is a web.xml format file that is applied to the context before the standard WEB-INF/web.xml
+     * @param defaultsDescriptor The defaultsDescriptor to set.
+     */
+    public void setDefaultsDescriptor(String defaultsDescriptor)
+    {
+        _defaultsDescriptor = defaultsDescriptor;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
+     * @param overrideDescriptor The overrideDescritpor to set.
+     * @deprecated use {@link #setOverrideDescriptors(List)}
+     */
+    @Deprecated
+    public void setOverrideDescriptor(String overrideDescriptor)
+    {
+        _overrideDescriptors.clear();
+        _overrideDescriptors.add(overrideDescriptor);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
+     * @param overrideDescriptors The overrideDescriptors (file or URL) to set.
+     */
+    public void setOverrideDescriptors(List<String> overrideDescriptors)
+    {
+        _overrideDescriptors.clear();
+        _overrideDescriptors.addAll(overrideDescriptors);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * The override descriptor is a web.xml format file that is applied to the context after the standard WEB-INF/web.xml
+     * @param overrideDescriptor The overrideDescriptor (file or URL) to add.
+     */
+    public void addOverrideDescriptor(String overrideDescriptor)
+    {
+        _overrideDescriptors.add(overrideDescriptor);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the web.xml descriptor to use. If set to null, WEB-INF/web.xml is used if it exists.
+     */
+    public String getDescriptor()
+    {
+        return _descriptor;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param descriptor the web.xml descriptor to use. If set to null, WEB-INF/web.xml is used if it exists.
+     */
+    public void setDescriptor(String descriptor)
+    {
+        _descriptor=descriptor;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param distributable The distributable to set.
+     */
+    public void setDistributable(boolean distributable)
+    {
+        this._distributable = distributable;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setEventListeners(EventListener[] eventListeners)
+    {
+        if (_sessionHandler!=null)
+            _sessionHandler.clearEventListeners();
+
+        super.setEventListeners(eventListeners);
+
+        for (int i=0; eventListeners!=null && i<eventListeners.length;i ++)
+        {
+            EventListener listener = eventListeners[i];
+
+            if ((listener instanceof HttpSessionActivationListener)
+                            || (listener instanceof HttpSessionAttributeListener)
+                            || (listener instanceof HttpSessionBindingListener)
+                            || (listener instanceof HttpSessionListener))
+            {
+                if (_sessionHandler!=null)
+                    _sessionHandler.addEventListener(listener);
+            }
+
+        }
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param extractWAR True if war files are extracted
+     */
+    public void setExtractWAR(boolean extractWAR)
+    {
+        _extractWAR = extractWAR;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param copy True if the webdir is copied (to allow hot replacement of jars)
+     */
+    public void setCopyWebDir(boolean copy)
+    {
+        _copyDir = copy;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param copyWebInf True if the web-inf lib and classes directories are copied (to allow hot replacement of jars on windows)
+     */
+    public void setCopyWebInf(boolean copyWebInf)
+    {
+        _copyWebInf = copyWebInf;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param java2compliant The java2compliant to set.
+     */
+    public void setParentLoaderPriority(boolean java2compliant)
+    {
+        _parentLoaderPriority = java2compliant;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param permissions The permissions to set.
+     */
+    public void setPermissions(PermissionCollection permissions)
+    {
+        _permissions = permissions;
+    }
+
+    /**
+     * Set the context white list
+     *
+     * In certain circumstances you want may want to deny access of one webapp from another
+     * when you may not fully trust the webapp.  Setting this white list will enable a
+     * check when a servlet called getContext(String), validating that the uriInPath
+     * for the given webapp has been declaratively allows access to the context.
+     * @param contextWhiteList
+     */
+    public void setContextWhiteList(String[] contextWhiteList)
+    {
+        _contextWhiteList = contextWhiteList;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the server classes patterns.
+     * <p>
+     * Server classes/packages are classes used to implement the server and are hidden
+     * from the context.  If the context needs to load these classes, it must have its
+     * own copy of them in WEB-INF/lib or WEB-INF/classes.
+     * A class pattern is a string of one of the forms:<dl>
+     * <dt>org.package.Classname</dt><dd>Match a specific class</dd>
+     * <dt>org.package.</dt><dd>Match a specific package hierarchy</dd>
+     * <dt>-org.package.Classname</dt><dd>Exclude a specific class</dd>
+     * <dt>-org.package.</dt><dd>Exclude a specific package hierarchy</dd>
+     * </dl>
+     * @param serverClasses The serverClasses to set.
+     */
+    public void setServerClasses(String[] serverClasses)
+    {
+        _serverClasses = new ClasspathPattern(serverClasses);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the system classes patterns.
+     * <p>
+     * System classes/packages are classes provided by the JVM and that
+     * cannot be replaced by classes of the same name from WEB-INF,
+     * regardless of the value of {@link #setParentLoaderPriority(boolean)}.
+     * A class pattern is a string of one of the forms:<dl>
+     * <dt>org.package.Classname</dt><dd>Match a specific class</dd>
+     * <dt>org.package.</dt><dd>Match a specific package hierarchy</dd>
+     * <dt>-org.package.Classname</dt><dd>Exclude a specific class</dd>
+     * <dt>-org.package.</dt><dd>Exclude a specific package hierarchy</dd>
+     * </dl>
+     * @param systemClasses The systemClasses to set.
+     */
+    public void setSystemClasses(String[] systemClasses)
+    {
+        _systemClasses = new ClasspathPattern(systemClasses);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Set temporary directory for context.
+     * The javax.servlet.context.tempdir attribute is also set.
+     * @param dir Writable temporary directory.
+     */
+    public void setTempDirectory(File dir)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Started");
+
+        if (dir!=null)
+        {
+            try{dir=new File(dir.getCanonicalPath());}
+            catch (IOException e){LOG.warn(Log.EXCEPTION,e);}
+        }
+
+        if (dir!=null && !dir.exists())
+        {
+            dir.mkdir();
+            dir.deleteOnExit();
+        }
+
+        if (dir!=null && ( !dir.exists() || !dir.isDirectory() || !dir.canWrite()))
+            throw new IllegalArgumentException("Bad temp directory: "+dir);
+
+        try
+        {
+            if (dir!=null)
+                dir=dir.getCanonicalFile();
+        }
+        catch(Exception e)
+        {
+            LOG.warn(e);
+        }
+        _tmpDir=dir;
+        setAttribute(TEMPDIR,_tmpDir);
+    }
+
+    /* ------------------------------------------------------------ */
+    public File getTempDirectory ()
+    {
+        return _tmpDir;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param war The war to set as a file name or URL
+     */
+    public void setWar(String war)
+    {
+        _war = war;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Comma or semicolon separated path of filenames or URLs
+     * pointing to directories or jar files. Directories should end
+     * with '/'.
+     */
+    public String getExtraClasspath()
+    {
+        return _extraClasspath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param extraClasspath Comma or semicolon separated path of filenames or URLs
+     * pointing to directories or jar files. Directories should end
+     * with '/'.
+     */
+    public void setExtraClasspath(String extraClasspath)
+    {
+        _extraClasspath=extraClasspath;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isLogUrlOnStart()
+    {
+        return _logUrlOnStart;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Sets whether or not the web app name and URL is logged on startup
+     *
+     * @param logOnStart whether or not the log message is created
+     */
+    public void setLogUrlOnStart(boolean logOnStart)
+    {
+        this._logUrlOnStart = logOnStart;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void setServer(Server server)
+    {
+        super.setServer(server);
+        //if we haven't been given a set of configuration instances to
+        //use, and we haven't been given a set of configuration classes
+        //to use, use the configuration classes that came from the
+        //Server (if there are any)
+        if (!_configurationsSet && !_configurationClassesSet && server != null)
+        {
+            String[] serverConfigs = (String[])server.getAttribute(SERVER_CONFIG);
+            if (serverConfigs != null)
+                setConfigurationClasses(serverConfigs);
+        }
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isAllowDuplicateFragmentNames()
+    {
+        return _allowDuplicateFragmentNames;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames)
+    {
+        _allowDuplicateFragmentNames = allowDuplicateFragmentNames;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void setThrowUnavailableOnStartupException (boolean throwIfStartupException) {
+        _throwUnavailableOnStartupException = throwIfStartupException;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public boolean isThrowUnavailableOnStartupException () {
+        return _throwUnavailableOnStartupException;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    protected void startContext()
+        throws Exception
+    {
+        configure();
+
+        //resolve the metadata
+        _metadata.resolve(this);
+
+        super.startContext();
+    }
+       
+    /* ------------------------------------------------------------ */    
+    @Override
+    public Set<String> setServletSecurity(Dynamic registration, ServletSecurityElement servletSecurityElement)
+    {
+     
+        Set<String> unchangedURLMappings = new HashSet<String>();
+        //From javadoc for ServletSecurityElement:
+        /*
+        If a URL pattern of this ServletRegistration is an exact target of a security-constraint that 
+        was established via the portable deployment descriptor, then this method does not change the 
+        security-constraint for that pattern, and the pattern will be included in the return value.
+
+        If a URL pattern of this ServletRegistration is an exact target of a security constraint 
+        that was established via the ServletSecurity annotation or a previous call to this method, 
+        then this method replaces the security constraint for that pattern.
+
+        If a URL pattern of this ServletRegistration is neither the exact target of a security constraint 
+        that was established via the ServletSecurity annotation or a previous call to this method, 
+        nor the exact target of a security-constraint in the portable deployment descriptor, then 
+        this method establishes the security constraint for that pattern from the argument ServletSecurityElement. 
+         */
+
+        Collection<String> pathMappings = registration.getMappings();
+        if (pathMappings != null)
+        {
+            Constraint constraint = ConstraintSecurityHandler.createConstraint(registration.getName(), servletSecurityElement);
+
+            for (String pathSpec:pathMappings)
+            {
+                Origin origin = getMetaData().getOrigin("constraint.url."+pathSpec);
+               
+                switch (origin)
+                {
+                    case NotSet:
+                    {
+                        //No mapping for this url already established
+                        List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
+                        for (ConstraintMapping m:mappings)
+                            ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
+                        getMetaData().setOrigin("constraint.url."+pathSpec, Origin.API);
+                        break;
+                    }
+                    case WebXml:
+                    case WebDefaults:
+                    case WebOverride:
+                    case WebFragment:
+                    {
+                        //a mapping for this url was created in a descriptor, which overrides everything
+                        unchangedURLMappings.add(pathSpec);
+                        break;
+                    }
+                    case Annotation:
+                    case API:
+                    {
+                        //mapping established via an annotation or by previous call to this method,
+                        //replace the security constraint for this pattern
+                        List<ConstraintMapping> constraintMappings = ConstraintSecurityHandler.removeConstraintMappingsForPath(pathSpec, ((ConstraintAware)getSecurityHandler()).getConstraintMappings());
+                       
+                        List<ConstraintMapping> freshMappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
+                        constraintMappings.addAll(freshMappings);
+                           
+                        ((ConstraintSecurityHandler)getSecurityHandler()).setConstraintMappings(constraintMappings);
+                        break;
+                    }
+                }
+            }
+        }
+        
+        return unchangedURLMappings;
+    }
+
+
+
+    /* ------------------------------------------------------------ */
+    public class Context extends ServletContextHandler.Context
+    {
+        /* ------------------------------------------------------------ */
+        @Override
+        public URL getResource(String path) throws MalformedURLException
+        {
+            Resource resource=WebAppContext.this.getResource(path);
+            if (resource==null || !resource.exists())
+                return null;
+
+            // Should we go to the original war?
+            if (resource.isDirectory() && resource instanceof ResourceCollection && !WebAppContext.this.isExtractWAR())
+            {
+                Resource[] resources = ((ResourceCollection)resource).getResources();
+                for (int i=resources.length;i-->0;)
+                {
+                    if (resources[i].getName().startsWith("jar:file"))
+                        return resources[i].getURL();
+                }
+            }
+
+            return resource.getURL();
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public ServletContext getContext(String uripath)
+        {
+            ServletContext servletContext = super.getContext(uripath);
+
+            if ( servletContext != null && _contextWhiteList != null )
+            {
+                for ( String context : _contextWhiteList )
+                {
+                    if ( context.equals(uripath) )
+                    {
+                        return servletContext;
+                    }
+                }
+
+                return null;
+            }
+            else
+            {
+                return servletContext;
+            }
+        }
+
+        
+        
+    }
+
+    /* ------------------------------------------------------------ */
+    public MetaData getMetaData()
+    {
+        return _metadata;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/webapp/WebDescriptor.java b/src/java/org/eclipse/jetty/webapp/WebDescriptor.java
new file mode 100644
index 0000000..19dba0a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/WebDescriptor.java
@@ -0,0 +1,276 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.Servlet;
+
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlParser;
+
+
+
+/**
+ * Descriptor
+ *
+ * A web descriptor (web.xml/web-defaults.xml/web-overrides.xml).
+ */
+public class WebDescriptor extends Descriptor
+{
+    private static final Logger LOG = Log.getLogger(WebDescriptor.class);
+ 
+    protected static XmlParser _parserSingleton;
+    protected MetaDataComplete _metaDataComplete;
+    protected int _majorVersion = 3; //default to container version
+    protected int _minorVersion = 0;
+    protected ArrayList<String> _classNames = new ArrayList<String>();
+    protected boolean _distributable;
+
+    protected boolean _isOrdered = false;
+    protected List<String> _ordering = new ArrayList<String>();
+    
+    @Override
+    public void ensureParser()
+    throws ClassNotFoundException
+    {
+        if (_parserSingleton == null)
+        {
+            _parserSingleton = newParser();
+        }
+        _parser = _parserSingleton;
+    }
+
+    
+    public XmlParser newParser()
+    throws ClassNotFoundException
+    {
+        XmlParser xmlParser=new XmlParser();
+        //set up cache of DTDs and schemas locally        
+        URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
+        URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
+        URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
+        URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
+        URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
+        URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
+        URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
+        URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
+        URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
+        URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
+        URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
+        URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
+        URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
+
+        URL jsp20xsd = null;
+        URL jsp21xsd = null;
+
+        try
+        {
+            Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
+            jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
+            jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
+        }
+        catch (Exception e)
+        {
+            LOG.ignore(e);
+        }
+        finally
+        {
+            if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
+            if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
+        }
+        
+        redirect(xmlParser,"web-app_2_2.dtd",dtd22);
+        redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
+        redirect(xmlParser,"web.dtd",dtd23);
+        redirect(xmlParser,"web-app_2_3.dtd",dtd23);
+        redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
+        redirect(xmlParser,"XMLSchema.dtd",schemadtd);
+        redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
+        redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
+        redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
+        redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
+        redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
+        redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
+        redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
+        redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd);
+        redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd);
+        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd);
+        redirect(xmlParser,"xml.xsd",xmlxsd);
+        redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
+        redirect(xmlParser,"datatypes.dtd",datatypesdtd);
+        redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
+        redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
+        redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
+        redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
+        redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
+        return xmlParser;
+    }
+    
+    
+    public WebDescriptor (Resource xml)
+    {
+        super(xml);
+    }
+    
+    public void parse ()
+    throws Exception
+    {
+        super.parse();
+        processVersion();
+        processOrdering();
+    }
+    
+    public MetaDataComplete getMetaDataComplete()
+    {
+        return _metaDataComplete;
+    }
+    
+ 
+    
+    public int getMajorVersion ()
+    {
+        return _majorVersion;
+    }
+    
+    public int getMinorVersion()
+    {
+        return _minorVersion;
+    }
+  
+    
+    public void processVersion ()
+    {
+        String version = _root.getAttribute("version", "DTD");
+        if ("DTD".equals(version))
+        {
+            _majorVersion = 2;
+            _minorVersion = 3;
+            String dtd = _parser.getDTD();
+            if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
+            {
+                _majorVersion = 2;
+                _minorVersion = 2;
+            }
+        }
+        else 
+        {
+           int dot = version.indexOf(".");
+           if (dot > 0)
+           {
+               _majorVersion = Integer.parseInt(version.substring(0,dot));
+               _minorVersion = Integer.parseInt(version.substring(dot+1));
+           }
+        }
+     
+        if (_majorVersion < 2 && _minorVersion < 5)
+            _metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
+        else
+        {
+            String s = (String)_root.getAttribute("metadata-complete");
+            if (s == null)
+                _metaDataComplete = MetaDataComplete.NotSet;
+            else
+                _metaDataComplete = Boolean.valueOf(s).booleanValue()?MetaDataComplete.True:MetaDataComplete.False;
+        }
+            
+        if (LOG.isDebugEnabled())
+            LOG.debug(_xml.toString()+": Calculated metadatacomplete = " + _metaDataComplete + " with version=" + version);     
+    }
+    
+    public void processOrdering ()
+    {
+        //Process the web.xml's optional <absolute-ordering> element              
+        XmlParser.Node ordering = _root.get("absolute-ordering");
+        if (ordering == null)
+           return;
+        
+        _isOrdered = true;
+        //If an absolute-ordering was already set, then ignore it in favor of this new one
+       // _processor.setOrdering(new AbsoluteOrdering());
+   
+        Iterator<Object> iter = ordering.iterator();
+        XmlParser.Node node = null;
+        while (iter.hasNext())
+        {
+            Object o = iter.next();
+            if (!(o instanceof XmlParser.Node)) continue;
+            node = (XmlParser.Node) o;
+
+            if (node.getTag().equalsIgnoreCase("others"))
+                //((AbsoluteOrdering)_processor.getOrdering()).addOthers();
+                _ordering.add("others");
+            else if (node.getTag().equalsIgnoreCase("name"))
+                //((AbsoluteOrdering)_processor.getOrdering()).add(node.toString(false,true));
+                _ordering.add(node.toString(false,true));
+        }
+    }
+  
+    public void addClassName (String className)
+    {
+        if (!_classNames.contains(className))
+            _classNames.add(className);
+    }
+    
+    public ArrayList<String> getClassNames ()
+    {
+        return _classNames;
+    }
+    
+    public void setDistributable (boolean distributable)
+    {
+        _distributable = distributable;
+    }
+    
+    public boolean isDistributable()
+    {
+        return _distributable;
+    }
+    
+    public void setValidating (boolean validating)
+    {
+       _validating = validating;
+    }
+    
+    
+    public boolean isOrdered()
+    {
+        return _isOrdered;
+    }
+    
+    public List<String> getOrdering()
+    {
+        return _ordering;
+    }
+
+  
+}
diff --git a/src/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/src/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
new file mode 100644
index 0000000..0695591
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -0,0 +1,732 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.PatternMatcher;
+import org.eclipse.jetty.util.URIUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.JarResource;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+
+public class WebInfConfiguration extends AbstractConfiguration
+{
+    private static final Logger LOG = Log.getLogger(WebInfConfiguration.class);
+
+    public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured";
+    public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern";
+    public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern";
+    
+    /**
+     * If set, to a list of URLs, these resources are added to the context
+     * resource base as a resource collection. 
+     */
+    public static final String RESOURCE_URLS = "org.eclipse.jetty.resources";
+    
+    protected Resource _preUnpackBaseResource;
+    
+    @Override
+    public void preConfigure(final WebAppContext context) throws Exception
+    {
+        // Look for a work directory
+        File work = findWorkDirectory(context);
+        if (work != null)
+            makeTempDirectory(work, context, false);
+        
+        //Make a temp directory for the webapp if one is not already set
+        resolveTempDirectory(context);
+        
+        //Extract webapp if necessary
+        unpack (context);
+
+        
+        //Apply an initial ordering to the jars which governs which will be scanned for META-INF
+        //info and annotations. The ordering is based on inclusion patterns.       
+        String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN);
+        Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
+        tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
+        Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
+
+        //Apply ordering to container jars - if no pattern is specified, we won't
+        //match any of the container jars
+        PatternMatcher containerJarNameMatcher = new PatternMatcher ()
+        {
+            public void matched(URI uri) throws Exception
+            {
+                context.getMetaData().addContainerJar(Resource.newResource(uri));
+            }      
+        };
+        ClassLoader loader = null;
+        if (context.getClassLoader() != null)
+            loader = context.getClassLoader().getParent();
+
+        while (loader != null && (loader instanceof URLClassLoader))
+        {
+            URL[] urls = ((URLClassLoader)loader).getURLs();
+            if (urls != null)
+            {
+                URI[] containerUris = new URI[urls.length];
+                int i=0;
+                for (URL u : urls)
+                {
+                    try 
+                    {
+                        containerUris[i] = u.toURI();
+                    }
+                    catch (URISyntaxException e)
+                    {
+                        containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
+                    }  
+                    i++;
+                }
+                containerJarNameMatcher.match(containerPattern, containerUris, false);
+            }
+            loader = loader.getParent();
+        }
+        
+        //Apply ordering to WEB-INF/lib jars
+        PatternMatcher webInfJarNameMatcher = new PatternMatcher ()
+        {
+            @Override
+            public void matched(URI uri) throws Exception
+            {
+                context.getMetaData().addWebInfJar(Resource.newResource(uri));
+            }      
+        };
+        List<Resource> jars = findJars(context);
+       
+        //Convert to uris for matching
+        URI[] uris = null;
+        if (jars != null)
+        {
+            uris = new URI[jars.size()];
+            int i=0;
+            for (Resource r: jars)
+            {
+                uris[i++] = r.getURI();
+            }
+        }
+        webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match 
+    }
+    
+
+    @Override
+    public void configure(WebAppContext context) throws Exception
+    {
+        //cannot configure if the context is already started
+        if (context.isStarted())
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("Cannot configure webapp "+context+" after it is started");
+            return;
+        }
+
+        Resource web_inf = context.getWebInf();
+
+        // Add WEB-INF classes and lib classpaths
+        if (web_inf != null && web_inf.isDirectory() && context.getClassLoader() instanceof WebAppClassLoader)
+        {
+            // Look for classes directory
+            Resource classes= web_inf.addPath("classes/");
+            if (classes.exists())
+                ((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
+
+            // Look for jars
+            Resource lib= web_inf.addPath("lib/");
+            if (lib.exists() || lib.isDirectory())
+                ((WebAppClassLoader)context.getClassLoader()).addJars(lib);
+        }
+        
+        // Look for extra resource
+        @SuppressWarnings("unchecked")
+        List<Resource> resources = (List<Resource>)context.getAttribute(RESOURCE_URLS);
+        if (resources!=null)
+        {
+            Resource[] collection=new Resource[resources.size()+1];
+            int i=0;
+            collection[i++]=context.getBaseResource();
+            for (Resource resource : resources)
+                collection[i++]=resource;
+            context.setBaseResource(new ResourceCollection(collection));
+        }
+    }
+
+    @Override
+    public void deconfigure(WebAppContext context) throws Exception
+    {
+        // delete temp directory if we had to create it or if it isn't called work
+        Boolean tmpdirConfigured = (Boolean)context.getAttribute(TEMPDIR_CONFIGURED);
+        
+        if (context.getTempDirectory()!=null && (tmpdirConfigured == null || !tmpdirConfigured.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory()))
+        {
+            IO.delete(context.getTempDirectory());
+            context.setTempDirectory(null);
+            
+            //clear out the context attributes for the tmp dir only if we had to
+            //create the tmp dir
+            context.setAttribute(TEMPDIR_CONFIGURED, null);
+            context.setAttribute(WebAppContext.TEMPDIR, null);
+        }
+
+        
+        //reset the base resource back to what it was before we did any unpacking of resources
+        context.setBaseResource(_preUnpackBaseResource);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext)
+     */
+    @Override
+    public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
+    {
+        File tmpDir=File.createTempFile(WebInfConfiguration.getCanonicalNameForWebAppTmpDir(context),"",template.getTempDirectory().getParentFile());
+        if (tmpDir.exists())
+        {
+            IO.delete(tmpDir);
+        }
+        tmpDir.mkdir();
+        tmpDir.deleteOnExit();
+        context.setTempDirectory(tmpDir);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get a temporary directory in which to unpack the war etc etc.
+     * The algorithm for determining this is to check these alternatives
+     * in the order shown:
+     * 
+     * <p>A. Try to use an explicit directory specifically for this webapp:</p>
+     * <ol>
+     * <li>
+     * Iff an explicit directory is set for this webapp, use it. Do NOT set
+     * delete on exit.
+     * </li>
+     * <li>
+     * Iff javax.servlet.context.tempdir context attribute is set for
+     * this webapp && exists && writeable, then use it. Do NOT set delete on exit.
+     * </li>
+     * </ol>
+     * 
+     * <p>B. Create a directory based on global settings. The new directory 
+     * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost
+     * Work out where to create this directory:
+     * <ol>
+     * <li>
+     * Iff $(jetty.home)/work exists create the directory there. Do NOT
+     * set delete on exit. Do NOT delete contents if dir already exists.
+     * </li>
+     * <li>
+     * Iff WEB-INF/work exists create the directory there. Do NOT set
+     * delete on exit. Do NOT delete contents if dir already exists.
+     * </li>
+     * <li>
+     * Else create dir in $(java.io.tmpdir). Set delete on exit. Delete
+     * contents if dir already exists.
+     * </li>
+     * </ol>
+     */
+    public void resolveTempDirectory (WebAppContext context)
+    {
+        //If a tmp directory is already set, we're done
+        File tmpDir = context.getTempDirectory();
+        if (tmpDir != null && tmpDir.isDirectory() && tmpDir.canWrite())
+        {
+            context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE);
+            return; // Already have a suitable tmp dir configured
+        }
+        
+
+        // No temp directory configured, try to establish one.
+        // First we check the context specific, javax.servlet specified, temp directory attribute
+        File servletTmpDir = asFile(context.getAttribute(WebAppContext.TEMPDIR));
+        if (servletTmpDir != null && servletTmpDir.isDirectory() && servletTmpDir.canWrite())
+        {
+            // Use as tmpDir
+            tmpDir = servletTmpDir;
+            // Ensure Attribute has File object
+            context.setAttribute(WebAppContext.TEMPDIR,tmpDir);
+            // Set as TempDir in context.
+            context.setTempDirectory(tmpDir);
+            return;
+        }
+
+        try
+        {
+            // Put the tmp dir in the work directory if we had one
+            File work =  new File(System.getProperty("jetty.home"),"work");
+            if (work.exists() && work.canWrite() && work.isDirectory())
+            {
+                makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists
+            }
+            else
+            {
+                File baseTemp = asFile(context.getAttribute(WebAppContext.BASETEMPDIR));
+                if (baseTemp != null && baseTemp.isDirectory() && baseTemp.canWrite())
+                {
+                    // Use baseTemp directory (allow the funky Jetty_0_0_0_0.. subdirectory logic to kick in
+                    makeTempDirectory(baseTemp,context,false);
+                }
+                else
+                {
+                    makeTempDirectory(new File(System.getProperty("java.io.tmpdir")),context,true); //make a tmpdir, delete if it already exists
+                }
+            }
+        }
+        catch(Exception e)
+        {
+            tmpDir=null;
+            LOG.ignore(e);
+        }
+
+        //Third ... Something went wrong trying to make the tmp directory, just make
+        //a jvm managed tmp directory
+        if (context.getTempDirectory() == null)
+        {
+            try
+            {
+                // Last resort
+                tmpDir=File.createTempFile("JettyContext","");
+                if (tmpDir.exists())
+                    IO.delete(tmpDir);
+                tmpDir.mkdir();
+                tmpDir.deleteOnExit();
+                context.setTempDirectory(tmpDir);
+            }
+            catch(IOException e)
+            {
+                tmpDir = null;
+                throw new IllegalStateException("Cannot create tmp dir in "+System.getProperty("java.io.tmpdir")+ " for context "+context,e);
+            }
+        }
+    }
+    
+    /**
+     * Given an Object, return File reference for object.
+     * Typically used to convert anonymous Object from getAttribute() calls to a File object.
+     * @param fileattr the file attribute to analyze and return from (supports type File and type String, all others return null)
+     * @return the File object, null if null, or null if not a File or String
+     */
+    private File asFile(Object fileattr)
+    {
+        if (fileattr == null)
+        {
+            return null;
+        }
+        if (fileattr instanceof File)
+        {
+            return (File)fileattr;
+        }
+        if (fileattr instanceof String)
+        {
+            return new File((String)fileattr);
+        }
+        return null;
+    }
+
+
+
+    public void makeTempDirectory (File parent, WebAppContext context, boolean deleteExisting)
+    throws IOException
+    {
+        if (parent != null && parent.exists() && parent.canWrite() && parent.isDirectory())
+        {
+            String temp = getCanonicalNameForWebAppTmpDir(context);                    
+            File tmpDir = new File(parent,temp);
+
+            if (deleteExisting && tmpDir.exists())
+            {
+                if (!IO.delete(tmpDir))
+                {
+                    if(LOG.isDebugEnabled())LOG.debug("Failed to delete temp dir "+tmpDir);
+                }
+            
+                //If we can't delete the existing tmp dir, create a new one
+                if (tmpDir.exists())
+                {
+                    String old=tmpDir.toString();
+                    tmpDir=File.createTempFile(temp+"_","");
+                    if (tmpDir.exists())
+                        IO.delete(tmpDir);
+                    LOG.warn("Can't reuse "+old+", using "+tmpDir);
+                } 
+            }
+            
+            if (!tmpDir.exists())
+                tmpDir.mkdir();
+
+            //If the parent is not a work directory
+            if (!isTempWorkDirectory(tmpDir))
+            {
+                tmpDir.deleteOnExit();
+            }
+
+            if(LOG.isDebugEnabled())
+                LOG.debug("Set temp dir "+tmpDir);
+            context.setTempDirectory(tmpDir);
+        }
+    }
+    
+    
+    public void unpack (WebAppContext context) throws IOException
+    {
+        Resource web_app = context.getBaseResource();
+        _preUnpackBaseResource = context.getBaseResource();
+        
+        if (web_app == null)
+        {
+            String war = context.getWar();
+            if (war!=null && war.length()>0)
+                web_app = context.newResource(war);
+            else
+                web_app=context.getBaseResource();
+
+            // Accept aliases for WAR files
+            if (web_app.getAlias() != null)
+            {
+                LOG.debug(web_app + " anti-aliased to " + web_app.getAlias());
+                web_app = context.newResource(web_app.getAlias());
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()+" file="+(web_app.getFile()));
+            // Is the WAR usable directly?
+            if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:"))
+            {
+                // No - then lets see if it can be turned into a jar URL.
+                Resource jarWebApp = JarResource.newJarResource(web_app);
+                if (jarWebApp.exists() && jarWebApp.isDirectory())
+                    web_app= jarWebApp;
+            }
+
+            // If we should extract or the URL is still not usable
+            if (web_app.exists()  && (
+                    (context.isCopyWebDir() && web_app.getFile() != null && web_app.getFile().isDirectory()) ||
+                    (context.isExtractWAR() && web_app.getFile() != null && !web_app.getFile().isDirectory()) ||
+                    (context.isExtractWAR() && web_app.getFile() == null) || 
+                    !web_app.isDirectory())
+                            )
+            {
+                // Look for sibling directory.
+                File extractedWebAppDir = null;
+
+                if (war!=null)
+                {
+                    // look for a sibling like "foo/" to a "foo.war"
+                    File warfile=Resource.newResource(war).getFile();
+                    if (warfile!=null && warfile.getName().toLowerCase(Locale.ENGLISH).endsWith(".war"))
+                    {
+                        File sibling = new File(warfile.getParent(),warfile.getName().substring(0,warfile.getName().length()-4));
+                        if (sibling.exists() && sibling.isDirectory() && sibling.canWrite())
+                            extractedWebAppDir=sibling;
+                    }
+                }
+                
+                if (extractedWebAppDir==null)
+                    // Then extract it if necessary to the temporary location
+                    extractedWebAppDir= new File(context.getTempDirectory(), "webapp");
+
+                if (web_app.getFile()!=null && web_app.getFile().isDirectory())
+                {
+                    // Copy directory
+                    LOG.info("Copy " + web_app + " to " + extractedWebAppDir);
+                    web_app.copyTo(extractedWebAppDir);
+                }
+                else
+                {
+                    //Use a sentinel file that will exist only whilst the extraction is taking place.
+                    //This will help us detect interrupted extractions.
+                    File extractionLock = new File (context.getTempDirectory(), ".extract_lock");
+                   
+                    if (!extractedWebAppDir.exists())
+                    {
+                        //it hasn't been extracted before so extract it
+                        extractionLock.createNewFile();  
+                        extractedWebAppDir.mkdir();
+                        LOG.info("Extract " + web_app + " to " + extractedWebAppDir);                                     
+                        Resource jar_web_app = JarResource.newJarResource(web_app);
+                        jar_web_app.copyTo(extractedWebAppDir);
+                        extractionLock.delete();
+                    }
+                    else
+                    {
+                        //only extract if the war file is newer, or a .extract_lock file is left behind meaning a possible partial extraction
+                        if (web_app.lastModified() > extractedWebAppDir.lastModified() || extractionLock.exists())
+                        {
+                            extractionLock.createNewFile();
+                            IO.delete(extractedWebAppDir);
+                            extractedWebAppDir.mkdir();
+                            LOG.info("Extract " + web_app + " to " + extractedWebAppDir);
+                            Resource jar_web_app = JarResource.newJarResource(web_app);
+                            jar_web_app.copyTo(extractedWebAppDir);
+                            extractionLock.delete();
+                        }
+                    }
+                } 
+                web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath());
+            }
+
+            // Now do we have something usable?
+            if (!web_app.exists() || !web_app.isDirectory())
+            {
+                LOG.warn("Web application not found " + war);
+                throw new java.io.FileNotFoundException(war);
+            }
+        
+            context.setBaseResource(web_app);
+            
+            if (LOG.isDebugEnabled())
+                LOG.debug("webapp=" + web_app);
+        }
+        
+
+        // Do we need to extract WEB-INF/lib?
+        if (context.isCopyWebInf() && !context.isCopyWebDir())
+        {
+            Resource web_inf= web_app.addPath("WEB-INF/");
+
+            File extractedWebInfDir= new File(context.getTempDirectory(), "webinf");
+            if (extractedWebInfDir.exists())
+                IO.delete(extractedWebInfDir);
+            extractedWebInfDir.mkdir();
+            Resource web_inf_lib = web_inf.addPath("lib/");
+            File webInfDir=new File(extractedWebInfDir,"WEB-INF");
+            webInfDir.mkdir();
+
+            if (web_inf_lib.exists())
+            {
+                File webInfLibDir = new File(webInfDir, "lib");
+                if (webInfLibDir.exists())
+                    IO.delete(webInfLibDir);
+                webInfLibDir.mkdir();
+
+                LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir);
+                web_inf_lib.copyTo(webInfLibDir);
+            }
+
+            Resource web_inf_classes = web_inf.addPath("classes/");
+            if (web_inf_classes.exists())
+            {
+                File webInfClassesDir = new File(webInfDir, "classes");
+                if (webInfClassesDir.exists())
+                    IO.delete(webInfClassesDir);
+                webInfClassesDir.mkdir();
+                LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath());
+                web_inf_classes.copyTo(webInfClassesDir);
+            }
+
+            web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath());
+
+            ResourceCollection rc = new ResourceCollection(web_inf,web_app);
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("context.resourcebase = "+rc);
+
+            context.setBaseResource(rc);   
+        }
+    }
+    
+    
+    public File findWorkDirectory (WebAppContext context) throws IOException
+    {
+        if (context.getBaseResource() != null)
+        {
+            Resource web_inf = context.getWebInf();
+            if (web_inf !=null && web_inf.exists())
+            {
+               return new File(web_inf.getFile(),"work");
+            }
+        }
+        return null;
+    }
+    
+    
+    /**
+     * Check if the tmpDir itself is called "work", or if the tmpDir
+     * is in a directory called "work".
+     * @return true if File is a temporary or work directory
+     */
+    public boolean isTempWorkDirectory (File tmpDir)
+    {
+        if (tmpDir == null)
+            return false;
+        if (tmpDir.getName().equalsIgnoreCase("work"))
+            return true;
+        File t = tmpDir.getParentFile();
+        if (t == null)
+            return false;
+        return (t.getName().equalsIgnoreCase("work"));
+    }
+    
+    
+    /**
+     * Create a canonical name for a webapp temp directory.
+     * The form of the name is:
+     *  <code>"Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string</code>
+     *  
+     *  host and port uniquely identify the server
+     *  context and virtual host uniquely identify the webapp
+     * @return the canonical name for the webapp temp directory
+     */
+    public static String getCanonicalNameForWebAppTmpDir (WebAppContext context)
+    {
+        StringBuffer canonicalName = new StringBuffer();
+        canonicalName.append("jetty-");
+       
+        //get the host and the port from the first connector 
+        Server server=context.getServer();
+        if (server!=null)
+        {
+            Connector[] connectors = context.getServer().getConnectors();
+
+            if (connectors.length>0)
+            {
+                //Get the host
+                String host = (connectors==null||connectors[0]==null?"":connectors[0].getHost());
+                if (host == null)
+                    host = "0.0.0.0";
+                canonicalName.append(host);
+                
+                //Get the port
+                canonicalName.append("-");
+                //try getting the real port being listened on
+                int port = (connectors==null||connectors[0]==null?0:connectors[0].getLocalPort());
+                //if not available (eg no connectors or connector not started), 
+                //try getting one that was configured.
+                if (port < 0)
+                    port = connectors[0].getPort();
+                canonicalName.append(port);
+                canonicalName.append("-");
+            }
+        }
+
+       
+        //Resource  base
+        try
+        {
+            Resource resource = context.getBaseResource();
+            if (resource == null)
+            {
+                if (context.getWar()==null || context.getWar().length()==0)
+                    resource=context.newResource(context.getResourceBase());
+                
+                // Set dir or WAR
+                resource = context.newResource(context.getWar());
+            }
+                
+            String tmp = URIUtil.decodePath(resource.getURL().getPath());
+            if (tmp.endsWith("/"))
+                tmp = tmp.substring(0, tmp.length()-1);
+            if (tmp.endsWith("!"))
+                tmp = tmp.substring(0, tmp.length() -1);
+            //get just the last part which is the filename
+            int i = tmp.lastIndexOf("/");
+            canonicalName.append(tmp.substring(i+1, tmp.length()));
+            canonicalName.append("-");
+        }
+        catch (Exception e)
+        {
+            LOG.warn("Can't generate resourceBase as part of webapp tmp dir name", e);
+        }
+            
+        //Context name
+        String contextPath = context.getContextPath();
+        contextPath=contextPath.replace('/','_');
+        contextPath=contextPath.replace('\\','_');
+        canonicalName.append(contextPath);
+        
+        //Virtual host (if there is one)
+        canonicalName.append("-");
+        String[] vhosts = context.getVirtualHosts();
+        if (vhosts == null || vhosts.length <= 0)
+            canonicalName.append("any");
+        else
+            canonicalName.append(vhosts[0]);
+        
+        // sanitize
+        for (int i=0;i<canonicalName.length();i++)
+        {
+            char c=canonicalName.charAt(i);
+            if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c)<0)
+                canonicalName.setCharAt(i,'.');
+        }        
+
+        canonicalName.append("-");
+        return canonicalName.toString();
+    }
+    
+    /**
+     * Look for jars in WEB-INF/lib
+     * @param context
+     * @return the list of jar resources found within context 
+     * @throws Exception
+     */
+    protected List<Resource> findJars (WebAppContext context) 
+    throws Exception
+    {
+        List<Resource> jarResources = new ArrayList<Resource>();
+        
+        Resource web_inf = context.getWebInf();
+        if (web_inf==null || !web_inf.exists())
+            return null;
+        
+        Resource web_inf_lib = web_inf.addPath("/lib");
+       
+        
+        if (web_inf_lib.exists() && web_inf_lib.isDirectory())
+        {
+            String[] files=web_inf_lib.list();
+            for (int f=0;files!=null && f<files.length;f++)
+            {
+                try 
+                {
+                    Resource file = web_inf_lib.addPath(files[f]);
+                    String fnlc = file.getName().toLowerCase(Locale.ENGLISH);
+                    int dot = fnlc.lastIndexOf('.');
+                    String extension = (dot < 0 ? null : fnlc.substring(dot));
+                    if (extension != null && (extension.equals(".jar") || extension.equals(".zip")))
+                    {
+                        jarResources.add(file);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LOG.warn(Log.EXCEPTION,ex);
+                }
+            }
+        }
+        return jarResources;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java b/src/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java
new file mode 100644
index 0000000..0211cea
--- /dev/null
+++ b/src/java/org/eclipse/jetty/webapp/WebXmlConfiguration.java
@@ -0,0 +1,136 @@
+//
+//  ========================================================================
+//  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.webapp;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+
+/* ------------------------------------------------------------------------------- */
+/**
+ * Configure by parsing default web.xml and web.xml
+ * 
+ */
+public class WebXmlConfiguration extends AbstractConfiguration
+{
+    private static final Logger LOG = Log.getLogger(WebXmlConfiguration.class);
+
+    
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * 
+     */
+    @Override
+    public void preConfigure (WebAppContext context) throws Exception
+    {
+        //parse webdefault.xml
+        String defaultsDescriptor = context.getDefaultsDescriptor();
+        if (defaultsDescriptor != null && defaultsDescriptor.length() > 0)
+        {
+            Resource dftResource = Resource.newSystemResource(defaultsDescriptor);
+            if (dftResource == null) 
+                dftResource = context.newResource(defaultsDescriptor);
+            context.getMetaData().setDefaults (dftResource);
+        }
+        
+        //parse, but don't process web.xml
+        Resource webxml = findWebXml(context);
+        if (webxml != null) 
+        {      
+            context.getMetaData().setWebXml(webxml);
+            context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebXml().getMajorVersion());
+            context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebXml().getMinorVersion());
+        }
+        
+        //parse but don't process override-web.xml
+        for (String overrideDescriptor : context.getOverrideDescriptors())
+        {
+            if (overrideDescriptor != null && overrideDescriptor.length() > 0)
+            {
+                Resource orideResource = Resource.newSystemResource(overrideDescriptor);
+                if (orideResource == null) 
+                    orideResource = context.newResource(overrideDescriptor);
+                context.getMetaData().addOverride(orideResource);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    /**
+     * Process web-default.xml, web.xml, override-web.xml
+     * 
+     */
+    @Override
+    public void configure (WebAppContext context) throws Exception
+    {
+        // cannot configure if the context is already started
+        if (context.isStarted())
+        {
+            LOG.debug("Cannot configure webapp after it is started");
+            return;
+        }
+
+        context.getMetaData().addDescriptorProcessor(new StandardDescriptorProcessor());
+    }
+    
+    /* ------------------------------------------------------------------------------- */
+    protected Resource findWebXml(WebAppContext context) throws IOException, MalformedURLException
+    {
+        String descriptor = context.getDescriptor();
+        if (descriptor != null)
+        {
+            Resource web = context.newResource(descriptor);
+            if (web.exists() && !web.isDirectory()) return web;
+        }
+
+        Resource web_inf = context.getWebInf();
+        if (web_inf != null && web_inf.isDirectory())
+        {
+            // do web.xml file
+            Resource web = web_inf.addPath("web.xml");
+            if (web.exists()) return web;
+            if (LOG.isDebugEnabled())
+                LOG.debug("No WEB-INF/web.xml in " + context.getWar() + ". Serving files and default/dynamic servlets only");
+        }
+        return null;
+    }
+
+
+    /* ------------------------------------------------------------------------------- */
+    @Override
+    public void deconfigure (WebAppContext context) throws Exception
+    {
+        ServletHandler _servletHandler = context.getServletHandler();
+       
+        context.setWelcomeFiles(null);
+
+        if (context.getErrorHandler() instanceof ErrorPageErrorHandler)
+            ((ErrorPageErrorHandler) 
+                    context.getErrorHandler()).setErrorPages(null);
+
+
+        // TODO remove classpaths from classloader
+
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/AbstractExtension.java b/src/java/org/eclipse/jetty/websocket/AbstractExtension.java
new file mode 100644
index 0000000..382ea6d
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/AbstractExtension.java
@@ -0,0 +1,149 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.websocket.WebSocketParser.FrameHandler;
+
+public class AbstractExtension implements Extension
+{
+    private static final int[] __mask = { -1, 0x04, 0x02, 0x01};
+    private final String _name;
+    private final Map<String,String> _parameters=new HashMap<String, String>();
+    private FrameHandler _inbound;
+    private WebSocketGenerator _outbound;
+    private WebSocket.FrameConnection _connection;
+    
+    public AbstractExtension(String name)
+    {
+        _name = name;
+    }
+    
+    public WebSocket.FrameConnection getConnection()
+    {
+        return _connection;
+    }
+
+    public boolean init(Map<String, String> parameters)
+    {
+        _parameters.putAll(parameters);
+        return true;
+    }
+    
+    public String getInitParameter(String name)
+    {
+        return _parameters.get(name);
+    }
+
+    public String getInitParameter(String name,String dft)
+    {
+        if (!_parameters.containsKey(name))
+            return dft;
+        return _parameters.get(name);
+    }
+
+    public int getInitParameter(String name, int dft)
+    {
+        String v=_parameters.get(name);
+        if (v==null)
+            return dft;
+        return Integer.valueOf(v);
+    }
+    
+    
+    public void bind(WebSocket.FrameConnection connection, FrameHandler incoming, WebSocketGenerator outgoing)
+    {
+        _connection=connection;
+        _inbound=incoming;
+        _outbound=outgoing;
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public String getParameterizedName()
+    {
+        StringBuilder name = new StringBuilder();
+        name.append(_name);
+        for (String param : _parameters.keySet())
+            name.append(';').append(param).append('=').append(QuotedStringTokenizer.quoteIfNeeded(_parameters.get(param),";="));
+        return name.toString();
+    }
+
+    public void onFrame(byte flags, byte opcode, Buffer buffer)
+    {
+        // System.err.printf("onFrame %s %x %x %d\n",getExtensionName(),flags,opcode,buffer.length());
+        _inbound.onFrame(flags,opcode,buffer);
+    }
+
+    public void close(int code, String message)
+    {
+        _inbound.close(code,message);
+    }
+
+    public int flush() throws IOException
+    {
+        return _outbound.flush();
+    }
+
+    public boolean isBufferEmpty()
+    {
+        return _outbound.isBufferEmpty();
+    }
+
+    public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        // System.err.printf("addFrame %s %x %x %d\n",getExtensionName(),flags,opcode,length);
+        _outbound.addFrame(flags,opcode,content,offset,length);
+    }
+    
+    public byte setFlag(byte flags,int rsv)
+    {
+        if (rsv<1||rsv>3)
+            throw new IllegalArgumentException("rsv"+rsv);
+        byte b=(byte)(flags | __mask[rsv]);
+        return b;
+    }
+    
+    public byte clearFlag(byte flags,int rsv)
+    {
+        if (rsv<1||rsv>3)
+            throw new IllegalArgumentException("rsv"+rsv);
+        return (byte)(flags & ~__mask[rsv]);
+    }
+
+    public boolean isFlag(byte flags,int rsv)
+    {
+        if (rsv<1||rsv>3)
+            throw new IllegalArgumentException("rsv"+rsv);
+        return (flags & __mask[rsv])!=0;
+    }
+    
+    public String toString()
+    {
+        return getParameterizedName();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java b/src/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java
new file mode 100644
index 0000000..6647622
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/DeflateFrameExtension.java
@@ -0,0 +1,164 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * TODO Implement proposed deflate frame draft
+ */
+public class DeflateFrameExtension extends AbstractExtension
+{
+    private static final Logger LOG = Log.getLogger(DeflateFrameExtension.class);
+
+    private int _minLength=8;
+    private Deflater _deflater;
+    private Inflater _inflater;
+
+    public DeflateFrameExtension()
+    {
+        super("x-deflate-frame");
+    }
+
+    @Override
+    public boolean init(Map<String, String> parameters)
+    {
+        if (!parameters.containsKey("minLength"))
+            parameters.put("minLength",Integer.toString(_minLength));
+        if(super.init(parameters))
+        {
+            _minLength=getInitParameter("minLength",_minLength);
+
+            _deflater=new Deflater();
+            _inflater=new Inflater();
+
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jetty.websocket.AbstractExtension#onFrame(byte, byte, org.eclipse.jetty.io.Buffer)
+     */
+    @Override
+    public void onFrame(byte flags, byte opcode, Buffer buffer)
+    {
+        if (getConnection().isControl(opcode) || !isFlag(flags,1))
+        {
+            super.onFrame(flags,opcode,buffer);
+            return;
+        }
+
+        if (buffer.array()==null)
+            buffer=buffer.asMutableBuffer();
+
+        int length=0xff&buffer.get();
+        if (length>=0x7e)
+        {
+            int b=(length==0x7f)?8:2;
+            length=0;
+            while(b-->0)
+                length=0x100*length+(0xff&buffer.get());
+        }
+
+        // TODO check a max framesize
+
+        _inflater.setInput(buffer.array(),buffer.getIndex(),buffer.length());
+        ByteArrayBuffer buf = new ByteArrayBuffer(length);
+        try
+        {
+            while(_inflater.getRemaining()>0)
+            {
+                int inflated=_inflater.inflate(buf.array(),buf.putIndex(),buf.space());
+                if (inflated==0)
+                    throw new DataFormatException("insufficient data");
+                buf.setPutIndex(buf.putIndex()+inflated);
+            }
+
+            super.onFrame(clearFlag(flags,1),opcode,buf);
+        }
+        catch(DataFormatException e)
+        {
+            LOG.warn(e);
+            getConnection().close(WebSocketConnectionRFC6455.CLOSE_BAD_PAYLOAD,e.toString());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jetty.websocket.AbstractExtension#addFrame(byte, byte, byte[], int, int)
+     */
+    @Override
+    public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        if (getConnection().isControl(opcode) || length<_minLength)
+        {
+            super.addFrame(clearFlag(flags,1),opcode,content,offset,length);
+            return;
+        }
+
+        // prepare the uncompressed input
+        _deflater.reset();
+        _deflater.setInput(content,offset,length);
+        _deflater.finish();
+
+        // prepare the output buffer
+        byte[] out= new byte[length];
+        int out_offset=0;
+
+        // write the uncompressed length
+        if (length>0xffff)
+        {
+            out[out_offset++]=0x7f;
+            out[out_offset++]=(byte)0;
+            out[out_offset++]=(byte)0;
+            out[out_offset++]=(byte)0;
+            out[out_offset++]=(byte)0;
+            out[out_offset++]=(byte)((length>>24)&0xff);
+            out[out_offset++]=(byte)((length>>16)&0xff);
+            out[out_offset++]=(byte)((length>>8)&0xff);
+            out[out_offset++]=(byte)(length&0xff);
+        }
+        else if (length >=0x7e)
+        {
+            out[out_offset++]=0x7e;
+            out[out_offset++]=(byte)(length>>8);
+            out[out_offset++]=(byte)(length&0xff);
+        }
+        else
+        {
+            out[out_offset++]=(byte)(length&0x7f);
+        }
+
+        int l = _deflater.deflate(out,out_offset,length-out_offset);
+
+        if (_deflater.finished())
+            super.addFrame(setFlag(flags,1),opcode,out,0,l+out_offset);
+        else
+            super.addFrame(clearFlag(flags,1),opcode,content,offset,length);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/Extension.java b/src/java/org/eclipse/jetty/websocket/Extension.java
new file mode 100644
index 0000000..1d2bb7a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/Extension.java
@@ -0,0 +1,31 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.util.Map;
+
+public interface Extension extends WebSocketParser.FrameHandler, WebSocketGenerator
+{
+    public String getName();
+    public String getParameterizedName();
+    
+    public boolean init(Map<String,String> parameters);
+    public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound);
+    
+}
diff --git a/src/java/org/eclipse/jetty/websocket/FixedMaskGen.java b/src/java/org/eclipse/jetty/websocket/FixedMaskGen.java
new file mode 100644
index 0000000..169d383
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/FixedMaskGen.java
@@ -0,0 +1,44 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+
+public class FixedMaskGen implements MaskGen
+{
+    private final byte[] _mask;
+
+    public FixedMaskGen()
+    {
+        this(new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff});
+    }
+
+    public FixedMaskGen(byte[] mask)
+    {
+        _mask=new byte[4];
+        // Copy to avoid that external code keeps a reference
+        // to the array parameter to modify masking on-the-fly
+        System.arraycopy(mask, 0, _mask, 0, 4);
+    }
+
+    public void genMask(byte[] mask)
+    {
+        System.arraycopy(_mask, 0, mask, 0, 4);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/FragmentExtension.java b/src/java/org/eclipse/jetty/websocket/FragmentExtension.java
new file mode 100644
index 0000000..177e4c0
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/FragmentExtension.java
@@ -0,0 +1,80 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class FragmentExtension extends AbstractExtension
+{
+    private int _maxLength=-1;
+    private int _minFragments=1;
+    
+    public FragmentExtension()
+    {
+        super("fragment");
+    }
+
+    @Override
+    public boolean init(Map<String, String> parameters)
+    {
+        if(super.init(parameters))
+        {
+            _maxLength=getInitParameter("maxLength",_maxLength);
+            _minFragments=getInitParameter("minFragments",_minFragments);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        if (getConnection().isControl(opcode))
+        {
+            super.addFrame(flags,opcode,content,offset,length);
+            return;
+        }
+        
+        int fragments=1;
+        
+        while (_maxLength>0 && length>_maxLength)
+        {
+            fragments++;
+            super.addFrame((byte)(flags&~getConnection().finMask()),opcode,content,offset,_maxLength);
+            length-=_maxLength;
+            offset+=_maxLength;
+            opcode=getConnection().continuationOpcode();
+        }
+        
+        while (fragments<_minFragments)
+        {
+            int frag=length/2;
+            fragments++;
+            super.addFrame((byte)(flags&0x7),opcode,content,offset,frag);
+            length-=frag;
+            offset+=frag;
+            opcode=getConnection().continuationOpcode();
+        }
+
+        super.addFrame((byte)(flags|getConnection().finMask()),opcode,content,offset,length);
+    }
+    
+    
+}
diff --git a/src/java/org/eclipse/jetty/websocket/IdentityExtension.java b/src/java/org/eclipse/jetty/websocket/IdentityExtension.java
new file mode 100644
index 0000000..59ba279
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/IdentityExtension.java
@@ -0,0 +1,27 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+public class IdentityExtension extends AbstractExtension
+{
+    public IdentityExtension()
+    {
+        super("identity");
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/MaskGen.java b/src/java/org/eclipse/jetty/websocket/MaskGen.java
new file mode 100644
index 0000000..a9adf64
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/MaskGen.java
@@ -0,0 +1,24 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+public interface MaskGen
+{
+    void genMask(byte[] mask);
+}
diff --git a/src/java/org/eclipse/jetty/websocket/RandomMaskGen.java b/src/java/org/eclipse/jetty/websocket/RandomMaskGen.java
new file mode 100644
index 0000000..771bc31
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/RandomMaskGen.java
@@ -0,0 +1,45 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.util.Random;
+
+
+public class RandomMaskGen implements MaskGen
+{
+    private final Random _random;
+
+    public RandomMaskGen()
+    {
+        this(new Random());
+    }
+
+    public RandomMaskGen(Random random)
+    {
+        _random=random;
+    }
+
+    public void genMask(byte[] mask)
+    {
+        // The assumption is that this code is always called
+        // with an external lock held to prevent concurrent access
+        // Otherwise we need to synchronize on the _random.
+        _random.nextBytes(mask);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocket.java b/src/java/org/eclipse/jetty/websocket/WebSocket.java
new file mode 100644
index 0000000..29dbc04
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocket.java
@@ -0,0 +1,275 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+/**
+ * WebSocket Interface.
+ * <p>
+ * This interface provides the signature for a server-side end point of a websocket connection.
+ * The Interface has several nested interfaces, for each type of message that may be received.
+ */
+public interface WebSocket
+{   
+    /**
+     * Called when a new websocket connection is accepted.
+     * @param connection The Connection object to use to send messages.
+     */
+    void onOpen(Connection connection);
+
+    /**
+     * Called when an established websocket connection closes
+     * @param closeCode
+     * @param message
+     */
+    void onClose(int closeCode, String message);
+
+    /**
+     * A nested WebSocket interface for receiving text messages
+     */
+    interface OnTextMessage extends WebSocket
+    {
+        /**
+         * Called with a complete text message when all fragments have been received.
+         * The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
+         * @param data The message
+         */
+        void onMessage(String data);
+    }
+
+    /**
+     * A nested WebSocket interface for receiving binary messages
+     */
+    interface OnBinaryMessage extends WebSocket
+    {
+        /**
+         * Called with a complete binary message when all fragments have been received.
+         * The maximum size of binary message that may be aggregated from multiple frames is set with {@link Connection#setMaxBinaryMessageSize(int)}.
+         * @param data
+         * @param offset
+         * @param length
+         */
+        void onMessage(byte[] data, int offset, int length);
+    }
+    
+    /**
+     * A nested WebSocket interface for receiving control messages
+     */
+    interface OnControl extends WebSocket
+    {
+        /** 
+         * Called when a control message has been received.
+         * @param controlCode
+         * @param data
+         * @param offset
+         * @param length
+         * @return true if this call has completely handled the control message and no further processing is needed.
+         */
+        boolean onControl(byte controlCode,byte[] data, int offset, int length);
+    }
+    
+    /**
+     * A nested WebSocket interface for receiving any websocket frame
+     */
+    interface OnFrame extends WebSocket
+    {
+        /**
+         * Called when any websocket frame is received.
+         * @param flags
+         * @param opcode
+         * @param data
+         * @param offset
+         * @param length
+         * @return true if this call has completely handled the frame and no further processing is needed (including aggregation and/or message delivery)
+         */
+        boolean onFrame(byte flags,byte opcode,byte[] data, int offset, int length);
+        
+        void onHandshake(FrameConnection connection);
+    }
+    
+    /**
+     * A  Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to 
+     * give the application access to the specifics of the current connection.   This includes methods 
+     * for sending frames and messages as well as methods for interpreting the flags and opcodes of the connection.
+     */
+    public interface Connection
+    {
+        String getProtocol();
+        void sendMessage(String data) throws IOException;
+        void sendMessage(byte[] data, int offset, int length) throws IOException;
+        
+        /**
+         * @deprecated Use {@link #close()}
+         */
+        void disconnect();
+
+        /** 
+         * Close the connection with normal close code.
+         */
+        void close();
+        
+        /** Close the connection with specific closeCode and message.
+         * @param closeCode The close code to send, or -1 for no close code
+         * @param message The message to send or null for no message
+         */
+        void close(int closeCode,String message);
+        
+        boolean isOpen();
+
+        /**
+         * @param ms The time in ms that the connection can be idle before closing
+         */
+        void setMaxIdleTime(int ms);
+        
+        /**
+         * @param size size<0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
+         */
+        void setMaxTextMessageSize(int size);
+        
+        /**
+         * @param size size<0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
+         */
+        void setMaxBinaryMessageSize(int size);
+        
+        /**
+         * @return The time in ms that the connection can be idle before closing
+         */
+        int getMaxIdleTime();
+        
+        /**
+         * Size in characters of the maximum text message to be received
+         * @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters
+         */
+        int getMaxTextMessageSize();
+        
+        /**
+         * Size in bytes of the maximum binary message to be received
+         * @return size <0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer
+         */
+        int getMaxBinaryMessageSize();
+    }
+
+    /**
+     * Frame Level Connection
+     * <p>The Connection interface at the level of sending/receiving frames rather than messages.
+     * Also contains methods to decode/generate flags and opcodes without using constants, so that 
+     * code can be written to work with multiple drafts of the protocol.
+     *
+     */
+    public interface FrameConnection extends Connection
+    {
+        /**
+         * @return The opcode of a binary message
+         */
+        byte binaryOpcode();
+        
+        /**
+         * @return The opcode of a text message
+         */
+        byte textOpcode();
+        
+        /**
+         * @return The opcode of a continuation frame
+         */
+        byte continuationOpcode();
+        
+        /**
+         * @return Mask for the FIN bit.
+         */
+        byte finMask();
+        
+        /** Set if frames larger than the frame buffer are handled with local fragmentations
+         * @param allowFragmentation
+         */
+        void setAllowFrameFragmentation(boolean allowFragmentation);
+
+        /**
+         * @param flags The flags bytes of a frame
+         * @return True of the flags indicate a final frame.
+         */
+        boolean isMessageComplete(byte flags);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is for a control frame
+         */
+        boolean isControl(byte opcode);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is for a text frame
+         */
+        boolean isText(byte opcode);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is for a binary frame
+         */
+        boolean isBinary(byte opcode);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is for a continuation frame
+         */
+        boolean isContinuation(byte opcode);
+
+        /**
+         * @param opcode 
+         * @return True if the opcode is a close control
+         */
+        boolean isClose(byte opcode);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is a ping control
+         */
+        boolean isPing(byte opcode);
+
+        /**
+         * @param opcode
+         * @return True if the opcode is a pong control
+         */
+        boolean isPong(byte opcode);
+        
+        /**
+         * @return True if frames larger than the frame buffer are fragmented.
+         */
+        boolean isAllowFrameFragmentation();
+        
+        /** Send a control frame
+         * @param control
+         * @param data
+         * @param offset
+         * @param length
+         * @throws IOException
+         */
+        void sendControl(byte control,byte[] data, int offset, int length) throws IOException;
+
+        /** Send an arbitrary frame
+         * @param flags
+         * @param opcode
+         * @param data
+         * @param offset
+         * @param length
+         * @throws IOException
+         */
+        void sendFrame(byte flags,byte opcode,byte[] data, int offset, int length) throws IOException;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketBuffers.java b/src/java/org/eclipse/jetty/websocket/WebSocketBuffers.java
new file mode 100644
index 0000000..4ee126a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketBuffers.java
@@ -0,0 +1,65 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Buffers.Type;
+import org.eclipse.jetty.io.BuffersFactory;
+
+
+/* ------------------------------------------------------------ */
+/** The WebSocket Buffer Pool.
+ *
+ * The normal buffers are byte array buffers so that user processes
+ * can access directly.   However the generator uses direct buffers
+ * for the final output stage as they are filled in bulk and are more
+ * efficient to flush.
+ */
+public class WebSocketBuffers
+{
+    final private int _bufferSize;
+    final private Buffers _buffers;
+
+    public WebSocketBuffers(final int bufferSize)
+    {
+        _bufferSize=bufferSize;
+        _buffers = BuffersFactory.newBuffers(Type.DIRECT,bufferSize,Type.INDIRECT,bufferSize,Type.INDIRECT,-1);
+    }
+
+    public Buffer getBuffer()
+    {
+        return _buffers.getBuffer();
+    }
+
+    public Buffer getDirectBuffer()
+    {
+        return _buffers.getHeader();
+    }
+
+    public void returnBuffer(Buffer buffer)
+    {
+        _buffers.returnBuffer(buffer);
+    }
+
+    public int getBufferSize()
+    {
+        return _bufferSize;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketClient.java b/src/java/org/eclipse/jetty/websocket/WebSocketClient.java
new file mode 100644
index 0000000..dff6a2f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketClient.java
@@ -0,0 +1,617 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ProtocolException;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SocketChannel;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Logger;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * <p>{@link WebSocketClient} allows to create multiple connections to multiple destinations
+ * that can speak the websocket protocol.</p>
+ * <p>When creating websocket connections, {@link WebSocketClient} accepts a {@link WebSocket}
+ * object (to receive events from the server), and returns a {@link WebSocket.Connection} to
+ * send data to the server.</p>
+ * <p>Example usage is as follows:</p>
+ * <pre>
+ *   WebSocketClientFactory factory = new WebSocketClientFactory();
+ *   factory.start();
+ *
+ *   WebSocketClient client = factory.newWebSocketClient();
+ *   // Configure the client
+ *
+ *   WebSocket.Connection connection = client.open(new URI("ws://127.0.0.1:8080/"), new WebSocket.OnTextMessage()
+ *   {
+ *     public void onOpen(Connection connection)
+ *     {
+ *       // open notification
+ *     }
+ *
+ *     public void onClose(int closeCode, String message)
+ *     {
+ *       // close notification
+ *     }
+ *
+ *     public void onMessage(String data)
+ *     {
+ *       // handle incoming message
+ *     }
+ *   }).get(5, TimeUnit.SECONDS);
+ *
+ *   connection.sendMessage("Hello World");
+ * </pre>
+ */
+public class WebSocketClient
+{
+    private final static Logger __log = org.eclipse.jetty.util.log.Log.getLogger(WebSocketClient.class.getName());
+
+    private final WebSocketClientFactory _factory;
+    private final Map<String,String> _cookies=new ConcurrentHashMap<String, String>();
+    private final List<String> _extensions=new CopyOnWriteArrayList<String>();
+    private String _origin;
+    private String _protocol;
+    private int _maxIdleTime=-1;
+    private int _maxTextMessageSize=16*1024;
+    private int _maxBinaryMessageSize=-1;
+    private MaskGen _maskGen;
+    private SocketAddress _bindAddress;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates a WebSocketClient from a private WebSocketClientFactory.</p>
+     * <p>This can be wasteful of resources if many clients are created.</p>
+     *
+     * @deprecated Use {@link WebSocketClientFactory#newWebSocketClient()}
+     * @throws Exception if the private WebSocketClientFactory fails to start
+     */
+    @Deprecated
+    public WebSocketClient() throws Exception
+    {
+        _factory=new WebSocketClientFactory();
+        _factory.start();
+        _maskGen=_factory.getMaskGen();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates a WebSocketClient with shared WebSocketClientFactory.</p>
+     *
+     * @param factory the shared {@link WebSocketClientFactory}
+     */
+    public WebSocketClient(WebSocketClientFactory factory)
+    {
+        _factory=factory;
+        _maskGen=_factory.getMaskGen();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The WebSocketClientFactory this client was created with.
+     */
+    public WebSocketClientFactory getFactory()
+    {
+        return _factory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the address to bind the socket channel to
+     * @see #setBindAddress(SocketAddress)
+     */
+    public SocketAddress getBindAddress()
+    {
+        return _bindAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param bindAddress the address to bind the socket channel to
+     * @see #getBindAddress()
+     */
+    public void setBindAddress(SocketAddress bindAddress)
+    {
+        this._bindAddress = bindAddress;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The maxIdleTime in ms for connections opened by this client,
+     * or -1 if the default from {@link WebSocketClientFactory#getSelectorManager()} is used.
+     * @see #setMaxIdleTime(int)
+     */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maxIdleTime The max idle time in ms for connections opened by this client
+     * @see #getMaxIdleTime()
+     */
+    public void setMaxIdleTime(int maxIdleTime)
+    {
+        _maxIdleTime=maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The subprotocol string for connections opened by this client.
+     * @see #setProtocol(String)
+     */
+    public String getProtocol()
+    {
+        return _protocol;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param protocol The subprotocol string for connections opened by this client.
+     * @see #getProtocol()
+     */
+    public void setProtocol(String protocol)
+    {
+        _protocol = protocol;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The origin URI of the client
+     * @see #setOrigin(String)
+     */
+    public String getOrigin()
+    {
+        return _origin;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param origin The origin URI of the client (eg "http://example.com")
+     * @see #getOrigin()
+     */
+    public void setOrigin(String origin)
+    {
+        _origin = origin;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Returns the map of the cookies that are sent during the initial HTTP handshake
+     * that upgrades to the websocket protocol.</p>
+     * @return The read-write cookie map
+     */
+    public Map<String,String> getCookies()
+    {
+        return _cookies;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The list of websocket protocol extensions
+     */
+    public List<String> getExtensions()
+    {
+        return _extensions;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the mask generator to use, or null if not mask generator should be used
+     * @see #setMaskGen(MaskGen)
+     */
+    public MaskGen getMaskGen()
+    {
+        return _maskGen;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maskGen the mask generator to use, or null if not mask generator should be used
+     * @see #getMaskGen()
+     */
+    public void setMaskGen(MaskGen maskGen)
+    {
+        _maskGen = maskGen;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The initial maximum text message size (in characters) for a connection
+     */
+    public int getMaxTextMessageSize()
+    {
+        return _maxTextMessageSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the initial maximum text message size for a connection. This can be changed by
+     * the application calling {@link WebSocket.Connection#setMaxTextMessageSize(int)}.
+     * @param maxTextMessageSize The default maximum text message size (in characters) for a connection
+     */
+    public void setMaxTextMessageSize(int maxTextMessageSize)
+    {
+        _maxTextMessageSize = maxTextMessageSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return The initial maximum binary message size (in bytes)  for a connection
+     */
+    public int getMaxBinaryMessageSize()
+    {
+        return _maxBinaryMessageSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the initial maximum binary message size for a connection. This can be changed by
+     * the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
+     * @param maxBinaryMessageSize The default maximum binary message size (in bytes) for a connection
+     */
+    public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
+    {
+        _maxBinaryMessageSize = maxBinaryMessageSize;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Opens a websocket connection to the URI and blocks until the connection is accepted or there is an error.</p>
+     *
+     * @param uri The URI to connect to.
+     * @param websocket The {@link WebSocket} instance to handle incoming events.
+     * @param maxConnectTime The interval to wait for a successful connection
+     * @param units the units of the maxConnectTime
+     * @return A {@link WebSocket.Connection}
+     * @throws IOException if the connection fails
+     * @throws InterruptedException if the thread is interrupted
+     * @throws TimeoutException if the timeout elapses before the connection is completed
+     * @see #open(URI, WebSocket)
+     */
+    public WebSocket.Connection open(URI uri, WebSocket websocket,long maxConnectTime,TimeUnit units) throws IOException, InterruptedException, TimeoutException
+    {
+        try
+        {
+            return open(uri,websocket).get(maxConnectTime,units);
+        }
+        catch (ExecutionException e)
+        {
+            Throwable cause = e.getCause();
+            if (cause instanceof IOException)
+                throw (IOException)cause;
+            if (cause instanceof Error)
+                throw (Error)cause;
+            if (cause instanceof RuntimeException)
+                throw (RuntimeException)cause;
+            throw new RuntimeException(cause);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Asynchronously opens a websocket connection and returns a {@link Future} to obtain the connection.</p>
+     * <p>The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open.</p>
+     *
+     * @param uri The URI to connect to.
+     * @param websocket The {@link WebSocket} instance to handle incoming events.
+     * @return A {@link Future} to the {@link WebSocket.Connection}
+     * @throws IOException if the connection fails
+     * @see #open(URI, WebSocket, long, TimeUnit)
+     */
+    public Future<WebSocket.Connection> open(URI uri, WebSocket websocket) throws IOException
+    {
+        if (!_factory.isStarted())
+            throw new IllegalStateException("Factory !started");
+
+        InetSocketAddress address = toSocketAddress(uri);
+
+        SocketChannel channel = null;
+        try
+        {
+            channel = SocketChannel.open();
+            if (_bindAddress != null)
+                channel.socket().bind(_bindAddress);
+            channel.socket().setTcpNoDelay(true);
+
+            WebSocketFuture holder = new WebSocketFuture(websocket,uri,this,channel);
+
+            channel.configureBlocking(false);
+            channel.connect(address);
+            _factory.getSelectorManager().register(channel,holder);
+
+            return holder;
+        }
+        catch (RuntimeException e)
+        {
+            // close the channel (prevent connection leak)
+            IO.close(channel);
+            
+            // rethrow
+            throw e;
+        }
+        catch(IOException e)
+        {
+            // close the channel (prevent connection leak)
+            IO.close(channel);
+
+            // rethrow
+            throw e;
+        }
+    }
+
+    public static InetSocketAddress toSocketAddress(URI uri)
+    {
+        String scheme = uri.getScheme();
+        if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme)))
+            throw new IllegalArgumentException("Bad WebSocket scheme: " + scheme);
+        int port = uri.getPort();
+        if (port == 0)
+            throw new IllegalArgumentException("Bad WebSocket port: " + port);
+        if (port < 0)
+            port = "ws".equals(scheme) ? 80 : 443;
+
+        return new InetSocketAddress(uri.getHost(), port);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** The Future Websocket Connection.
+     */
+    static class WebSocketFuture implements Future<WebSocket.Connection>
+    {
+        final WebSocket _websocket;
+        final URI _uri;
+        final WebSocketClient _client;
+        final CountDownLatch _done = new CountDownLatch(1);
+        ByteChannel _channel;
+        WebSocketConnection _connection;
+        Throwable _exception;
+
+        private WebSocketFuture(WebSocket websocket, URI uri, WebSocketClient client, ByteChannel channel)
+        {
+            _websocket=websocket;
+            _uri=uri;
+            _client=client;
+            _channel=channel;
+        }
+
+        public void onConnection(WebSocketConnection connection)
+        {
+            try
+            {
+                _client.getFactory().addConnection(connection);
+
+                connection.getConnection().setMaxTextMessageSize(_client.getMaxTextMessageSize());
+                connection.getConnection().setMaxBinaryMessageSize(_client.getMaxBinaryMessageSize());
+
+                WebSocketConnection con;
+                synchronized (this)
+                {
+                    if (_channel!=null)
+                        _connection=connection;
+                    con=_connection;
+                }
+
+                if (con!=null)
+                {
+                    if (_websocket instanceof WebSocket.OnFrame)
+                        ((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)con.getConnection());
+
+                    _websocket.onOpen(con.getConnection());
+                }
+            }
+            finally
+            {
+                _done.countDown();
+            }
+        }
+
+        public void handshakeFailed(Throwable ex)
+        {
+            try
+            {
+                ByteChannel channel=null;
+                synchronized (this)
+                {
+                    if (_channel!=null)
+                    {
+                        channel=_channel;
+                        _channel=null;
+                        _exception=ex;
+                    }
+                }
+
+                if (channel!=null)
+                {
+                    if (ex instanceof ProtocolException)
+                        closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_PROTOCOL,ex.getMessage());
+                    else
+                        closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,ex.getMessage());
+                }
+            }
+            finally
+            {
+                _done.countDown();
+            }
+        }
+
+        public Map<String,String> getCookies()
+        {
+            return _client.getCookies();
+        }
+
+        public String getProtocol()
+        {
+            return _client.getProtocol();
+        }
+
+        public WebSocket getWebSocket()
+        {
+            return _websocket;
+        }
+
+        public URI getURI()
+        {
+            return _uri;
+        }
+
+        public int getMaxIdleTime()
+        {
+            return _client.getMaxIdleTime();
+        }
+
+        public String getOrigin()
+        {
+            return _client.getOrigin();
+        }
+
+        public MaskGen getMaskGen()
+        {
+            return _client.getMaskGen();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "[" + _uri + ","+_websocket+"]@"+hashCode();
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning)
+        {
+            try
+            {
+                ByteChannel channel=null;
+                synchronized (this)
+                {
+                    if (_connection==null && _exception==null && _channel!=null)
+                    {
+                        channel=_channel;
+                        _channel=null;
+                    }
+                }
+
+                if (channel!=null)
+                {
+                    closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"cancelled");
+                    return true;
+                }
+                return false;
+            }
+            finally
+            {
+                _done.countDown();
+            }
+        }
+
+        public boolean isCancelled()
+        {
+            synchronized (this)
+            {
+                return _channel==null && _connection==null;
+            }
+        }
+
+        public boolean isDone()
+        {
+            synchronized (this)
+            {
+                return _connection!=null && _exception==null;
+            }
+        }
+
+        public org.eclipse.jetty.websocket.WebSocket.Connection get() throws InterruptedException, ExecutionException
+        {
+            try
+            {
+                return get(Long.MAX_VALUE,TimeUnit.SECONDS);
+            }
+            catch(TimeoutException e)
+            {
+                throw new IllegalStateException("The universe has ended",e);
+            }
+        }
+
+        public org.eclipse.jetty.websocket.WebSocket.Connection get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,
+                TimeoutException
+        {
+            _done.await(timeout,unit);
+            ByteChannel channel=null;
+            org.eclipse.jetty.websocket.WebSocket.Connection connection=null;
+            Throwable exception;
+            synchronized (this)
+            {
+                exception=_exception;
+                if (_connection==null)
+                {
+                    exception=_exception;
+                    channel=_channel;
+                    _channel=null;
+                }
+                else
+                    connection=_connection.getConnection();
+            }
+
+            if (channel!=null)
+                closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"timeout");
+            if (exception!=null)
+                throw new ExecutionException(exception);
+            if (connection!=null)
+                return connection;
+            throw new TimeoutException();
+        }
+
+        private void closeChannel(ByteChannel channel,int code, String message)
+        {
+            try
+            {
+                _websocket.onClose(code,message);
+            }
+            catch(Exception e)
+            {
+                __log.warn(e);
+            }
+
+            try
+            {
+                channel.close();
+            }
+            catch(IOException e)
+            {
+                __log.debug(e);
+            }
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java b/src/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java
new file mode 100644
index 0000000..4a701a5
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java
@@ -0,0 +1,574 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import javax.net.ssl.SSLEngine;
+
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.SimpleBuffers;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager;
+import org.eclipse.jetty.io.nio.SslConnection;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.component.AggregateLifeCycle;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.ThreadPool;
+
+/* ------------------------------------------------------------ */
+/**
+ * <p>WebSocketClientFactory contains the common components needed by multiple {@link WebSocketClient} instances
+ * (for example, a {@link ThreadPool}, a {@link SelectorManager NIO selector}, etc).</p>
+ * <p>WebSocketClients with different configurations should share the same factory to avoid to waste resources.</p>
+ * <p>If a ThreadPool or MaskGen is passed in the constructor, then it is not added with {@link AggregateLifeCycle#addBean(Object)},
+ * so it's lifecycle must be controlled externally.
+ *
+ * @see WebSocketClient
+ */
+public class WebSocketClientFactory extends AggregateLifeCycle
+{
+    private final static Logger __log = org.eclipse.jetty.util.log.Log.getLogger(WebSocketClientFactory.class.getName());
+    private final static ByteArrayBuffer __ACCEPT = new ByteArrayBuffer.CaseInsensitive("Sec-WebSocket-Accept");
+    private final Queue<WebSocketConnection> connections = new ConcurrentLinkedQueue<WebSocketConnection>();
+    private final SslContextFactory _sslContextFactory = new SslContextFactory();
+    private final ThreadPool _threadPool;
+    private final WebSocketClientSelector _selector;
+    private MaskGen _maskGen;
+    private WebSocketBuffers _buffers;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates a WebSocketClientFactory with the default configuration.</p>
+     */
+    public WebSocketClientFactory()
+    {
+        this(null);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates a WebSocketClientFactory with the given ThreadPool and the default configuration.</p>
+     *
+     * @param threadPool the ThreadPool instance to use
+     */
+    public WebSocketClientFactory(ThreadPool threadPool)
+    {
+        this(threadPool, new RandomMaskGen());
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates a WebSocketClientFactory with the given ThreadPool and the given MaskGen.</p>
+     *
+     * @param threadPool the ThreadPool instance to use
+     * @param maskGen    the MaskGen instance to use
+     */
+    public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen)
+    {
+        this(threadPool, maskGen, 8192);
+    }
+
+    /* ------------------------------------------------------------ */
+
+    /**
+     * <p>Creates a WebSocketClientFactory with the specified configuration.</p>
+     *
+     * @param threadPool the ThreadPool instance to use
+     * @param maskGen    the mask generator to use
+     * @param bufferSize the read buffer size
+     */
+    public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen, int bufferSize)
+    {
+        if (threadPool == null)
+            threadPool = new QueuedThreadPool();
+        _threadPool = threadPool;
+        addBean(_threadPool);
+
+        _buffers = new WebSocketBuffers(bufferSize);
+        addBean(_buffers);
+
+        _maskGen = maskGen;
+        addBean(_maskGen);
+
+        _selector = new WebSocketClientSelector();
+        addBean(_selector);
+
+        addBean(_sslContextFactory);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the SslContextFactory used to configure SSL parameters
+     */
+    public SslContextFactory getSslContextFactory()
+    {
+        return _sslContextFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the selectorManager. Used to configure the manager.
+     *
+     * @return The {@link SelectorManager} instance.
+     */
+    public SelectorManager getSelectorManager()
+    {
+        return _selector;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Get the ThreadPool.
+     * Used to set/query the thread pool configuration.
+     *
+     * @return The {@link ThreadPool}
+     */
+    public ThreadPool getThreadPool()
+    {
+        return _threadPool;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the shared mask generator, or null if no shared mask generator is used
+     * @see WebSocketClient#getMaskGen()
+     */
+    public MaskGen getMaskGen()
+    {
+        return _maskGen;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param maskGen the shared mask generator, or null if no shared mask generator is used
+     * @see WebSocketClient#setMaskGen(MaskGen)
+     */
+    public void setMaskGen(MaskGen maskGen)
+    {
+        if (isRunning())
+            throw new IllegalStateException(getState());
+        removeBean(_maskGen);
+        _maskGen = maskGen;
+        addBean(maskGen);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param bufferSize the read buffer size
+     * @see #getBufferSize()
+     */
+    public void setBufferSize(int bufferSize)
+    {
+        if (isRunning())
+            throw new IllegalStateException(getState());
+        removeBean(_buffers);
+        _buffers = new WebSocketBuffers(bufferSize);
+        addBean(_buffers);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return the read buffer size
+     */
+    public int getBufferSize()
+    {
+        return _buffers.getBufferSize();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        closeConnections();
+        super.doStop();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * <p>Creates and returns a new instance of a {@link WebSocketClient}, configured with this
+     * WebSocketClientFactory instance.</p>
+     *
+     * @return a new {@link WebSocketClient} instance
+     */
+    public WebSocketClient newWebSocketClient()
+    {
+        return new WebSocketClient(this);
+    }
+
+    protected SSLEngine newSslEngine(SocketChannel channel) throws IOException
+    {
+        SSLEngine sslEngine;
+        if (channel != null)
+        {
+            String peerHost = channel.socket().getInetAddress().getHostAddress();
+            int peerPort = channel.socket().getPort();
+            sslEngine = _sslContextFactory.newSslEngine(peerHost, peerPort);
+        }
+        else
+        {
+            sslEngine = _sslContextFactory.newSslEngine();
+        }
+        sslEngine.setUseClientMode(true);
+        sslEngine.beginHandshake();
+
+        return sslEngine;
+    }
+
+    protected boolean addConnection(WebSocketConnection connection)
+    {
+        return isRunning() && connections.add(connection);
+    }
+
+    protected boolean removeConnection(WebSocketConnection connection)
+    {
+        return connections.remove(connection);
+    }
+
+    protected void closeConnections()
+    {
+        for (WebSocketConnection connection : connections)
+            connection.shutdown();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * WebSocket Client Selector Manager
+     */
+    class WebSocketClientSelector extends SelectorManager
+    {
+        @Override
+        public boolean dispatch(Runnable task)
+        {
+            return _threadPool.dispatch(task);
+        }
+
+        @Override
+        protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, final SelectionKey key) throws IOException
+        {
+            WebSocketClient.WebSocketFuture holder = (WebSocketClient.WebSocketFuture)key.attachment();
+            int maxIdleTime = holder.getMaxIdleTime();
+            if (maxIdleTime < 0)
+                maxIdleTime = (int)getMaxIdleTime();
+            SelectChannelEndPoint result = new SelectChannelEndPoint(channel, selectSet, key, maxIdleTime);
+            AsyncEndPoint endPoint = result;
+
+            // Detect if it is SSL, and wrap the connection if so
+            if ("wss".equals(holder.getURI().getScheme()))
+            {
+                SSLEngine sslEngine = newSslEngine(channel);
+                SslConnection sslConnection = new SslConnection(sslEngine, endPoint);
+                endPoint.setConnection(sslConnection);
+                endPoint = sslConnection.getSslEndPoint();
+            }
+
+            AsyncConnection connection = selectSet.getManager().newConnection(channel, endPoint, holder);
+            endPoint.setConnection(connection);
+
+            return result;
+        }
+
+        @Override
+        public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment)
+        {
+            WebSocketClient.WebSocketFuture holder = (WebSocketClient.WebSocketFuture)attachment;
+            return new HandshakeConnection(endpoint, holder);
+        }
+
+        @Override
+        protected void endPointOpened(SelectChannelEndPoint endpoint)
+        {
+            // TODO expose on outer class ??
+        }
+
+        @Override
+        protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
+        {
+            LOG.debug("upgrade {} -> {}", oldConnection, endpoint.getConnection());
+        }
+
+        @Override
+        protected void endPointClosed(SelectChannelEndPoint endpoint)
+        {
+            endpoint.getConnection().onClose();
+        }
+
+        @Override
+        protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
+        {
+            if (!(attachment instanceof WebSocketClient.WebSocketFuture))
+                super.connectionFailed(channel, ex, attachment);
+            else
+            {
+                __log.debug(ex);
+                WebSocketClient.WebSocketFuture future = (WebSocketClient.WebSocketFuture)attachment;
+
+                future.handshakeFailed(ex);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Handshake Connection.
+     * Handles the connection until the handshake succeeds or fails.
+     */
+    class HandshakeConnection extends AbstractConnection implements AsyncConnection
+    {
+        private final AsyncEndPoint _endp;
+        private final WebSocketClient.WebSocketFuture _future;
+        private final String _key;
+        private final HttpParser _parser;
+        private String _accept;
+        private String _error;
+        private ByteArrayBuffer _handshake;
+
+        public HandshakeConnection(AsyncEndPoint endpoint, WebSocketClient.WebSocketFuture future)
+        {
+            super(endpoint, System.currentTimeMillis());
+            _endp = endpoint;
+            _future = future;
+
+            byte[] bytes = new byte[16];
+            new Random().nextBytes(bytes);
+            _key = new String(B64Code.encode(bytes));
+
+            Buffers buffers = new SimpleBuffers(_buffers.getBuffer(), null);
+            _parser = new HttpParser(buffers, _endp, new HttpParser.EventHandler()
+            {
+                @Override
+                public void startResponse(Buffer version, int status, Buffer reason) throws IOException
+                {
+                    if (status != 101)
+                    {
+                        _error = "Bad response status " + status + " " + reason;
+                        _endp.close();
+                    }
+                }
+
+                @Override
+                public void parsedHeader(Buffer name, Buffer value) throws IOException
+                {
+                    if (__ACCEPT.equals(name))
+                        _accept = value.toString();
+                }
+
+                @Override // TODO simone says shouldn't be needed
+                public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException
+                {
+                    if (_error == null)
+                        _error = "Bad response: " + method + " " + url + " " + version;
+                    _endp.close();
+                }
+
+                @Override // TODO simone says shouldn't be needed
+                public void content(Buffer ref) throws IOException
+                {
+                    if (_error == null)
+                        _error = "Bad response. " + ref.length() + "B of content?";
+                    _endp.close();
+                }
+            });
+        }
+
+        private boolean handshake()
+        {
+            if (_handshake==null)
+            {
+                String path = _future.getURI().getPath();
+                if (path == null || path.length() == 0)
+                    path = "/";
+
+                if (_future.getURI().getRawQuery() != null)
+                    path += "?" + _future.getURI().getRawQuery();
+
+                String origin = _future.getOrigin();
+
+                StringBuilder request = new StringBuilder(512);
+                request.append("GET ").append(path).append(" HTTP/1.1\r\n")
+                .append("Host: ").append(_future.getURI().getHost()).append(":")
+                .append(_future.getURI().getPort()).append("\r\n")
+                .append("Upgrade: websocket\r\n")
+                .append("Connection: Upgrade\r\n")
+                .append("Sec-WebSocket-Key: ")
+                .append(_key).append("\r\n");
+
+                if (origin != null)
+                    request.append("Origin: ").append(origin).append("\r\n");
+
+                request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n");
+
+                if (_future.getProtocol() != null)
+                    request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n");
+
+                Map<String, String> cookies = _future.getCookies();
+                if (cookies != null && cookies.size() > 0)
+                {
+                    for (String cookie : cookies.keySet())
+                        request.append("Cookie: ")
+                        .append(QuotedStringTokenizer.quoteIfNeeded(cookie, HttpFields.__COOKIE_DELIM))
+                        .append("=")
+                        .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), HttpFields.__COOKIE_DELIM))
+                        .append("\r\n");
+                }
+
+                request.append("\r\n");
+
+                _handshake=new ByteArrayBuffer(request.toString(), false);
+            }
+            
+            // TODO extensions
+
+            try
+            {
+                int len = _handshake.length();
+                int flushed = _endp.flush(_handshake);
+                if (flushed<0)
+                    throw new IOException("incomplete handshake");
+            }
+            catch (IOException e)
+            {
+                _future.handshakeFailed(e);
+            }
+            return _handshake.length()==0;
+        }
+
+        public Connection handle() throws IOException
+        {
+            while (_endp.isOpen() && !_parser.isComplete())
+            {
+                if (_handshake==null || _handshake.length()>0)
+                    if (!handshake())
+                        return this;
+
+                if (!_parser.parseAvailable())
+                {
+                    if (_endp.isInputShutdown())
+                        _future.handshakeFailed(new IOException("Incomplete handshake response"));
+                    return this;
+                }
+            }
+            if (_error == null)
+            {
+                if (_accept == null)
+                {
+                    _error = "No Sec-WebSocket-Accept";
+                }
+                else if (!WebSocketConnectionRFC6455.hashKey(_key).equals(_accept))
+                {
+                    _error = "Bad Sec-WebSocket-Accept";
+                }
+                else
+                {
+                    WebSocketConnection connection = newWebSocketConnection();
+
+                    Buffer header = _parser.getHeaderBuffer();
+                    if (header.hasContent())
+                        connection.fillBuffersFrom(header);
+                    _buffers.returnBuffer(header);
+
+                    _future.onConnection(connection);
+
+                    return connection;
+                }
+            }
+
+            _endp.close();
+            return this;
+        }
+
+        private WebSocketConnection newWebSocketConnection() throws IOException
+        {
+            __log.debug("newWebSocketConnection()");
+            return new WebSocketClientConnection(
+                    _future._client.getFactory(),
+                    _future.getWebSocket(),
+                    _endp,
+                    _buffers,
+                    System.currentTimeMillis(),
+                    _future.getMaxIdleTime(),
+                    _future.getProtocol(),
+                    null,
+                    WebSocketConnectionRFC6455.VERSION,
+                    _future.getMaskGen());
+        }
+
+        public void onInputShutdown() throws IOException
+        {
+            _endp.close();
+        }
+
+        public boolean isIdle()
+        {
+            return false;
+        }
+
+        public boolean isSuspended()
+        {
+            return false;
+        }
+
+        public void onClose()
+        {
+            if (_error != null)
+                _future.handshakeFailed(new ProtocolException(_error));
+            else
+                _future.handshakeFailed(new EOFException());
+        }
+    }
+
+    private static class WebSocketClientConnection extends WebSocketConnectionRFC6455
+    {
+        private final WebSocketClientFactory factory;
+
+        public WebSocketClientConnection(WebSocketClientFactory factory, WebSocket webSocket, EndPoint endPoint, WebSocketBuffers buffers, long timeStamp, int maxIdleTime, String protocol, List<Extension> extensions, int draftVersion, MaskGen maskGen) throws IOException
+        {
+            super(webSocket, endPoint, buffers, timeStamp, maxIdleTime, protocol, extensions, draftVersion, maskGen);
+            this.factory = factory;
+        }
+
+        @Override
+        public void onClose()
+        {
+            super.onClose();
+            factory.removeConnection(this);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketConnection.java b/src/java/org/eclipse/jetty/websocket/WebSocketConnection.java
new file mode 100644
index 0000000..8412feb
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketConnection.java
@@ -0,0 +1,36 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+
+import java.util.List;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.nio.AsyncConnection;
+
+public interface WebSocketConnection extends AsyncConnection
+{
+    void fillBuffersFrom(Buffer buffer);
+
+    List<Extension> getExtensions();
+
+    WebSocket.Connection getConnection();
+
+    void shutdown();
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java
new file mode 100644
index 0000000..06740a1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD00.java
@@ -0,0 +1,514 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.WebSocket.OnFrame;
+
+public class WebSocketConnectionD00 extends AbstractConnection implements WebSocketConnection, WebSocket.FrameConnection
+{
+    private static final Logger LOG = Log.getLogger(WebSocketConnectionD00.class);
+
+    public final static byte LENGTH_FRAME=(byte)0x80;
+    public final static byte SENTINEL_FRAME=(byte)0x00;
+
+    private final WebSocketParser _parser;
+    private final WebSocketGenerator _generator;
+    private final WebSocket _websocket;
+    private final String _protocol;
+    private String _key1;
+    private String _key2;
+    private ByteArrayBuffer _hixieBytes;
+
+    public WebSocketConnectionD00(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol)
+        throws IOException
+    {
+        super(endpoint,timestamp);
+
+        _endp.setMaxIdleTime(maxIdleTime);
+
+        _websocket = websocket;
+        _protocol=protocol;
+
+        _generator = new WebSocketGeneratorD00(buffers, _endp);
+        _parser = new WebSocketParserD00(buffers, endpoint, new FrameHandlerD00(_websocket));
+    }
+
+    /* ------------------------------------------------------------ */
+    public org.eclipse.jetty.websocket.WebSocket.Connection getConnection()
+    {
+        return this;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public void setHixieKeys(String key1,String key2)
+    {
+        _key1=key1;
+        _key2=key2;
+        _hixieBytes=new IndirectNIOBuffer(16);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection handle() throws IOException
+    {
+        try
+        {
+            // handle stupid hixie random bytes
+            if (_hixieBytes!=null)
+            {
+
+                // take any available bytes from the parser buffer, which may have already been read
+                Buffer buffer=_parser.getBuffer();
+                if (buffer!=null && buffer.length()>0)
+                {
+                    int l=buffer.length();
+                    if (l>(8-_hixieBytes.length()))
+                        l=8-_hixieBytes.length();
+                    _hixieBytes.put(buffer.peek(buffer.getIndex(),l));
+                    buffer.skip(l);
+                }
+
+                // while we are not blocked
+                while(_endp.isOpen())
+                {
+                    // do we now have enough
+                    if (_hixieBytes.length()==8)
+                    {
+                        // we have the silly random bytes
+                        // so let's work out the stupid 16 byte reply.
+                        doTheHixieHixieShake();
+                        _endp.flush(_hixieBytes);
+                        _hixieBytes=null;
+                        _endp.flush();
+                        break;
+                    }
+
+                    // no, then let's fill
+                    int filled=_endp.fill(_hixieBytes);
+                    if (filled<0)
+                    {
+                        _endp.flush();
+                        _endp.close();
+                        break;
+                    }
+                    else if (filled==0)
+                        return this;
+                }
+
+                if (_websocket instanceof OnFrame)
+                    ((OnFrame)_websocket).onHandshake(this);
+                _websocket.onOpen(this);
+                return this;
+            }
+
+            // handle the framing protocol
+            boolean progress=true;
+
+            while (progress)
+            {
+                int flushed=_generator.flush();
+                int filled=_parser.parseNext();
+
+                progress = flushed>0 || filled>0;
+
+                _endp.flush();
+
+                if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed())
+                    progress=true;
+            }
+        }
+        catch(IOException e)
+        {
+            LOG.debug(e);
+            try
+            {
+                if (_endp.isOpen())
+                    _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+            throw e;
+        }
+        finally
+        {
+            if (_endp.isOpen())
+            {
+                if (_endp.isInputShutdown() && _generator.isBufferEmpty())
+                    _endp.close();
+                else
+                    checkWriteable();
+
+                checkWriteable();
+            }
+        }
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onInputShutdown() throws IOException
+    {
+        // TODO
+    }
+
+    /* ------------------------------------------------------------ */
+    private void doTheHixieHixieShake()
+    {
+        byte[] result=WebSocketConnectionD00.doTheHixieHixieShake(
+                WebSocketConnectionD00.hixieCrypt(_key1),
+                WebSocketConnectionD00.hixieCrypt(_key2),
+                _hixieBytes.asArray());
+        _hixieBytes.clear();
+        _hixieBytes.put(result);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isOpen()
+    {
+        return _endp!=null&&_endp.isOpen();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _parser.isBufferEmpty() && _generator.isBufferEmpty();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        _websocket.onClose(WebSocketConnectionD06.CLOSE_NORMAL,"");
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     */
+    public void sendMessage(String content) throws IOException
+    {
+        byte[] data = content.getBytes(StringUtil.__UTF8);
+        _generator.addFrame((byte)0,SENTINEL_FRAME,data,0,data.length);
+        _generator.flush();
+        checkWriteable();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void sendMessage(byte[] data, int offset, int length) throws IOException
+    {
+        _generator.addFrame((byte)0,LENGTH_FRAME,data,offset,length);
+        _generator.flush();
+        checkWriteable();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isMore(byte flags)
+    {
+        return (flags&0x8) != 0;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * {@inheritDoc}
+     */
+    public void sendControl(byte code, byte[] content, int offset, int length) throws IOException
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        _generator.addFrame((byte)0,opcode,content,offset,length);
+        _generator.flush();
+        checkWriteable();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void close(int code, String message)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void disconnect()
+    {
+        close();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void close()
+    {
+        try
+        {
+            _generator.flush();
+            _endp.close();
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+        }
+    }
+
+    public void shutdown()
+    {
+        close();
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fillBuffersFrom(Buffer buffer)
+    {
+        _parser.fill(buffer);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    private void checkWriteable()
+    {
+        if (!_generator.isBufferEmpty() && _endp instanceof AsyncEndPoint)
+            ((AsyncEndPoint)_endp).scheduleWrite();
+    }
+
+    /* ------------------------------------------------------------ */
+    static long hixieCrypt(String key)
+    {
+        // Don't ask me what all this is about.
+        // I think it's pretend secret stuff, kind of
+        // like talking in pig latin!
+        long number=0;
+        int spaces=0;
+        for (char c : key.toCharArray())
+        {
+            if (Character.isDigit(c))
+                number=number*10+(c-'0');
+            else if (c==' ')
+                spaces++;
+        }
+        return number/spaces;
+    }
+
+    public static byte[] doTheHixieHixieShake(long key1,long key2,byte[] key3)
+    {
+        try
+        {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte [] fodder = new byte[16];
+
+            fodder[0]=(byte)(0xff&(key1>>24));
+            fodder[1]=(byte)(0xff&(key1>>16));
+            fodder[2]=(byte)(0xff&(key1>>8));
+            fodder[3]=(byte)(0xff&key1);
+            fodder[4]=(byte)(0xff&(key2>>24));
+            fodder[5]=(byte)(0xff&(key2>>16));
+            fodder[6]=(byte)(0xff&(key2>>8));
+            fodder[7]=(byte)(0xff&key2);
+            System.arraycopy(key3, 0, fodder, 8, 8);
+            md.update(fodder);
+            return md.digest();
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public void setMaxTextMessageSize(int size)
+    {
+    }
+
+    public void setMaxIdleTime(int ms)
+    {
+        try
+        {
+            _endp.setMaxIdleTime(ms);
+        }
+        catch(IOException e)
+        {
+            LOG.warn(e);
+        }
+    }
+
+    public void setMaxBinaryMessageSize(int size)
+    {
+    }
+
+    public int getMaxTextMessageSize()
+    {
+        return -1;
+    }
+
+    public int getMaxIdleTime()
+    {
+        return _endp.getMaxIdleTime();
+    }
+
+    public int getMaxBinaryMessageSize()
+    {
+        return -1;
+    }
+
+    public String getProtocol()
+    {
+        return _protocol;
+    }
+
+    protected void onFrameHandshake()
+    {
+        if (_websocket instanceof OnFrame)
+        {
+            ((OnFrame)_websocket).onHandshake(this);
+        }
+    }
+
+    protected void onWebsocketOpen()
+    {
+        _websocket.onOpen(this);
+    }
+
+    static class FrameHandlerD00 implements WebSocketParser.FrameHandler
+    {
+        final WebSocket _websocket;
+
+        FrameHandlerD00(WebSocket websocket)
+        {
+            _websocket=websocket;
+        }
+
+        public void onFrame(byte flags, byte opcode, Buffer buffer)
+        {
+            try
+            {
+                byte[] array=buffer.array();
+
+                if (opcode==0)
+                {
+                    if (_websocket instanceof WebSocket.OnTextMessage)
+                        ((WebSocket.OnTextMessage)_websocket).onMessage(buffer.toString(StringUtil.__UTF8));
+                }
+                else
+                {
+                    if (_websocket instanceof WebSocket.OnBinaryMessage)
+                        ((WebSocket.OnBinaryMessage)_websocket).onMessage(array,buffer.getIndex(),buffer.length());
+                }
+            }
+            catch(Throwable th)
+            {
+                LOG.warn(th);
+            }
+        }
+
+        public void close(int code,String message)
+        {
+        }
+    }
+
+    public boolean isMessageComplete(byte flags)
+    {
+        return true;
+    }
+
+    public byte binaryOpcode()
+    {
+        return LENGTH_FRAME;
+    }
+
+    public byte textOpcode()
+    {
+        return SENTINEL_FRAME;
+    }
+
+    public boolean isControl(byte opcode)
+    {
+        return false;
+    }
+
+    public boolean isText(byte opcode)
+    {
+        return (opcode&LENGTH_FRAME)==0;
+    }
+
+    public boolean isBinary(byte opcode)
+    {
+        return (opcode&LENGTH_FRAME)!=0;
+    }
+
+    public boolean isContinuation(byte opcode)
+    {
+        return false;
+    }
+
+    public boolean isClose(byte opcode)
+    {
+        return false;
+    }
+
+    public boolean isPing(byte opcode)
+    {
+        return false;
+    }
+
+    public boolean isPong(byte opcode)
+    {
+        return false;
+    }
+
+    public List<Extension> getExtensions()
+    {
+        return Collections.emptyList();
+    }
+
+    public byte continuationOpcode()
+    {
+        return 0;
+    }
+
+    public byte finMask()
+    {
+        return 0;
+    }
+
+    public void setAllowFrameFragmentation(boolean allowFragmentation)
+    {
+    }
+
+    public boolean isAllowFrameFragmentation()
+    {
+        return false;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java
new file mode 100644
index 0000000..5b47723
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD06.java
@@ -0,0 +1,734 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.Utf8StringBuilder;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage;
+import org.eclipse.jetty.websocket.WebSocket.OnControl;
+import org.eclipse.jetty.websocket.WebSocket.OnFrame;
+import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
+
+public class WebSocketConnectionD06 extends AbstractConnection implements WebSocketConnection
+{
+    private static final Logger LOG = Log.getLogger(WebSocketConnectionD06.class);
+
+    final static byte OP_CONTINUATION = 0x00;
+    final static byte OP_CLOSE = 0x01;
+    final static byte OP_PING = 0x02;
+    final static byte OP_PONG = 0x03;
+    final static byte OP_TEXT = 0x04;
+    final static byte OP_BINARY = 0x05;
+
+    final static int CLOSE_NORMAL=1000;
+    final static int CLOSE_SHUTDOWN=1001;
+    final static int CLOSE_PROTOCOL=1002;
+    final static int CLOSE_BADDATA=1003;
+    final static int CLOSE_LARGE=1004;
+
+    static boolean isLastFrame(int flags)
+    {
+        return (flags&0x8)!=0;
+    }
+
+    static boolean isControlFrame(int opcode)
+    {
+        switch(opcode)
+        {
+            case OP_CLOSE:
+            case OP_PING:
+            case OP_PONG:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private final static byte[] MAGIC;
+    private final WebSocketParser _parser;
+    private final WebSocketGenerator _generator;
+    private final WebSocket _webSocket;
+    private final OnFrame _onFrame;
+    private final OnBinaryMessage _onBinaryMessage;
+    private final OnTextMessage _onTextMessage;
+    private final OnControl _onControl;
+    private final String _protocol;
+    private volatile boolean _closedIn;
+    private volatile boolean _closedOut;
+    private int _maxTextMessageSize;
+    private int _maxBinaryMessageSize=-1;
+
+    static
+    {
+        try
+        {
+            MAGIC="258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StringUtil.__ISO_8859_1);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final WebSocketParser.FrameHandler _frameHandler= new FrameHandlerD06();
+    private final WebSocket.FrameConnection _connection = new FrameConnectionD06();
+
+
+    /* ------------------------------------------------------------ */
+    public WebSocketConnectionD06(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol)
+        throws IOException
+    {
+        super(endpoint,timestamp);
+
+        _endp.setMaxIdleTime(maxIdleTime);
+
+        _webSocket = websocket;
+        _onFrame=_webSocket instanceof OnFrame ? (OnFrame)_webSocket : null;
+        _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null;
+        _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null;
+        _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null;
+        _generator = new WebSocketGeneratorD06(buffers, _endp,null);
+        _parser = new WebSocketParserD06(buffers, endpoint, _frameHandler,true);
+        _protocol=protocol;
+
+        _maxTextMessageSize=buffers.getBufferSize();
+        _maxBinaryMessageSize=-1;
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebSocket.Connection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection handle() throws IOException
+    {
+        try
+        {
+            // handle the framing protocol
+            boolean progress=true;
+
+            while (progress)
+            {
+                int flushed=_generator.flush();
+                int filled=_parser.parseNext();
+
+                progress = flushed>0 || filled>0;
+
+                if (filled<0 || flushed<0)
+                {
+                    _endp.close();
+                    break;
+                }
+            }
+        }
+        catch(IOException e)
+        {
+            try
+            {
+                _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+            throw e;
+        }
+        finally
+        {
+            if (_endp.isOpen())
+            {
+                if (_closedIn && _closedOut && _generator.isBufferEmpty())
+                    _endp.close();
+                else if (_endp.isInputShutdown() && !_closedIn)
+                    closeIn(CLOSE_PROTOCOL,null);
+                else
+                    checkWriteable();
+            }
+
+        }
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onInputShutdown() throws IOException
+    {
+        // TODO
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _parser.isBufferEmpty() && _generator.isBufferEmpty();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void onIdleExpired(long idleForMs)
+    {
+        closeOut(WebSocketConnectionD06.CLOSE_NORMAL,"Idle");
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        _webSocket.onClose(WebSocketConnectionD06.CLOSE_NORMAL,"");
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized void closeIn(int code,String message)
+    {
+        LOG.debug("ClosedIn {} {}",this,message);
+        try
+        {
+            if (_closedOut)
+                _endp.close();
+            else
+                closeOut(code,message);
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+        }
+        finally
+        {
+            _closedIn=true;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized void closeOut(int code,String message)
+    {
+        LOG.debug("ClosedOut {} {}",this,message);
+        try
+        {
+            if (_closedIn || _closedOut)
+                _endp.close();
+            else
+            {
+                if (code<=0)
+                    code=WebSocketConnectionD06.CLOSE_NORMAL;
+                byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1);
+                bytes[0]=(byte)(code/0x100);
+                bytes[1]=(byte)(code%0x100);
+                _generator.addFrame((byte)0x8,WebSocketConnectionD06.OP_CLOSE,bytes,0,bytes.length);
+            }
+            _generator.flush();
+
+        }
+        catch(IOException e)
+        {
+            LOG.ignore(e);
+        }
+        finally
+        {
+            _closedOut=true;
+        }
+    }
+
+    public void shutdown()
+    {
+        final WebSocket.Connection connection = _connection;
+        if (connection != null)
+            connection.close(CLOSE_SHUTDOWN, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fillBuffersFrom(Buffer buffer)
+    {
+        _parser.fill(buffer);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void checkWriteable()
+    {
+        if (!_generator.isBufferEmpty() && _endp instanceof AsyncEndPoint)
+        {
+            ((AsyncEndPoint)_endp).scheduleWrite();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public List<Extension> getExtensions()
+    {
+        return Collections.emptyList();
+    }
+
+    protected void onFrameHandshake()
+    {
+        if (_onFrame!=null)
+        {
+            _onFrame.onHandshake(_connection);
+        }
+    }
+
+    protected void onWebSocketOpen()
+    {
+        _webSocket.onOpen(_connection);
+    }
+
+    /* ------------------------------------------------------------ */
+    private class FrameConnectionD06 implements WebSocket.FrameConnection
+    {
+        volatile boolean _disconnecting;
+        int _maxTextMessage=WebSocketConnectionD06.this._maxTextMessageSize;
+        int _maxBinaryMessage=WebSocketConnectionD06.this._maxBinaryMessageSize;
+
+        /* ------------------------------------------------------------ */
+        public synchronized void sendMessage(String content) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closing");
+            byte[] data = content.getBytes(StringUtil.__UTF8);
+            _generator.addFrame((byte)0x8,WebSocketConnectionD06.OP_TEXT,data,0,data.length);
+            _generator.flush();
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public synchronized void sendMessage(byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closing");
+            _generator.addFrame((byte)0x8,WebSocketConnectionD06.OP_BINARY,content,offset,length);
+            _generator.flush();
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closing");
+            _generator.addFrame(flags,opcode,content,offset,length);
+            _generator.flush();
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendControl(byte control, byte[] data, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closing");
+            _generator.addFrame((byte)0x8,control,data,offset,length);
+            _generator.flush();
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isMessageComplete(byte flags)
+        {
+            return isLastFrame(flags);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isOpen()
+        {
+            return _endp!=null&&_endp.isOpen();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close(int code, String message)
+        {
+            if (_disconnecting)
+                return;
+            _disconnecting=true;
+            WebSocketConnectionD06.this.closeOut(code,message);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxIdleTime(int ms)
+        {
+            try
+            {
+                _endp.setMaxIdleTime(ms);
+            }
+            catch(IOException e)
+            {
+                LOG.warn(e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxTextMessageSize(int size)
+        {
+            _maxTextMessage=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxBinaryMessageSize(int size)
+        {
+            _maxBinaryMessage=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxTextMessageSize()
+        {
+            return _maxTextMessage;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxIdleTime()
+        {
+            return _endp.getMaxIdleTime();
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxBinaryMessageSize()
+        {
+            return _maxBinaryMessage;
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getProtocol()
+        {
+            return _protocol;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte binaryOpcode()
+        {
+            return OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte textOpcode()
+        {
+            return OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte continuationOpcode()
+        {
+            return OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte finMask()
+        {
+            return 0x8;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isControl(byte opcode)
+        {
+            return isControlFrame(opcode);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isText(byte opcode)
+        {
+            return opcode==OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isBinary(byte opcode)
+        {
+            return opcode==OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isContinuation(byte opcode)
+        {
+            return opcode==OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isClose(byte opcode)
+        {
+            return opcode==OP_CLOSE;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPing(byte opcode)
+        {
+            return opcode==OP_PING;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPong(byte opcode)
+        {
+            return opcode==OP_PONG;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void disconnect()
+        {
+            close();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close()
+        {
+            close(CLOSE_NORMAL,null);
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return this.getClass().getSimpleName()+"@"+_endp.getLocalAddr()+":"+_endp.getLocalPort()+"<->"+_endp.getRemoteAddr()+":"+_endp.getRemotePort();
+        }
+
+        public void setAllowFrameFragmentation(boolean allowFragmentation)
+        {
+        }
+
+        public boolean isAllowFrameFragmentation()
+        {
+            return false;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class FrameHandlerD06 implements WebSocketParser.FrameHandler
+    {
+        private final Utf8StringBuilder _utf8 = new Utf8StringBuilder();
+        private ByteArrayBuffer _aggregate;
+        private byte _opcode=-1;
+
+        public void onFrame(byte flags, byte opcode, Buffer buffer)
+        {
+            boolean lastFrame = isLastFrame(flags);
+
+            synchronized(WebSocketConnectionD06.this)
+            {
+                // Ignore incoming after a close
+                if (_closedIn)
+                    return;
+
+                try
+                {
+                    byte[] array=buffer.array();
+
+                    // Deliver frame if websocket is a FrameWebSocket
+                    if (_onFrame!=null)
+                    {
+                        if (_onFrame.onFrame(flags,opcode,array,buffer.getIndex(),buffer.length()))
+                            return;
+                    }
+
+                    if (_onControl!=null && isControlFrame(opcode))
+                    {
+                        if (_onControl.onControl(opcode,array,buffer.getIndex(),buffer.length()))
+                            return;
+                    }
+
+                    switch(opcode)
+                    {
+                        case WebSocketConnectionD06.OP_CONTINUATION:
+                        {
+                            // If text, append to the message buffer
+                            if (_opcode==WebSocketConnectionD06.OP_TEXT && _connection.getMaxTextMessageSize()>=0)
+                            {
+                                if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                                {
+                                    // If this is the last fragment, deliver the text buffer
+                                    if (lastFrame && _onTextMessage!=null)
+                                    {
+                                        _opcode=-1;
+                                        String msg =_utf8.toString();
+                                        _utf8.reset();
+                                        _onTextMessage.onMessage(msg);
+                                    }
+                                }
+                                else
+                                {
+                                    _connection.close(WebSocketConnectionD06.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
+                                    _utf8.reset();
+                                    _opcode=-1;
+                                }
+                            }
+                            else if (_opcode>=0 && _connection.getMaxBinaryMessageSize()>=0)
+                            {
+                                if (_aggregate.space()<_aggregate.length())
+                                {
+                                    _connection.close(WebSocketConnectionD06.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize());
+                                    _aggregate.clear();
+                                    _opcode=-1;
+                                }
+                                else
+                                {
+                                    _aggregate.put(buffer);
+
+                                    // If this is the last fragment, deliver
+                                    if (lastFrame && _onBinaryMessage!=null)
+                                    {
+                                        try
+                                        {
+                                            _onBinaryMessage.onMessage(_aggregate.array(),_aggregate.getIndex(),_aggregate.length());
+                                        }
+                                        finally
+                                        {
+                                            _opcode=-1;
+                                            _aggregate.clear();
+                                        }
+                                    }
+                                }
+                            }
+                            break;
+                        }
+                        case WebSocketConnectionD06.OP_PING:
+                        {
+                            LOG.debug("PING {}",this);
+                            if (!_closedOut)
+                                _connection.sendControl(WebSocketConnectionD06.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
+                            break;
+                        }
+
+                        case WebSocketConnectionD06.OP_PONG:
+                        {
+                            LOG.debug("PONG {}",this);
+                            break;
+                        }
+
+                        case WebSocketConnectionD06.OP_CLOSE:
+                        {
+                            int code=-1;
+                            String message=null;
+                            if (buffer.length()>=2)
+                            {
+                                code=buffer.array()[buffer.getIndex()]*0xff+buffer.array()[buffer.getIndex()+1];
+                                if (buffer.length()>2)
+                                    message=new String(buffer.array(),buffer.getIndex()+2,buffer.length()-2,StringUtil.__UTF8);
+                            }
+                            closeIn(code,message);
+                            break;
+                        }
+
+
+                        case WebSocketConnectionD06.OP_TEXT:
+                        {
+                            if(_onTextMessage!=null)
+                            {
+                                if (lastFrame)
+                                {
+                                    // Deliver the message
+                                    _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8));
+                                }
+                                else
+                                {
+                                    if (_connection.getMaxTextMessageSize()>=0)
+                                    {
+                                        // If this is a text fragment, append to buffer
+                                        if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                                            _opcode=WebSocketConnectionD06.OP_TEXT;
+                                        else
+                                        {
+                                            _utf8.reset();
+                                            _opcode=-1;
+                                            _connection.close(WebSocketConnectionD06.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
+                                        }
+                                    }
+                                }
+                            }
+                            break;
+                        }
+
+                        default:
+                        {
+                            if (_onBinaryMessage!=null)
+                            {
+                                if (lastFrame)
+                                {
+                                    _onBinaryMessage.onMessage(array,buffer.getIndex(),buffer.length());
+                                }
+                                else
+                                {
+                                    if (_connection.getMaxBinaryMessageSize()>=0)
+                                    {
+                                        if (buffer.length()>_connection.getMaxBinaryMessageSize())
+                                        {
+                                            _connection.close(WebSocketConnectionD06.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize());
+                                            if (_aggregate!=null)
+                                                _aggregate.clear();
+                                            _opcode=-1;
+                                        }
+                                        else
+                                        {
+                                            _opcode=opcode;
+                                            if (_aggregate==null)
+                                                _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
+                                            _aggregate.put(buffer);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                catch(Throwable th)
+                {
+                    LOG.warn(th);
+                }
+            }
+        }
+
+        public void close(int code,String message)
+        {
+            _connection.close(code,message);
+        }
+
+        @Override
+        public String toString()
+        {
+            return WebSocketConnectionD06.this.toString()+"FH";
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String hashKey(String key)
+    {
+        try
+        {
+            MessageDigest md = MessageDigest.getInstance("SHA1");
+            md.update(key.getBytes("UTF-8"));
+            md.update(MAGIC);
+            return new String(B64Code.encode(md.digest()));
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java
new file mode 100644
index 0000000..a6fa9ff
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionD08.java
@@ -0,0 +1,854 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.Utf8StringBuilder;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage;
+import org.eclipse.jetty.websocket.WebSocket.OnControl;
+import org.eclipse.jetty.websocket.WebSocket.OnFrame;
+import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
+
+public class WebSocketConnectionD08 extends AbstractConnection implements WebSocketConnection
+{
+    private static final Logger LOG = Log.getLogger(WebSocketConnectionD08.class);
+
+    final static byte OP_CONTINUATION = 0x00;
+    final static byte OP_TEXT = 0x01;
+    final static byte OP_BINARY = 0x02;
+    final static byte OP_EXT_DATA = 0x03;
+
+    final static byte OP_CONTROL = 0x08;
+    final static byte OP_CLOSE = 0x08;
+    final static byte OP_PING = 0x09;
+    final static byte OP_PONG = 0x0A;
+    final static byte OP_EXT_CTRL = 0x0B;
+
+    final static int CLOSE_NORMAL=1000;
+    final static int CLOSE_SHUTDOWN=1001;
+    final static int CLOSE_PROTOCOL=1002;
+    final static int CLOSE_BADDATA=1003;
+    final static int CLOSE_NOCODE=1005;
+    final static int CLOSE_NOCLOSE=1006;
+    final static int CLOSE_NOTUTF8=1007;
+
+    final static int FLAG_FIN=0x8;
+
+    final static int VERSION=8;
+
+    static boolean isLastFrame(byte flags)
+    {
+        return (flags&FLAG_FIN)!=0;
+    }
+
+    static boolean isControlFrame(byte opcode)
+    {
+        return (opcode&OP_CONTROL)!=0;
+    }
+
+    private final static byte[] MAGIC;
+    private final List<Extension> _extensions;
+    private final WebSocketParserD08 _parser;
+    private final WebSocketGeneratorD08 _generator;
+    private final WebSocketGenerator _outbound;
+    private final WebSocket _webSocket;
+    private final OnFrame _onFrame;
+    private final OnBinaryMessage _onBinaryMessage;
+    private final OnTextMessage _onTextMessage;
+    private final OnControl _onControl;
+    private final String _protocol;
+    private final int _draft;
+    private final ClassLoader _context;
+    private volatile int _closeCode;
+    private volatile String _closeMessage;
+    private volatile boolean _closedIn;
+    private volatile boolean _closedOut;
+    private int _maxTextMessageSize=-1;
+    private int _maxBinaryMessageSize=-1;
+
+    static
+    {
+        try
+        {
+            MAGIC="258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StringUtil.__ISO_8859_1);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final WebSocket.FrameConnection _connection = new WSFrameConnection();
+
+
+    /* ------------------------------------------------------------ */
+    public WebSocketConnectionD08(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft)
+        throws IOException
+    {
+        this(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol,extensions,draft,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebSocketConnectionD08(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft, MaskGen maskgen)
+        throws IOException
+    {
+        super(endpoint,timestamp);
+
+        _context=Thread.currentThread().getContextClassLoader();
+
+        _draft=draft;
+        _endp.setMaxIdleTime(maxIdleTime);
+
+        _webSocket = websocket;
+        _onFrame=_webSocket instanceof OnFrame ? (OnFrame)_webSocket : null;
+        _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null;
+        _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null;
+        _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null;
+        _generator = new WebSocketGeneratorD08(buffers, _endp,maskgen);
+
+        _extensions=extensions;
+        WebSocketParser.FrameHandler _frameHandler= new WSFrameHandler();
+        if (_extensions!=null)
+        {
+            int e=0;
+            for (Extension extension : _extensions)
+            {
+                extension.bind(
+                        _connection,
+                        e==extensions.size()-1?_frameHandler:extensions.get(e+1),
+                        e==0?_generator:extensions.get(e-1));
+                e++;
+            }
+        }
+
+        _outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1);
+        WebSocketParser.FrameHandler _inbound=(_extensions==null||_extensions.size()==0)?_frameHandler:extensions.get(0);
+
+        _parser = new WebSocketParserD08(buffers, endpoint,_inbound,maskgen==null);
+
+        _protocol=protocol;
+
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebSocket.Connection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    public List<Extension> getExtensions()
+    {
+        if (_extensions==null)
+            return Collections.emptyList();
+
+        return _extensions;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection handle() throws IOException
+    {
+        Thread current = Thread.currentThread();
+        ClassLoader oldcontext = current.getContextClassLoader();
+        current.setContextClassLoader(_context);
+        try
+        {
+            // handle the framing protocol
+            boolean progress=true;
+
+            while (progress)
+            {
+                int flushed=_generator.flushBuffer();
+                int filled=_parser.parseNext();
+
+                progress = flushed>0 || filled>0;
+                _endp.flush();
+
+                if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed())
+                    progress=true;
+            }
+        }
+        catch(IOException e)
+        {
+            try
+            {
+                if (_endp.isOpen())
+                    _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+            throw e;
+        }
+        finally
+        {
+            current.setContextClassLoader(oldcontext);
+            _parser.returnBuffer();
+            _generator.returnBuffer();
+            if (_endp.isOpen())
+            {
+                if (_closedIn && _closedOut && _outbound.isBufferEmpty())
+                    _endp.close();
+                else if (_endp.isInputShutdown() && !_closedIn)
+                    closeIn(CLOSE_NOCLOSE,null);
+                else
+                    checkWriteable();
+            }
+        }
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onInputShutdown() throws IOException
+    {
+        if (!_closedIn)
+            _endp.close();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _parser.isBufferEmpty() && _outbound.isBufferEmpty();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void onIdleExpired(long idleForMs)
+    {
+        closeOut(WebSocketConnectionD08.CLOSE_NORMAL,"Idle for "+idleForMs+"ms > "+_endp.getMaxIdleTime()+"ms");
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        final boolean closed;
+        synchronized (this)
+        {
+            closed=_closeCode==0;
+            if (closed)
+                _closeCode=WebSocketConnectionD08.CLOSE_NOCLOSE;
+        }
+        if (closed)
+            _webSocket.onClose(WebSocketConnectionD08.CLOSE_NOCLOSE,"closed");
+    }
+
+    /* ------------------------------------------------------------ */
+    public void closeIn(int code,String message)
+    {
+        LOG.debug("ClosedIn {} {} {}",this,code,message);
+
+        final boolean closed_out;
+        final boolean tell_app;
+        synchronized (this)
+        {
+            closed_out=_closedOut;
+            _closedIn=true;
+            tell_app=_closeCode==0;
+            if (tell_app)
+            {
+                _closeCode=code;
+                _closeMessage=message;
+            }
+        }
+
+        try
+        {
+            if (!closed_out)
+                closeOut(code,message);
+        }
+        finally
+        {
+            if  (tell_app)
+                _webSocket.onClose(code,message);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void closeOut(int code,String message)
+    {
+        LOG.debug("ClosedOut {} {} {}",this,code,message);
+
+        final boolean closed_out;
+        final boolean tell_app;
+        synchronized (this)
+        {
+            closed_out=_closedOut;
+            _closedOut=true;
+            tell_app=_closeCode==0;
+            if (tell_app)
+            {
+                _closeCode=code;
+                _closeMessage=message;
+            }
+        }
+
+        try
+        {                    
+            if (tell_app)
+                _webSocket.onClose(code,message);
+        }
+        finally
+        {
+            try
+            {
+                if (!closed_out)
+                {
+                    if (code<=0)
+                        code=WebSocketConnectionD08.CLOSE_NORMAL;
+                    byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1);
+                    bytes[0]=(byte)(code/0x100);
+                    bytes[1]=(byte)(code%0x100);
+                    _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_CLOSE,bytes,0,bytes.length);
+                }
+                _outbound.flush();
+
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+    }
+
+    public void shutdown()
+    {
+        final WebSocket.Connection connection = _connection;
+        if (connection != null)
+            connection.close(CLOSE_SHUTDOWN, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fillBuffersFrom(Buffer buffer)
+    {
+        _parser.fill(buffer);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void checkWriteable()
+    {
+        if (!_outbound.isBufferEmpty() && _endp instanceof AsyncEndPoint)
+        {
+            ((AsyncEndPoint)_endp).scheduleWrite();
+        }
+    }
+
+    protected void onFrameHandshake()
+    {
+        if (_onFrame != null)
+        {
+            _onFrame.onHandshake(_connection);
+        }
+    }
+
+    protected void onWebSocketOpen()
+    {
+        _webSocket.onOpen(_connection);
+    }
+
+    /* ------------------------------------------------------------ */
+    private class WSFrameConnection implements WebSocket.FrameConnection
+    {
+        private volatile boolean _disconnecting;
+
+        /* ------------------------------------------------------------ */
+        public void sendMessage(String content) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            byte[] data = content.getBytes(StringUtil.__UTF8);
+            _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_TEXT,data,0,data.length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendMessage(byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionD08.OP_BINARY,content,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame(flags,opcode,content,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendControl(byte ctrl, byte[] data, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame((byte)FLAG_FIN,ctrl,data,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isMessageComplete(byte flags)
+        {
+            return isLastFrame(flags);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isOpen()
+        {
+            return _endp!=null&&_endp.isOpen();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close(int code, String message)
+        {
+            if (_disconnecting)
+                return;
+            _disconnecting=true;
+            WebSocketConnectionD08.this.closeOut(code,message);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxIdleTime(int ms)
+        {
+            try
+            {
+                _endp.setMaxIdleTime(ms);
+            }
+            catch(IOException e)
+            {
+                LOG.warn(e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxTextMessageSize(int size)
+        {
+            _maxTextMessageSize=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxBinaryMessageSize(int size)
+        {
+            _maxBinaryMessageSize=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxIdleTime()
+        {
+            return _endp.getMaxIdleTime();
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxTextMessageSize()
+        {
+            return _maxTextMessageSize;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxBinaryMessageSize()
+        {
+            return _maxBinaryMessageSize;
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getProtocol()
+        {
+            return _protocol;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte binaryOpcode()
+        {
+            return OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte textOpcode()
+        {
+            return OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte continuationOpcode()
+        {
+            return OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte finMask()
+        {
+            return FLAG_FIN;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isControl(byte opcode)
+        {
+            return isControlFrame(opcode);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isText(byte opcode)
+        {
+            return opcode==OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isBinary(byte opcode)
+        {
+            return opcode==OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isContinuation(byte opcode)
+        {
+            return opcode==OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isClose(byte opcode)
+        {
+            return opcode==OP_CLOSE;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPing(byte opcode)
+        {
+            return opcode==OP_PING;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPong(byte opcode)
+        {
+            return opcode==OP_PONG;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void disconnect()
+        {
+            close(CLOSE_NORMAL,null);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close()
+        {
+            close(CLOSE_NORMAL,null);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setAllowFrameFragmentation(boolean allowFragmentation)
+        {
+            _parser.setFakeFragments(allowFragmentation);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isAllowFrameFragmentation()
+        {
+            return _parser.isFakeFragments();
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return String.format("%s[D08]@%x l(%s:%d)<->r(%s:%d)",
+                    getClass().getSimpleName(),
+                    hashCode(),
+                    _endp.getLocalAddr(),
+                    _endp.getLocalPort(),
+                    _endp.getRemoteAddr(),
+                    _endp.getRemotePort());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class WSFrameHandler implements WebSocketParser.FrameHandler
+    {
+        private final Utf8StringBuilder _utf8 = new Utf8StringBuilder();
+        private ByteArrayBuffer _aggregate;
+        private byte _opcode=-1;
+
+        public void onFrame(final byte flags, final byte opcode, final Buffer buffer)
+        {
+            boolean lastFrame = isLastFrame(flags);
+
+            synchronized(WebSocketConnectionD08.this)
+            {
+                // Ignore incoming after a close
+                if (_closedIn)
+                    return;
+            }
+            try
+            {
+                byte[] array=buffer.array();
+
+                // Deliver frame if websocket is a FrameWebSocket
+                if (_onFrame!=null)
+                {
+                    if (_onFrame.onFrame(flags,opcode,array,buffer.getIndex(),buffer.length()))
+                        return;
+                }
+
+                if (_onControl!=null && isControlFrame(opcode))
+                {
+                    if (_onControl.onControl(opcode,array,buffer.getIndex(),buffer.length()))
+                        return;
+                }
+
+                switch(opcode)
+                {
+                    case WebSocketConnectionD08.OP_CONTINUATION:
+                    {
+                        // If text, append to the message buffer
+                        if (_onTextMessage!=null && _opcode==WebSocketConnectionD08.OP_TEXT)
+                        {
+                            if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                            {
+                                // If this is the last fragment, deliver the text buffer
+                                if (lastFrame)
+                                {
+                                    _opcode=-1;
+                                    String msg =_utf8.toString();
+                                    _utf8.reset();
+                                    _onTextMessage.onMessage(msg);
+                                }
+                            }
+                            else
+                                textMessageTooLarge();
+                        }
+
+                        if (_opcode>=0 && _connection.getMaxBinaryMessageSize()>=0)
+                        {
+                            if (checkBinaryMessageSize(_aggregate.length(),buffer.length()))
+                            {
+                                _aggregate.put(buffer);
+
+                                // If this is the last fragment, deliver
+                                if (lastFrame && _onBinaryMessage!=null)
+                                {
+                                    try
+                                    {
+                                        _onBinaryMessage.onMessage(_aggregate.array(),_aggregate.getIndex(),_aggregate.length());
+                                    }
+                                    finally
+                                    {
+                                        _opcode=-1;
+                                        _aggregate.clear();
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case WebSocketConnectionD08.OP_PING:
+                    {
+                        LOG.debug("PING {}",this);
+                        if (!_closedOut)
+                            _connection.sendControl(WebSocketConnectionD08.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
+                        break;
+                    }
+
+                    case WebSocketConnectionD08.OP_PONG:
+                    {
+                        LOG.debug("PONG {}",this);
+                        break;
+                    }
+
+                    case WebSocketConnectionD08.OP_CLOSE:
+                    {
+                        int code=WebSocketConnectionD08.CLOSE_NOCODE;
+                        String message=null;
+                        if (buffer.length()>=2)
+                        {
+                            code=buffer.array()[buffer.getIndex()]*0x100+buffer.array()[buffer.getIndex()+1];
+                            if (buffer.length()>2)
+                                message=new String(buffer.array(),buffer.getIndex()+2,buffer.length()-2,StringUtil.__UTF8);
+                        }
+                        closeIn(code,message);
+                        break;
+                    }
+
+                    case WebSocketConnectionD08.OP_TEXT:
+                    {
+                        if(_onTextMessage!=null)
+                        {
+                            if (_connection.getMaxTextMessageSize()<=0)
+                            {
+                                // No size limit, so handle only final frames
+                                if (lastFrame)
+                                    _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8));
+                                else
+                                {
+                                    LOG.warn("Frame discarded. Text aggregation disabled for {}",_endp);
+                                    _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Text frame aggregation disabled");
+                                }
+                            }
+                            // append bytes to message buffer (if they fit)
+                            else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                            {
+                                if (lastFrame)
+                                {
+                                    String msg =_utf8.toString();
+                                    _utf8.reset();
+                                    _onTextMessage.onMessage(msg);
+                                }
+                                else
+                                {
+                                    _opcode=WebSocketConnectionD08.OP_TEXT;
+                                }
+                            }
+                            else
+                                textMessageTooLarge();
+                        }
+                        break;
+                    }
+
+                    default:
+                    {
+                        if (_onBinaryMessage!=null && checkBinaryMessageSize(0,buffer.length()))
+                        {
+                            if (lastFrame)
+                            {
+                                _onBinaryMessage.onMessage(array,buffer.getIndex(),buffer.length());
+                            }
+                            else if (_connection.getMaxBinaryMessageSize()>=0)
+                            {
+                                _opcode=opcode;
+                                if (_aggregate==null)
+                                    _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
+                                _aggregate.put(buffer);
+                            }
+                            else
+                            {
+                                LOG.warn("Frame discarded. Binary aggregation disabed for {}",_endp);
+                                _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Binary frame aggregation disabled");
+                            }
+                        }
+                    }
+                }
+            }
+            catch(Throwable e)
+            {
+                LOG.warn("{} for {}",e,_endp, e);
+                LOG.debug(e);
+                errorClose(WebSocketConnectionRFC6455.CLOSE_SERVER_ERROR,"Internal Server Error: "+e);
+            }
+        }
+
+        private void errorClose(int code, String message)
+        {
+            _connection.close(code,message);
+
+            // Brutally drop the connection
+            try
+            {
+                _endp.close();
+            }
+            catch (IOException e)
+            {
+                LOG.warn(e.toString());
+                LOG.debug(e);
+            }
+        }
+
+        private boolean checkBinaryMessageSize(int bufferLen, int length)
+        {
+            int max = _connection.getMaxBinaryMessageSize();
+            if (max>0 && (bufferLen+length)>max)
+            {
+                LOG.warn("Binary message too large > {}B for {}",_connection.getMaxBinaryMessageSize(),_endp);
+                _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Message size > "+_connection.getMaxBinaryMessageSize());
+                _opcode=-1;
+                if (_aggregate!=null)
+                    _aggregate.clear();
+                return false;
+            }
+            return true;
+        }
+
+        private void textMessageTooLarge()
+        {
+            LOG.warn("Text message too large > {} chars for {}",_connection.getMaxTextMessageSize(),_endp);
+            _connection.close(WebSocketConnectionD08.CLOSE_BADDATA,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
+
+            _opcode=-1;
+            _utf8.reset();
+        }
+
+        public void close(int code,String message)
+        {
+            if (code!=CLOSE_NORMAL)
+                LOG.warn("Close: "+code+" "+message);
+            _connection.close(code,message);
+        }
+
+        @Override
+        public String toString()
+        {
+            return WebSocketConnectionD08.this.toString()+"FH";
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String hashKey(String key)
+    {
+        try
+        {
+            MessageDigest md = MessageDigest.getInstance("SHA1");
+            md.update(key.getBytes("UTF-8"));
+            md.update(MAGIC);
+            return new String(B64Code.encode(md.digest()));
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return String.format("WS/D%d p=%s g=%s", _draft, _parser, _generator);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java
new file mode 100644
index 0000000..9dd2773
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java
@@ -0,0 +1,974 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.AsyncEndPoint;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.ByteArrayBuffer;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.B64Code;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.Utf8Appendable;
+import org.eclipse.jetty.util.Utf8StringBuilder;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage;
+import org.eclipse.jetty.websocket.WebSocket.OnControl;
+import org.eclipse.jetty.websocket.WebSocket.OnFrame;
+import org.eclipse.jetty.websocket.WebSocket.OnTextMessage;
+
+
+/* ------------------------------------------------------------ */
+/**
+ * <pre>
+ *    0                   1                   2                   3
+ *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *   +-+-+-+-+-------+-+-------------+-------------------------------+
+ *   |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
+ *   |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
+ *   |N|V|V|V|       |S|             |   (if payload len==126/127)   |
+ *   | |1|2|3|       |K|             |                               |
+ *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ *   |     Extended payload length continued, if payload len == 127  |
+ *   + - - - - - - - - - - - - - - - +-------------------------------+
+ *   |                               |Masking-key, if MASK set to 1  |
+ *   +-------------------------------+-------------------------------+
+ *   | Masking-key (continued)       |          Payload Data         |
+ *   +-------------------------------- - - - - - - - - - - - - - - - +
+ *   :                     Payload Data continued ...                :
+ *   + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ *   |                     Payload Data continued ...                |
+ *   +---------------------------------------------------------------+
+ * </pre>
+ */
+public class WebSocketConnectionRFC6455 extends AbstractConnection implements WebSocketConnection
+{
+    private static final Logger LOG = Log.getLogger(WebSocketConnectionRFC6455.class);
+
+    final static byte OP_CONTINUATION = 0x00;
+    final static byte OP_TEXT = 0x01;
+    final static byte OP_BINARY = 0x02;
+    final static byte OP_EXT_DATA = 0x03;
+
+    final static byte OP_CONTROL = 0x08;
+    final static byte OP_CLOSE = 0x08;
+    final static byte OP_PING = 0x09;
+    final static byte OP_PONG = 0x0A;
+    final static byte OP_EXT_CTRL = 0x0B;
+
+    final static int CLOSE_NORMAL=1000;
+    final static int CLOSE_SHUTDOWN=1001;
+    final static int CLOSE_PROTOCOL=1002;
+    final static int CLOSE_BAD_DATA=1003;
+    final static int CLOSE_UNDEFINED=1004;
+    final static int CLOSE_NO_CODE=1005;
+    final static int CLOSE_NO_CLOSE=1006;
+    final static int CLOSE_BAD_PAYLOAD=1007;
+    final static int CLOSE_POLICY_VIOLATION=1008;
+    final static int CLOSE_MESSAGE_TOO_LARGE=1009;
+    final static int CLOSE_REQUIRED_EXTENSION=1010;
+    final static int CLOSE_SERVER_ERROR=1011;
+    final static int CLOSE_FAILED_TLS_HANDSHAKE=1015;
+
+    final static int FLAG_FIN=0x8;
+
+    // Per RFC 6455, section 1.3 - Opening Handshake - this version is "13"
+    final static int VERSION=13;
+
+    static boolean isLastFrame(byte flags)
+    {
+        return (flags&FLAG_FIN)!=0;
+    }
+
+    static boolean isControlFrame(byte opcode)
+    {
+        return (opcode&OP_CONTROL)!=0;
+    }
+
+    private final static byte[] MAGIC;
+    private final List<Extension> _extensions;
+    private final WebSocketParserRFC6455 _parser;
+    private final WebSocketGeneratorRFC6455 _generator;
+    private final WebSocketGenerator _outbound;
+    private final WebSocket _webSocket;
+    private final OnFrame _onFrame;
+    private final OnBinaryMessage _onBinaryMessage;
+    private final OnTextMessage _onTextMessage;
+    private final OnControl _onControl;
+    private final String _protocol;
+    private final int _draft;
+    private final ClassLoader _context;
+    private volatile int _closeCode;
+    private volatile String _closeMessage;
+    private volatile boolean _closedIn;
+    private volatile boolean _closedOut;
+    private int _maxTextMessageSize=-1;
+    private int _maxBinaryMessageSize=-1;
+
+    static
+    {
+        try
+        {
+            MAGIC="258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StringUtil.__ISO_8859_1);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private final WebSocket.FrameConnection _connection = new WSFrameConnection();
+
+
+    /* ------------------------------------------------------------ */
+    public WebSocketConnectionRFC6455(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft)
+        throws IOException
+    {
+        this(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol,extensions,draft,null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebSocketConnectionRFC6455(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft, MaskGen maskgen)
+        throws IOException
+    {
+        super(endpoint,timestamp);
+
+        _context=Thread.currentThread().getContextClassLoader();
+
+        _draft=draft;
+        _endp.setMaxIdleTime(maxIdleTime);
+
+        _webSocket = websocket;
+        _onFrame=_webSocket instanceof OnFrame ? (OnFrame)_webSocket : null;
+        _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null;
+        _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null;
+        _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null;
+        _generator = new WebSocketGeneratorRFC6455(buffers, _endp,maskgen);
+
+        _extensions=extensions;
+        WebSocketParser.FrameHandler frameHandler = new WSFrameHandler();
+        if (_extensions!=null)
+        {
+            int e=0;
+            for (Extension extension : _extensions)
+            {
+                extension.bind(
+                        _connection,
+                        e==extensions.size()-1? frameHandler :extensions.get(e+1),
+                        e==0?_generator:extensions.get(e-1));
+                e++;
+            }
+        }
+
+        _outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1);
+        WebSocketParser.FrameHandler inbound = (_extensions == null || _extensions.size() == 0) ? frameHandler : extensions.get(0);
+
+        _parser = new WebSocketParserRFC6455(buffers, endpoint, inbound,maskgen==null);
+
+        _protocol=protocol;
+
+    }
+
+    /* ------------------------------------------------------------ */
+    public WebSocket.Connection getConnection()
+    {
+        return _connection;
+    }
+
+    /* ------------------------------------------------------------ */
+    public List<Extension> getExtensions()
+    {
+        if (_extensions==null)
+            return Collections.emptyList();
+
+        return _extensions;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Connection handle() throws IOException
+    {
+        Thread current = Thread.currentThread();
+        ClassLoader oldcontext = current.getContextClassLoader();
+        current.setContextClassLoader(_context);
+        try
+        {
+            // handle the framing protocol
+            boolean progress=true;
+
+            while (progress)
+            {
+                int flushed=_generator.flushBuffer();
+                int filled=_parser.parseNext();
+
+                progress = flushed>0 || filled>0;
+                _endp.flush();
+
+                if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed())
+                    progress=true;
+            }
+        }
+        catch(IOException e)
+        {
+            try
+            {
+                if (_endp.isOpen())
+                    _endp.close();
+            }
+            catch(IOException e2)
+            {
+                LOG.ignore(e2);
+            }
+            throw e;
+        }
+        finally
+        {
+            current.setContextClassLoader(oldcontext);
+            _parser.returnBuffer();
+            _generator.returnBuffer();
+            if (_endp.isOpen())
+            {
+                if (_closedIn && _closedOut && _outbound.isBufferEmpty())
+                    _endp.close();
+                else if (_endp.isInputShutdown() && !_closedIn)
+                    closeIn(CLOSE_NO_CLOSE,null);
+                else
+                    checkWriteable();
+            }
+        }
+        return this;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onInputShutdown() throws IOException
+    {
+        if (!_closedIn)
+            _endp.close();
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isIdle()
+    {
+        return _parser.isBufferEmpty() && _outbound.isBufferEmpty();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void onIdleExpired(long idleForMs)
+    {
+        closeOut(WebSocketConnectionRFC6455.CLOSE_NORMAL,"Idle for "+idleForMs+"ms > "+_endp.getMaxIdleTime()+"ms");
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isSuspended()
+    {
+        return false;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void onClose()
+    {
+        final boolean closed;
+        synchronized (this)
+        {
+            closed=_closeCode==0;
+            if (closed)
+                _closeCode=WebSocketConnectionRFC6455.CLOSE_NO_CLOSE;
+        }
+        if (closed)
+            _webSocket.onClose(WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"closed");
+    }
+
+    /* ------------------------------------------------------------ */
+    public void closeIn(int code,String message)
+    {
+        LOG.debug("ClosedIn {} {} {}",this,code,message);
+
+        final boolean closed_out;
+        final boolean tell_app;
+        synchronized (this)
+        {
+            closed_out=_closedOut;
+            _closedIn=true;
+            tell_app=_closeCode==0;
+            if (tell_app)
+            {
+                _closeCode=code;
+                _closeMessage=message;
+            }
+        }
+
+        try
+        {
+            if (!closed_out)
+                closeOut(code,message);
+        }
+        finally
+        {
+            if  (tell_app)
+                _webSocket.onClose(code,message);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void closeOut(int code,String message)
+    {
+        LOG.debug("ClosedOut {} {} {}",this,code,message);
+
+        final boolean closed_out;
+        final boolean tell_app;
+        synchronized (this)
+        {
+            closed_out=_closedOut;
+            _closedOut=true;
+            tell_app=_closeCode==0;
+            if (tell_app)
+            {
+                _closeCode=code;
+                _closeMessage=message;
+            }
+        }
+
+        try
+        {                    
+            if (tell_app)
+                _webSocket.onClose(code,message);
+        }
+        finally
+        {
+            try
+            {
+                if (!closed_out)
+                {
+                    // Close code 1005/1006/1015 are never to be sent as a status over
+                    // a Close control frame. Code<-1 also means no node.
+
+                    if (code < 0 || (code == WebSocketConnectionRFC6455.CLOSE_NO_CODE) || (code == WebSocketConnectionRFC6455.CLOSE_NO_CLOSE)
+                            || (code == WebSocketConnectionRFC6455.CLOSE_FAILED_TLS_HANDSHAKE))
+                    {
+                        code = -1;
+                    }
+                    else if (code == 0)
+                    {
+                        code = WebSocketConnectionRFC6455.CLOSE_NORMAL;
+                    }
+
+                    byte[] bytes = ("xx"+(message==null?"":message)).getBytes(StringUtil.__ISO_8859_1);
+                    bytes[0]=(byte)(code/0x100);
+                    bytes[1]=(byte)(code%0x100);
+                    _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionRFC6455.OP_CLOSE,bytes,0,code>0?bytes.length:0);
+                    _outbound.flush();
+                }
+            }
+            catch(IOException e)
+            {
+                LOG.ignore(e);
+            }
+        }
+    }
+
+    public void shutdown()
+    {
+        final WebSocket.Connection connection = _connection;
+        if (connection != null)
+            connection.close(CLOSE_SHUTDOWN, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fillBuffersFrom(Buffer buffer)
+    {
+        _parser.fill(buffer);
+    }
+
+    /* ------------------------------------------------------------ */
+    private void checkWriteable()
+    {
+        if (!_outbound.isBufferEmpty() && _endp instanceof AsyncEndPoint)
+        {
+            ((AsyncEndPoint)_endp).scheduleWrite();
+        }
+    }
+
+    protected void onFrameHandshake()
+    {
+        if (_onFrame != null)
+        {
+            _onFrame.onHandshake(_connection);
+        }
+    }
+
+    protected void onWebSocketOpen()
+    {
+        _webSocket.onOpen(_connection);
+    }
+
+    /* ------------------------------------------------------------ */
+    private class WSFrameConnection implements WebSocket.FrameConnection
+    {
+        private volatile boolean _disconnecting;
+
+        /* ------------------------------------------------------------ */
+        public void sendMessage(String content) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            byte[] data = content.getBytes(StringUtil.__UTF8);
+            _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionRFC6455.OP_TEXT,data,0,data.length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendMessage(byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionRFC6455.OP_BINARY,content,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException
+        {
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame(flags,opcode,content,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void sendControl(byte ctrl, byte[] data, int offset, int length) throws IOException
+        {
+            // TODO: section 5.5 states that control frames MUST never be length > 125 bytes and MUST NOT be fragmented
+            if (_closedOut)
+                throw new IOException("closedOut "+_closeCode+":"+_closeMessage);
+            _outbound.addFrame((byte)FLAG_FIN,ctrl,data,offset,length);
+            checkWriteable();
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isMessageComplete(byte flags)
+        {
+            return isLastFrame(flags);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isOpen()
+        {
+            return _endp!=null&&_endp.isOpen();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close(int code, String message)
+        {
+            if (_disconnecting)
+                return;
+            _disconnecting=true;
+            WebSocketConnectionRFC6455.this.closeOut(code,message);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxIdleTime(int ms)
+        {
+            try
+            {
+                _endp.setMaxIdleTime(ms);
+            }
+            catch(IOException e)
+            {
+                LOG.warn(e);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxTextMessageSize(int size)
+        {
+            _maxTextMessageSize=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setMaxBinaryMessageSize(int size)
+        {
+            _maxBinaryMessageSize=size;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxIdleTime()
+        {
+            return _endp.getMaxIdleTime();
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxTextMessageSize()
+        {
+            return _maxTextMessageSize;
+        }
+
+        /* ------------------------------------------------------------ */
+        public int getMaxBinaryMessageSize()
+        {
+            return _maxBinaryMessageSize;
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getProtocol()
+        {
+            return _protocol;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte binaryOpcode()
+        {
+            return OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte textOpcode()
+        {
+            return OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte continuationOpcode()
+        {
+            return OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public byte finMask()
+        {
+            return FLAG_FIN;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isControl(byte opcode)
+        {
+            return isControlFrame(opcode);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isText(byte opcode)
+        {
+            return opcode==OP_TEXT;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isBinary(byte opcode)
+        {
+            return opcode==OP_BINARY;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isContinuation(byte opcode)
+        {
+            return opcode==OP_CONTINUATION;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isClose(byte opcode)
+        {
+            return opcode==OP_CLOSE;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPing(byte opcode)
+        {
+            return opcode==OP_PING;
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isPong(byte opcode)
+        {
+            return opcode==OP_PONG;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void disconnect()
+        {
+            close(CLOSE_NORMAL,null);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void close()
+        {
+            close(CLOSE_NORMAL,null);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void setAllowFrameFragmentation(boolean allowFragmentation)
+        {
+            _parser.setFakeFragments(allowFragmentation);
+        }
+
+        /* ------------------------------------------------------------ */
+        public boolean isAllowFrameFragmentation()
+        {
+            return _parser.isFakeFragments();
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public String toString()
+        {
+            return String.format("%s@%x l(%s:%d)<->r(%s:%d)",
+                    getClass().getSimpleName(),
+                    hashCode(),
+                    _endp.getLocalAddr(),
+                    _endp.getLocalPort(),
+                    _endp.getRemoteAddr(),
+                    _endp.getRemotePort());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class WSFrameHandler implements WebSocketParser.FrameHandler
+    {
+        private static final int MAX_CONTROL_FRAME_PAYLOAD = 125;
+        private final Utf8StringBuilder _utf8 = new Utf8StringBuilder(512); // TODO configure initial capacity
+        private ByteArrayBuffer _aggregate;
+        private byte _opcode=-1;
+
+        public void onFrame(final byte flags, final byte opcode, final Buffer buffer)
+        {
+            boolean lastFrame = isLastFrame(flags);
+
+            synchronized(WebSocketConnectionRFC6455.this)
+            {
+                // Ignore incoming after a close
+                if (_closedIn)
+                    return;
+            }
+            try
+            {
+                byte[] array=buffer.array();
+
+                if (isControlFrame(opcode) && buffer.length()>MAX_CONTROL_FRAME_PAYLOAD)
+                {
+                    errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Control frame too large: " + buffer.length() + " > " + MAX_CONTROL_FRAME_PAYLOAD);
+                    return;
+                }
+
+                // TODO: check extensions for RSV bit(s) meanings
+                if ((flags&0x7)!=0)
+                {
+                    errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"RSV bits set 0x"+Integer.toHexString(flags));
+                    return;
+                }
+
+                // Ignore all frames after error close
+                if (_closeCode!=0 && _closeCode!=CLOSE_NORMAL && opcode!=OP_CLOSE)
+                {
+                    return;
+                }
+
+                // Deliver frame if websocket is a FrameWebSocket
+                if (_onFrame!=null)
+                {
+                    if (_onFrame.onFrame(flags,opcode,array,buffer.getIndex(),buffer.length()))
+                        return;
+                }
+
+                if (_onControl!=null && isControlFrame(opcode))
+                {
+                    if (_onControl.onControl(opcode,array,buffer.getIndex(),buffer.length()))
+                        return;
+                }
+
+                switch(opcode)
+                {
+                    case WebSocketConnectionRFC6455.OP_CONTINUATION:
+                    {
+                        if (_opcode==-1)
+                        {
+                            errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Bad Continuation");
+                            return;
+                        }
+
+                        // If text, append to the message buffer
+                        if (_onTextMessage!=null && _opcode==WebSocketConnectionRFC6455.OP_TEXT)
+                        {
+                            if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                            {
+                                // If this is the last fragment, deliver the text buffer
+                                if (lastFrame)
+                                {
+                                    _opcode=-1;
+                                    String msg =_utf8.toString();
+                                    _utf8.reset();
+                                    _onTextMessage.onMessage(msg);
+                                }
+                            }
+                            else
+                                textMessageTooLarge();
+                        }
+
+                        if (_opcode>=0 && _connection.getMaxBinaryMessageSize()>=0)
+                        {
+                            if (_aggregate!=null && checkBinaryMessageSize(_aggregate.length(),buffer.length()))
+                            {
+                                _aggregate.put(buffer);
+
+                                // If this is the last fragment, deliver
+                                if (lastFrame && _onBinaryMessage!=null)
+                                {
+                                    try
+                                    {
+                                        _onBinaryMessage.onMessage(_aggregate.array(),_aggregate.getIndex(),_aggregate.length());
+                                    }
+                                    finally
+                                    {
+                                        _opcode=-1;
+                                        _aggregate.clear();
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case WebSocketConnectionRFC6455.OP_PING:
+                    {
+                        LOG.debug("PING {}",this);
+                        if (!_closedOut)
+                        {
+                            _connection.sendControl(WebSocketConnectionRFC6455.OP_PONG,buffer.array(),buffer.getIndex(),buffer.length());
+                        }
+                        break;
+                    }
+
+                    case WebSocketConnectionRFC6455.OP_PONG:
+                    {
+                        LOG.debug("PONG {}",this);
+                        break;
+                    }
+
+                    case WebSocketConnectionRFC6455.OP_CLOSE:
+                    {
+                        int code=WebSocketConnectionRFC6455.CLOSE_NO_CODE;
+                        String message=null;
+                        if (buffer.length()>=2)
+                        {
+                            code=(0xff&buffer.array()[buffer.getIndex()])*0x100+(0xff&buffer.array()[buffer.getIndex()+1]);
+
+                            // Validate close status codes.
+                            if (code < WebSocketConnectionRFC6455.CLOSE_NORMAL ||
+                                code == WebSocketConnectionRFC6455.CLOSE_UNDEFINED ||
+                                code == WebSocketConnectionRFC6455.CLOSE_NO_CLOSE ||
+                                code == WebSocketConnectionRFC6455.CLOSE_NO_CODE ||
+                                ( code > 1011 && code <= 2999 ) ||
+                                code >= 5000 )
+                            {
+                                errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Invalid close code " + code);
+                                return;
+                            }
+
+                            if (buffer.length()>2)
+                            {
+                                if(_utf8.append(buffer.array(),buffer.getIndex()+2,buffer.length()-2,_connection.getMaxTextMessageSize()))
+                                {
+                                    message = _utf8.toString();
+                                    _utf8.reset();
+                                }
+                            }
+                        }
+                        else if(buffer.length() == 1)
+                        {
+                            // Invalid length. use status code 1002 (Protocol error)
+                            errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Invalid payload length of 1");
+                            return;
+                        }
+                        closeIn(code,message);
+                        break;
+                    }
+
+                    case WebSocketConnectionRFC6455.OP_TEXT:
+                    {
+                        if (_opcode!=-1)
+                        {
+                            errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Expected Continuation"+Integer.toHexString(opcode));
+                            return;
+                        }
+
+                        if(_onTextMessage!=null)
+                        {
+                            if (_connection.getMaxTextMessageSize()<=0)
+                            {
+                                // No size limit, so handle only final frames
+                                if (lastFrame)
+                                    _onTextMessage.onMessage(buffer.toString(StringUtil.__UTF8));
+                                else
+                                {
+                                    LOG.warn("Frame discarded. Text aggregation disabled for {}",_endp);
+                                    errorClose(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"Text frame aggregation disabled");
+                                }
+                            }
+                            // append bytes to message buffer (if they fit)
+                            else if (_utf8.append(buffer.array(),buffer.getIndex(),buffer.length(),_connection.getMaxTextMessageSize()))
+                            {
+                                if (lastFrame)
+                                {
+                                    String msg =_utf8.toString();
+                                    _utf8.reset();
+                                    _onTextMessage.onMessage(msg);
+                                }
+                                else
+                                {
+                                    _opcode=WebSocketConnectionRFC6455.OP_TEXT;
+                                }
+                            }
+                            else
+                                textMessageTooLarge();
+                        }
+                        break;
+                    }
+
+                    case WebSocketConnectionRFC6455.OP_BINARY:
+                    {
+                        if (_opcode!=-1)
+                        {
+                            errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Expected Continuation"+Integer.toHexString(opcode));
+                            return;
+                        }
+
+                        if (_onBinaryMessage!=null && checkBinaryMessageSize(0,buffer.length()))
+                        {
+                            if (lastFrame)
+                            {
+                                _onBinaryMessage.onMessage(array,buffer.getIndex(),buffer.length());
+                            }
+                            else if (_connection.getMaxBinaryMessageSize()>=0)
+                            {
+                                _opcode=opcode;
+                                // TODO use a growing buffer rather than a fixed one.
+                                if (_aggregate==null)
+                                    _aggregate=new ByteArrayBuffer(_connection.getMaxBinaryMessageSize());
+                                _aggregate.put(buffer);
+                            }
+                            else
+                            {
+                                LOG.warn("Frame discarded. Binary aggregation disabed for {}",_endp);
+                                errorClose(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"Binary frame aggregation disabled");
+                            }
+                        }
+                        break;
+                    }
+
+                    default:
+                        errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Bad opcode 0x"+Integer.toHexString(opcode));
+                        break;
+                }
+            }
+            catch(Utf8Appendable.NotUtf8Exception notUtf8)
+            {
+                LOG.warn("NOTUTF8 - {} for {}",notUtf8,_endp, notUtf8);
+                LOG.debug(notUtf8);
+                errorClose(WebSocketConnectionRFC6455.CLOSE_BAD_PAYLOAD,"Invalid UTF-8");
+            }
+            catch(Throwable e)
+            {
+                LOG.warn("{} for {}",e,_endp, e);
+                LOG.debug(e);
+                errorClose(WebSocketConnectionRFC6455.CLOSE_SERVER_ERROR,"Internal Server Error: "+e);
+            }
+        }
+
+        private void errorClose(int code, String message)
+        {
+            _connection.close(code,message);
+
+            // Brutally drop the connection
+            try
+            {
+                _endp.close();
+            }
+            catch (IOException e)
+            {
+                LOG.warn(e.toString());
+                LOG.debug(e);
+            }
+        }
+
+        private boolean checkBinaryMessageSize(int bufferLen, int length)
+        {
+            int max = _connection.getMaxBinaryMessageSize();
+            if (max>0 && (bufferLen+length)>max)
+            {
+                LOG.warn("Binary message too large > {}B for {}",_connection.getMaxBinaryMessageSize(),_endp);
+                _connection.close(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize());
+                _opcode=-1;
+                if (_aggregate!=null)
+                    _aggregate.clear();
+                return false;
+            }
+            return true;
+        }
+
+        private void textMessageTooLarge()
+        {
+            LOG.warn("Text message too large > {} chars for {}",_connection.getMaxTextMessageSize(),_endp);
+            _connection.close(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
+
+            _opcode=-1;
+            _utf8.reset();
+        }
+
+        public void close(int code,String message)
+        {
+            if (code!=CLOSE_NORMAL)
+                LOG.warn("Close: "+code+" "+message);
+            _connection.close(code,message);
+        }
+
+        @Override
+        public String toString()
+        {
+            return WebSocketConnectionRFC6455.this.toString()+"FH";
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public static String hashKey(String key)
+    {
+        try
+        {
+            MessageDigest md = MessageDigest.getInstance("SHA1");
+            md.update(key.getBytes("UTF-8"));
+            md.update(MAGIC);
+            return new String(B64Code.encode(md.digest()));
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return String.format("%s p=%s g=%s", getClass().getSimpleName(), _parser, _generator);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketFactory.java b/src/java/org/eclipse/jetty/websocket/WebSocketFactory.java
new file mode 100644
index 0000000..04ab4f3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketFactory.java
@@ -0,0 +1,465 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpException;
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.io.ConnectedEndPoint;
+import org.eclipse.jetty.server.AbstractHttpConnection;
+import org.eclipse.jetty.server.BlockingHttpConnection;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Factory to create WebSocket connections
+ */
+public class WebSocketFactory extends AbstractLifeCycle
+{
+    private static final Logger LOG = Log.getLogger(WebSocketFactory.class);
+    private final Queue<WebSocketServletConnection> connections = new ConcurrentLinkedQueue<WebSocketServletConnection>();
+
+    public interface Acceptor
+    {
+        /* ------------------------------------------------------------ */
+        /**
+         * <p>Factory method that applications needs to implement to return a
+         * {@link WebSocket} object.</p>
+         * @param request the incoming HTTP upgrade request
+         * @param protocol the websocket sub protocol
+         * @return a new {@link WebSocket} object that will handle websocket events.
+         */
+        WebSocket doWebSocketConnect(HttpServletRequest request, String protocol);
+
+        /* ------------------------------------------------------------ */
+        /**
+         * <p>Checks the origin of an incoming WebSocket handshake request.</p>
+         * @param request the incoming HTTP upgrade request
+         * @param origin the origin URI
+         * @return boolean to indicate that the origin is acceptable.
+         */
+        boolean checkOrigin(HttpServletRequest request, String origin);
+    }
+
+    private final Map<String,Class<? extends Extension>> _extensionClasses = new HashMap<String, Class<? extends Extension>>();
+    {
+        _extensionClasses.put("identity",IdentityExtension.class);
+        _extensionClasses.put("fragment",FragmentExtension.class);
+        _extensionClasses.put("x-deflate-frame",DeflateFrameExtension.class);
+    }
+
+    private final Acceptor _acceptor;
+    private WebSocketBuffers _buffers;
+    private int _maxIdleTime = 300000;
+    private int _maxTextMessageSize = 16 * 1024;
+    private int _maxBinaryMessageSize = -1;
+    private int _minVersion;
+
+    public WebSocketFactory(Acceptor acceptor)
+    {
+        this(acceptor, 64 * 1024, WebSocketConnectionRFC6455.VERSION);
+    }
+
+    public WebSocketFactory(Acceptor acceptor, int bufferSize)
+    {
+        this(acceptor, bufferSize, WebSocketConnectionRFC6455.VERSION);
+    }
+
+    public WebSocketFactory(Acceptor acceptor, int bufferSize, int minVersion)
+    {
+        _buffers = new WebSocketBuffers(bufferSize);
+        _acceptor = acceptor;
+        _minVersion=WebSocketConnectionRFC6455.VERSION;
+    }
+
+    public int getMinVersion()
+    {
+        return _minVersion;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param minVersion The minimum support version (default RCF6455.VERSION == 13 )
+     */
+    public void setMinVersion(int minVersion)
+    {
+        _minVersion = minVersion;
+    }
+
+    /**
+     * @return A modifiable map of extension name to extension class
+     */
+    public Map<String,Class<? extends Extension>> getExtensionClassesMap()
+    {
+        return _extensionClasses;
+    }
+
+    /**
+     * Get the maxIdleTime.
+     *
+     * @return the maxIdleTime
+     */
+    public long getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /**
+     * Set the maxIdleTime.
+     *
+     * @param maxIdleTime the maxIdleTime to set
+     */
+    public void setMaxIdleTime(int maxIdleTime)
+    {
+        _maxIdleTime = maxIdleTime;
+    }
+
+    /**
+     * Get the bufferSize.
+     *
+     * @return the bufferSize
+     */
+    public int getBufferSize()
+    {
+        return _buffers.getBufferSize();
+    }
+
+    /**
+     * Set the bufferSize.
+     *
+     * @param bufferSize the bufferSize to set
+     */
+    public void setBufferSize(int bufferSize)
+    {
+        if (bufferSize != getBufferSize())
+            _buffers = new WebSocketBuffers(bufferSize);
+    }
+
+    /**
+     * @return The initial maximum text message size (in characters) for a connection
+     */
+    public int getMaxTextMessageSize()
+    {
+        return _maxTextMessageSize;
+    }
+
+    /**
+     * Set the initial maximum text message size for a connection. This can be changed by
+     * the application calling {@link WebSocket.Connection#setMaxTextMessageSize(int)}.
+     * @param maxTextMessageSize The default maximum text message size (in characters) for a connection
+     */
+    public void setMaxTextMessageSize(int maxTextMessageSize)
+    {
+        _maxTextMessageSize = maxTextMessageSize;
+    }
+
+    /**
+     * @return The initial maximum binary message size (in bytes)  for a connection
+     */
+    public int getMaxBinaryMessageSize()
+    {
+        return _maxBinaryMessageSize;
+    }
+
+    /**
+     * Set the initial maximum binary message size for a connection. This can be changed by
+     * the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}.
+     * @param maxBinaryMessageSize The default maximum binary message size (in bytes) for a connection
+     */
+    public void setMaxBinaryMessageSize(int maxBinaryMessageSize)
+    {
+        _maxBinaryMessageSize = maxBinaryMessageSize;
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        closeConnections();
+    }
+
+    /**
+     * Upgrade the request/response to a WebSocket Connection.
+     * <p>This method will not normally return, but will instead throw a
+     * UpgradeConnectionException, to exit HTTP handling and initiate
+     * WebSocket handling of the connection.
+     *
+     * @param request   The request to upgrade
+     * @param response  The response to upgrade
+     * @param websocket The websocket handler implementation to use
+     * @param protocol  The websocket protocol
+     * @throws IOException in case of I/O errors
+     */
+    public void upgrade(HttpServletRequest request, HttpServletResponse response, WebSocket websocket, String protocol)
+            throws IOException
+    {
+        if (!"websocket".equalsIgnoreCase(request.getHeader("Upgrade")))
+            throw new IllegalStateException("!Upgrade:websocket");
+        if (!"HTTP/1.1".equals(request.getProtocol()))
+            throw new IllegalStateException("!HTTP/1.1");
+
+        int draft = request.getIntHeader("Sec-WebSocket-Version");
+        if (draft < 0) {
+            // Old pre-RFC version specifications (header not present in RFC-6455)
+            draft = request.getIntHeader("Sec-WebSocket-Draft");
+        }
+        // Remember requested version for possible error message later
+        int requestedVersion = draft;
+        AbstractHttpConnection http = AbstractHttpConnection.getCurrentConnection();
+        if (http instanceof BlockingHttpConnection)
+            throw new IllegalStateException("Websockets not supported on blocking connectors");
+        ConnectedEndPoint endp = (ConnectedEndPoint)http.getEndPoint();
+
+        List<String> extensions_requested = new ArrayList<String>();
+        @SuppressWarnings("unchecked")
+        Enumeration<String> e = request.getHeaders("Sec-WebSocket-Extensions");
+        while (e.hasMoreElements())
+        {
+            QuotedStringTokenizer tok = new QuotedStringTokenizer(e.nextElement(),",");
+            while (tok.hasMoreTokens())
+            {
+                extensions_requested.add(tok.nextToken());
+            }
+        }
+
+        final WebSocketServletConnection connection;
+        if (draft<_minVersion)
+            draft=Integer.MAX_VALUE;
+        switch (draft)
+        {
+            case -1: // unspecified draft/version (such as early OSX Safari 5.1 and iOS 5.x)
+            case 0: // Old school draft/version
+            {
+                connection = new WebSocketServletConnectionD00(this, websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol);
+                break;
+            }
+            case 1:
+            case 2:
+            case 3:
+            case 4:
+            case 5:
+            case 6:
+            {
+                connection = new WebSocketServletConnectionD06(this, websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol);
+                break;
+            }
+            case 7:
+            case 8:
+            {
+                List<Extension> extensions = initExtensions(extensions_requested, 8 - WebSocketConnectionD08.OP_EXT_DATA, 16 - WebSocketConnectionD08.OP_EXT_CTRL, 3);
+                connection = new WebSocketServletConnectionD08(this, websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol, extensions, draft);
+                break;
+            }
+            case WebSocketConnectionRFC6455.VERSION: // RFC 6455 Version
+            {
+                List<Extension> extensions = initExtensions(extensions_requested, 8 - WebSocketConnectionRFC6455.OP_EXT_DATA, 16 - WebSocketConnectionRFC6455.OP_EXT_CTRL, 3);
+                connection = new WebSocketServletConnectionRFC6455(this, websocket, endp, _buffers, http.getTimeStamp(), _maxIdleTime, protocol, extensions, draft);
+                break;
+            }
+            default:
+            {
+                // Per RFC 6455 - 4.4 - Supporting Multiple Versions of WebSocket Protocol
+                // Using the examples as outlined
+                String versions="13";
+                if (_minVersion<=8)
+                    versions+=", 8";
+                if (_minVersion<=6)
+                    versions+=", 6";
+                if (_minVersion<=0)
+                    versions+=", 0";
+                    
+                response.setHeader("Sec-WebSocket-Version", versions);
+
+                // Make error clear for developer / end-user
+                StringBuilder err = new StringBuilder();
+                err.append("Unsupported websocket client version specification ");
+                if(requestedVersion >= 0) {
+                    err.append("[").append(requestedVersion).append("]");
+                } else {
+                    err.append("<Unspecified, likely a pre-draft version of websocket>");
+                }
+                err.append(", configured minVersion [").append(_minVersion).append("]");
+                err.append(", reported supported versions [").append(versions).append("]");
+                LOG.warn(err.toString()); // Log it
+                // use spec language for unsupported versions
+                throw new HttpException(400, "Unsupported websocket version specification"); // Tell client
+            }
+        }
+
+        addConnection(connection);
+
+        // Set the defaults
+        connection.getConnection().setMaxBinaryMessageSize(_maxBinaryMessageSize);
+        connection.getConnection().setMaxTextMessageSize(_maxTextMessageSize);
+
+        // Let the connection finish processing the handshake
+        connection.handshake(request, response, protocol);
+        response.flushBuffer();
+
+        // Give the connection any unused data from the HTTP connection.
+        connection.fillBuffersFrom(((HttpParser)http.getParser()).getHeaderBuffer());
+        connection.fillBuffersFrom(((HttpParser)http.getParser()).getBodyBuffer());
+
+        // Tell jetty about the new connection
+        LOG.debug("Websocket upgrade {} {} {} {}",request.getRequestURI(),draft,protocol,connection);
+        request.setAttribute("org.eclipse.jetty.io.Connection", connection);
+    }
+
+    protected String[] parseProtocols(String protocol)
+    {
+        if (protocol == null)
+            return new String[]{null};
+        protocol = protocol.trim();
+        if (protocol == null || protocol.length() == 0)
+            return new String[]{null};
+        String[] passed = protocol.split("\\s*,\\s*");
+        String[] protocols = new String[passed.length + 1];
+        System.arraycopy(passed, 0, protocols, 0, passed.length);
+        return protocols;
+    }
+
+    public boolean acceptWebSocket(HttpServletRequest request, HttpServletResponse response)
+            throws IOException
+    {
+        if ("websocket".equalsIgnoreCase(request.getHeader("Upgrade")))
+        {
+            String origin = request.getHeader("Origin");
+            if (origin==null)
+                origin = request.getHeader("Sec-WebSocket-Origin");
+            if (!_acceptor.checkOrigin(request,origin))
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return false;
+            }
+
+            // Try each requested protocol
+            WebSocket websocket = null;
+
+            @SuppressWarnings("unchecked")
+            Enumeration<String> protocols = request.getHeaders("Sec-WebSocket-Protocol");
+            String protocol=null;
+            while (protocol==null && protocols!=null && protocols.hasMoreElements())
+            {
+                String candidate = protocols.nextElement();
+                for (String p : parseProtocols(candidate))
+                {
+                    websocket = _acceptor.doWebSocketConnect(request, p);
+                    if (websocket != null)
+                    {
+                        protocol = p;
+                        break;
+                    }
+                }
+            }
+
+            // Did we get a websocket?
+            if (websocket == null)
+            {
+                // Try with no protocol
+                websocket = _acceptor.doWebSocketConnect(request, null);
+
+                if (websocket==null)
+                {
+                    response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+                    return false;
+                }
+            }
+
+            // Send the upgrade
+            upgrade(request, response, websocket, protocol);
+            return true;
+        }
+
+        return false;
+    }
+
+    public List<Extension> initExtensions(List<String> requested,int maxDataOpcodes,int maxControlOpcodes,int maxReservedBits)
+    {
+        List<Extension> extensions = new ArrayList<Extension>();
+        for (String rExt : requested)
+        {
+            QuotedStringTokenizer tok = new QuotedStringTokenizer(rExt,";");
+            String extName=tok.nextToken().trim();
+            Map<String,String> parameters = new HashMap<String,String>();
+            while (tok.hasMoreTokens())
+            {
+                QuotedStringTokenizer nv = new QuotedStringTokenizer(tok.nextToken().trim(),"=");
+                String name=nv.nextToken().trim();
+                String value=nv.hasMoreTokens()?nv.nextToken().trim():null;
+                parameters.put(name,value);
+            }
+
+            Extension extension = newExtension(extName);
+
+            if (extension==null)
+                continue;
+
+            if (extension.init(parameters))
+            {
+                LOG.debug("add {} {}",extName,parameters);
+                extensions.add(extension);
+            }
+        }
+        LOG.debug("extensions={}",extensions);
+        return extensions;
+    }
+
+    private Extension newExtension(String name)
+    {
+        try
+        {
+            Class<? extends Extension> extClass = _extensionClasses.get(name);
+            if (extClass!=null)
+                return extClass.newInstance();
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
+
+        return null;
+    }
+
+    protected boolean addConnection(WebSocketServletConnection connection)
+    {
+        return isRunning() && connections.add(connection);
+    }
+
+    protected boolean removeConnection(WebSocketServletConnection connection)
+    {
+        return connections.remove(connection);
+    }
+
+    protected void closeConnections()
+    {
+        for (WebSocketServletConnection connection : connections)
+            connection.shutdown();
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketGenerator.java b/src/java/org/eclipse/jetty/websocket/WebSocketGenerator.java
new file mode 100644
index 0000000..fb69e1a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketGenerator.java
@@ -0,0 +1,33 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+
+
+/* ------------------------------------------------------------ */
+/** WebSocketGenerator.
+ */
+public interface WebSocketGenerator
+{
+    int flush() throws IOException;
+    boolean isBufferEmpty();
+    void addFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException;
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD00.java b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD00.java
new file mode 100644
index 0000000..502b0b3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD00.java
@@ -0,0 +1,173 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+
+
+/* ------------------------------------------------------------ */
+/** WebSocketGenerator.
+ * This class generates websocket packets.
+ * It is fully synchronized because it is likely that async
+ * threads will call the addMessage methods while other
+ * threads are flushing the generator.
+ */
+public class WebSocketGeneratorD00 implements WebSocketGenerator
+{
+    final private WebSocketBuffers _buffers;
+    final private EndPoint _endp;
+    private Buffer _buffer;
+
+    public WebSocketGeneratorD00(WebSocketBuffers buffers, EndPoint endp)
+    {
+        _buffers=buffers;
+        _endp=endp;
+    }
+    
+    public synchronized void addFrame(byte flags, byte opcode,byte[] content, int offset, int length) throws IOException
+    {
+        long blockFor=_endp.getMaxIdleTime();
+        
+        if (_buffer==null)
+            _buffer=_buffers.getDirectBuffer();
+
+        if (_buffer.space() == 0)
+            expelBuffer(blockFor);
+
+        bufferPut(opcode, blockFor);
+
+        if (isLengthFrame(opcode))
+        {
+            // Send a length delimited frame
+
+            // How many bytes we need for the length ?
+            // We have 7 bits available, so log2(length) / 7 + 1
+            // For example, 50000 bytes is 2 8-bytes: 11000011 01010000
+            // but we need to write it in 3 7-bytes 0000011 0000110 1010000
+            // 65536 == 1 00000000 00000000 => 100 0000000 0000000
+            int lengthBytes = new BigInteger(String.valueOf(length)).bitLength() / 7 + 1;
+            for (int i = lengthBytes - 1; i > 0; --i)
+            {
+                byte lengthByte = (byte)(0x80 | (0x7F & (length >> 7 * i)));
+                bufferPut(lengthByte, blockFor);
+            }
+            bufferPut((byte)(0x7F & length), blockFor);
+        }
+
+        int remaining = length;
+        while (remaining > 0)
+        {
+            int chunk = remaining < _buffer.space() ? remaining : _buffer.space();
+            _buffer.put(content, offset + (length - remaining), chunk);
+            remaining -= chunk;
+            if (_buffer.space() > 0)
+            {
+                if (!isLengthFrame(opcode))
+                    _buffer.put((byte)0xFF);
+                // Gently flush the data, issuing a non-blocking write
+                flushBuffer();
+            }
+            else
+            {
+                // Forcibly flush the data, issuing a blocking write
+                expelBuffer(blockFor);
+                if (remaining == 0)
+                {
+                    if (!isLengthFrame(opcode))
+                        _buffer.put((byte)0xFF);
+                    // Gently flush the data, issuing a non-blocking write
+                    flushBuffer();
+                }
+            }
+        }
+    }
+
+    private synchronized boolean isLengthFrame(byte frame)
+    {
+        return (frame & WebSocketConnectionD00.LENGTH_FRAME) == WebSocketConnectionD00.LENGTH_FRAME;
+    }
+
+    private synchronized void bufferPut(byte datum, long blockFor) throws IOException
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getDirectBuffer();
+        _buffer.put(datum);
+        if (_buffer.space() == 0)
+            expelBuffer(blockFor);
+    }
+
+    public synchronized int flush(int blockFor) throws IOException
+    {
+        return expelBuffer(blockFor);
+    }
+
+    public synchronized int flush() throws IOException
+    {
+        int flushed = flushBuffer();
+        if (_buffer!=null && _buffer.length()==0)
+        {
+            _buffers.returnBuffer(_buffer);
+            _buffer=null;
+        }
+        return flushed;
+    }
+
+    private synchronized int flushBuffer() throws IOException
+    {
+        if (!_endp.isOpen())
+            throw new EofException();
+
+        if (_buffer!=null && _buffer.hasContent())
+            return _endp.flush(_buffer);
+
+        return 0;
+    }
+
+    private synchronized int expelBuffer(long blockFor) throws IOException
+    {
+        if (_buffer==null)
+            return 0;
+        int result = flushBuffer();
+        _buffer.compact();
+        if (!_endp.isBlocking())
+        {
+            while (_buffer.space()==0)
+            {
+                boolean ready = _endp.blockWritable(blockFor);
+                if (!ready)
+                    throw new IOException("Write timeout");
+
+                result += flushBuffer();
+                _buffer.compact();
+            }
+        }
+        return result;
+    }
+
+    public synchronized boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD06.java b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD06.java
new file mode 100644
index 0000000..129b1c6
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD06.java
@@ -0,0 +1,234 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+
+
+/* ------------------------------------------------------------ */
+/** WebSocketGenerator.
+ * This class generates websocket packets.
+ * It is fully synchronized because it is likely that async
+ * threads will call the addMessage methods while other
+ * threads are flushing the generator.
+ */
+public class WebSocketGeneratorD06 implements WebSocketGenerator
+{
+    final private WebSocketBuffers _buffers;
+    final private EndPoint _endp;
+    private Buffer _buffer;
+    private final byte[] _mask=new byte[4];
+    private int _m;
+    private boolean _opsent;
+    private final MaskGen _maskGen;
+
+    public WebSocketGeneratorD06(WebSocketBuffers buffers, EndPoint endp)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _maskGen=null;
+    }
+
+    public WebSocketGeneratorD06(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _maskGen=maskGen;
+    }
+
+    public synchronized void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        // System.err.printf("<< %s %s %s\n",TypeUtil.toHexString(flags),TypeUtil.toHexString(opcode),length);
+
+        long blockFor=_endp.getMaxIdleTime();
+
+        if (_buffer==null)
+            _buffer=(_maskGen!=null)?_buffers.getBuffer():_buffers.getDirectBuffer();
+
+        boolean last=WebSocketConnectionD06.isLastFrame(flags);
+        opcode=(byte)(((0xf&flags)<<4)+0xf&opcode);
+
+        int space=(_maskGen!=null)?14:10;
+
+        do
+        {
+            opcode = _opsent?WebSocketConnectionD06.OP_CONTINUATION:opcode;
+            _opsent=true;
+
+            int payload=length;
+            if (payload+space>_buffer.capacity())
+            {
+                // We must fragement, so clear FIN bit
+                opcode&=(byte)0x7F; // Clear the FIN bit
+                payload=_buffer.capacity()-space;
+            }
+            else if (last)
+                opcode|=(byte)0x80; // Set the FIN bit
+
+            // ensure there is space for header
+            if (_buffer.space() <= space)
+                expelBuffer(blockFor);
+
+            // write mask
+            if ((_maskGen!=null))
+            {
+                _maskGen.genMask(_mask);
+                _m=0;
+                _buffer.put(_mask);
+            }
+
+            // write the opcode and length
+            if (payload>0xffff)
+            {
+                bufferPut(new byte[]{
+                        opcode,
+                        (byte)0x7f,
+                        (byte)0,
+                        (byte)0,
+                        (byte)0,
+                        (byte)0,
+                        (byte)((payload>>24)&0xff),
+                        (byte)((payload>>16)&0xff),
+                        (byte)((payload>>8)&0xff),
+                        (byte)(payload&0xff)});
+            }
+            else if (payload >=0x7e)
+            {
+                bufferPut(new byte[]{
+                        opcode,
+                        (byte)0x7e,
+                        (byte)(payload>>8),
+                        (byte)(payload&0xff)});
+            }
+            else
+            {
+                bufferPut(opcode);
+                bufferPut((byte)payload);
+            }
+
+            // write payload
+            int remaining = payload;
+            while (remaining > 0)
+            {
+                _buffer.compact();
+                int chunk = remaining < _buffer.space() ? remaining : _buffer.space();
+
+                if ((_maskGen!=null))
+                {
+                    for (int i=0;i<chunk;i++)
+                        bufferPut(content[offset+ (payload-remaining)+i]);
+                }
+                else
+                    _buffer.put(content, offset + (payload - remaining), chunk);
+
+                remaining -= chunk;
+                if (_buffer.space() > 0)
+                {
+                    // Gently flush the data, issuing a non-blocking write
+                    flushBuffer();
+                }
+                else
+                {
+                    // Forcibly flush the data, issuing a blocking write
+                    expelBuffer(blockFor);
+                    if (remaining == 0)
+                    {
+                        // Gently flush the data, issuing a non-blocking write
+                        flushBuffer();
+                    }
+                }
+            }
+            offset+=payload;
+            length-=payload;
+        }
+        while (length>0);
+        _opsent=!last;
+    }
+
+    private synchronized void bufferPut(byte[] data) throws IOException
+    {
+        if (_maskGen!=null)
+            for (int i=0;i<data.length;i++)
+                data[i]^=_mask[+_m++%4];
+        _buffer.put(data);
+    }
+
+    private synchronized void bufferPut(byte data) throws IOException
+    {
+        _buffer.put((byte)(data^_mask[+_m++%4]));
+    }
+
+    public synchronized int flush(int blockFor) throws IOException
+    {
+        return expelBuffer(blockFor);
+    }
+
+    public synchronized int flush() throws IOException
+    {
+        int flushed = flushBuffer();
+        if (_buffer!=null && _buffer.length()==0)
+        {
+            _buffers.returnBuffer(_buffer);
+            _buffer=null;
+        }
+        return flushed;
+    }
+
+    private synchronized int flushBuffer() throws IOException
+    {
+        if (!_endp.isOpen())
+            throw new EofException();
+
+        if (_buffer!=null)
+            return _endp.flush(_buffer);
+
+        return 0;
+    }
+
+    private synchronized int expelBuffer(long blockFor) throws IOException
+    {
+        if (_buffer==null)
+            return 0;
+        int result = flushBuffer();
+        _buffer.compact();
+        if (!_endp.isBlocking())
+        {
+            while (_buffer.space()==0)
+            {
+                boolean ready = _endp.blockWritable(blockFor);
+                if (!ready)
+                    throw new IOException("Write timeout");
+
+                result += flushBuffer();
+                _buffer.compact();
+            }
+        }
+        return result;
+    }
+
+    public synchronized boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD08.java b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD08.java
new file mode 100644
index 0000000..d2bb753
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorD08.java
@@ -0,0 +1,308 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+
+/**
+ * WebSocketGenerator. This class generates websocket packets. It is fully synchronized because it is likely that async threads will call the addMessage methods
+ * while other threads are flushing the generator.
+ */
+public class WebSocketGeneratorD08 implements WebSocketGenerator
+{
+    private final Lock _lock = new ReentrantLock();
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final byte[] _mask = new byte[4];
+    private final MaskGen _maskGen;
+    private Buffer _buffer;
+    private int _m;
+    private boolean _opsent;
+    private boolean _closed;
+
+    public WebSocketGeneratorD08(WebSocketBuffers buffers, EndPoint endp)
+    {
+        this(buffers, endp, null);
+    }
+
+    public WebSocketGeneratorD08(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen)
+    {
+        _buffers = buffers;
+        _endp = endp;
+        _maskGen = maskGen;
+    }
+
+    public Buffer getBuffer()
+    {
+        _lock.lock();
+        try
+        {
+            return _buffer;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        _lock.lock();
+        try
+        {
+            if (_closed)
+                throw new EofException("Closed");
+            if (opcode == WebSocketConnectionRFC6455.OP_CLOSE)
+                _closed = true;
+
+            boolean mask = _maskGen != null;
+
+            if (_buffer == null)
+                _buffer = mask ? _buffers.getBuffer() : _buffers.getDirectBuffer();
+
+            boolean last = WebSocketConnectionD08.isLastFrame(flags);
+
+            int space = mask ? 14 : 10;
+
+            do
+            {
+                opcode = _opsent ? WebSocketConnectionD08.OP_CONTINUATION : opcode;
+                opcode = (byte)(((0xf & flags) << 4) + (0xf & opcode));
+                _opsent = true;
+
+                int payload = length;
+                if (payload + space > _buffer.capacity())
+                {
+                    // We must fragement, so clear FIN bit
+                    opcode = (byte)(opcode & 0x7F); // Clear the FIN bit
+                    payload = _buffer.capacity() - space;
+                }
+                else if (last)
+                    opcode = (byte)(opcode | 0x80); // Set the FIN bit
+
+                // ensure there is space for header
+                if (_buffer.space() <= space)
+                {
+                    flushBuffer();
+                    if (_buffer.space() <= space)
+                        flush();
+                }
+
+                // write the opcode and length
+                if (payload > 0xffff)
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            mask ? (byte)0xff : (byte)0x7f,
+                            (byte)0,
+                            (byte)0,
+                            (byte)0,
+                            (byte)0,
+                            (byte)((payload >> 24) & 0xff),
+                            (byte)((payload >> 16) & 0xff),
+                            (byte)((payload >> 8) & 0xff),
+                            (byte)(payload & 0xff)});
+                }
+                else if (payload >= 0x7e)
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            mask ? (byte)0xfe : (byte)0x7e,
+                            (byte)(payload >> 8),
+                            (byte)(payload & 0xff)});
+                }
+                else
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            (byte)(mask ? (0x80 | payload) : payload)});
+                }
+
+                // write mask
+                if (mask)
+                {
+                    _maskGen.genMask(_mask);
+                    _m = 0;
+                    _buffer.put(_mask);
+                }
+
+                // write payload
+                int remaining = payload;
+                while (remaining > 0)
+                {
+                    _buffer.compact();
+                    int chunk = remaining < _buffer.space() ? remaining : _buffer.space();
+
+                    if (mask)
+                    {
+                        for (int i = 0; i < chunk; i++)
+                            _buffer.put((byte)(content[offset + (payload - remaining) + i] ^ _mask[+_m++ % 4]));
+                    }
+                    else
+                        _buffer.put(content, offset + (payload - remaining), chunk);
+
+                    remaining -= chunk;
+                    if (_buffer.space() > 0)
+                    {
+                        // Gently flush the data, issuing a non-blocking write
+                        flushBuffer();
+                    }
+                    else
+                    {
+                        // Forcibly flush the data, issuing a blocking write
+                        flush();
+                        if (remaining == 0)
+                        {
+                            // Gently flush the data, issuing a non-blocking write
+                            flushBuffer();
+                        }
+                    }
+                }
+                offset += payload;
+                length -= payload;
+            }
+            while (length > 0);
+            _opsent = !last;
+
+            if (_buffer != null && _buffer.length() == 0)
+            {
+                _buffers.returnBuffer(_buffer);
+                _buffer = null;
+            }
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public int flushBuffer() throws IOException
+    {
+        if (!_lock.tryLock())
+            return 0;
+
+        try
+        {
+            if (!_endp.isOpen())
+                throw new EofException();
+
+            if (_buffer != null)
+            {
+                int flushed = _buffer.hasContent() ? _endp.flush(_buffer) : 0;
+                if (_closed && _buffer.length() == 0)
+                    _endp.shutdownOutput();
+                return flushed;
+            }
+
+            return 0;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public int flush() throws IOException
+    {
+        if (!_lock.tryLock())
+            return 0;
+
+        try
+        {
+            if (_buffer == null)
+                return 0;
+
+            int result = flushBuffer();
+            if (!_endp.isBlocking())
+            {
+                long now = System.currentTimeMillis();
+                long end = now + _endp.getMaxIdleTime();
+                while (_buffer.length() > 0)
+                {
+                    boolean ready = _endp.blockWritable(end - now);
+                    if (!ready)
+                    {
+                        now = System.currentTimeMillis();
+                        if (now < end)
+                            continue;
+                        throw new IOException("Write timeout");
+                    }
+
+                    result += flushBuffer();
+                }
+            }
+            _buffer.compact();
+            return result;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public boolean isBufferEmpty()
+    {
+        _lock.lock();
+        try
+        {
+            return _buffer == null || _buffer.length() == 0;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public void returnBuffer()
+    {
+        _lock.lock();
+        try
+        {
+            if (_buffer != null && _buffer.length() == 0)
+            {
+                _buffers.returnBuffer(_buffer);
+                _buffer = null;
+            }
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        // Do NOT use synchronized (this)
+        // because it's very easy to deadlock when debugging is enabled.
+        // We do a best effort to print the right toString() and that's it.
+        Buffer buffer = _buffer;
+        return String.format("%s@%x closed=%b buffer=%d",
+                getClass().getSimpleName(),
+                hashCode(),
+                _closed,
+                buffer == null ? -1 : buffer.length());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java
new file mode 100644
index 0000000..5a539ca
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java
@@ -0,0 +1,312 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+
+
+/**
+ * WebSocketGenerator.
+ * This class generates websocket packets.
+ * It is fully synchronized because it is likely that async
+ * threads will call the addMessage methods while other
+ * threads are flushing the generator.
+ */
+public class WebSocketGeneratorRFC6455 implements WebSocketGenerator
+{
+    private final Lock _lock = new ReentrantLock();
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final byte[] _mask = new byte[4];
+    private final MaskGen _maskGen;
+    private Buffer _buffer;
+    private int _m;
+    private boolean _opsent;
+    private boolean _closed;
+
+    public WebSocketGeneratorRFC6455(WebSocketBuffers buffers, EndPoint endp)
+    {
+        this(buffers, endp, null);
+    }
+
+    public WebSocketGeneratorRFC6455(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen)
+    {
+        _buffers = buffers;
+        _endp = endp;
+        _maskGen = maskGen;
+    }
+
+    public Buffer getBuffer()
+    {
+        _lock.lock();
+        try
+        {
+            return _buffer;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException
+    {
+        _lock.lock();
+        try
+        {
+            if (_closed)
+                throw new EofException("Closed");
+            if (opcode == WebSocketConnectionRFC6455.OP_CLOSE)
+                _closed = true;
+
+            boolean mask = _maskGen != null;
+
+            if (_buffer == null)
+                _buffer = mask ? _buffers.getBuffer() : _buffers.getDirectBuffer();
+
+            boolean last = WebSocketConnectionRFC6455.isLastFrame(flags);
+
+            int space = mask ? 14 : 10;
+
+            do
+            {
+                opcode = _opsent ? WebSocketConnectionRFC6455.OP_CONTINUATION : opcode;
+                opcode = (byte)(((0xf & flags) << 4) + (0xf & opcode));
+                _opsent = true;
+
+                int payload = length;
+                if (payload + space > _buffer.capacity())
+                {
+                    // We must fragement, so clear FIN bit
+                    opcode = (byte)(opcode & 0x7F); // Clear the FIN bit
+                    payload = _buffer.capacity() - space;
+                }
+                else if (last)
+                    opcode = (byte)(opcode | 0x80); // Set the FIN bit
+
+                // ensure there is space for header
+                if (_buffer.space() <= space)
+                {
+                    flushBuffer();
+                    if (_buffer.space() <= space)
+                        flush();
+                }
+
+                // write the opcode and length
+                if (payload > 0xffff)
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            mask ? (byte)0xff : (byte)0x7f,
+                            (byte)0,
+                            (byte)0,
+                            (byte)0,
+                            (byte)0,
+                            (byte)((payload >> 24) & 0xff),
+                            (byte)((payload >> 16) & 0xff),
+                            (byte)((payload >> 8) & 0xff),
+                            (byte)(payload & 0xff)});
+                }
+                else if (payload >= 0x7e)
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            mask ? (byte)0xfe : (byte)0x7e,
+                            (byte)(payload >> 8),
+                            (byte)(payload & 0xff)});
+                }
+                else
+                {
+                    _buffer.put(new byte[]{
+                            opcode,
+                            (byte)(mask ? (0x80 | payload) : payload)});
+                }
+
+                // write mask
+                if (mask)
+                {
+                    _maskGen.genMask(_mask);
+                    _m = 0;
+                    _buffer.put(_mask);
+                }
+
+                // write payload
+                int remaining = payload;
+                while (remaining > 0)
+                {
+                    _buffer.compact();
+                    int chunk = remaining < _buffer.space() ? remaining : _buffer.space();
+
+                    if (mask)
+                    {
+                        for (int i = 0; i < chunk; i++)
+                            _buffer.put((byte)(content[offset + (payload - remaining) + i] ^ _mask[+_m++ % 4]));
+                    }
+                    else
+                        _buffer.put(content, offset + (payload - remaining), chunk);
+
+                    remaining -= chunk;
+                    if (_buffer.space() > 0)
+                    {
+                        // Gently flush the data, issuing a non-blocking write
+                        flushBuffer();
+                    }
+                    else
+                    {
+                        // Forcibly flush the data, issuing a blocking write
+                        flush();
+                        if (remaining == 0)
+                        {
+                            // Gently flush the data, issuing a non-blocking write
+                            flushBuffer();
+                        }
+                    }
+                }
+                offset += payload;
+                length -= payload;
+            }
+            while (length > 0);
+            _opsent = !last;
+
+            if (_buffer != null && _buffer.length() == 0)
+            {
+                _buffers.returnBuffer(_buffer);
+                _buffer = null;
+            }
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public int flushBuffer() throws IOException
+    {
+        if (!_lock.tryLock())
+            return 0;
+
+        try
+        {
+            if (!_endp.isOpen())
+                throw new EofException();
+
+            if (_buffer != null)
+            {
+                int flushed = _buffer.hasContent() ? _endp.flush(_buffer) : 0;
+                if (_closed && _buffer.length() == 0)
+                    _endp.shutdownOutput();
+                return flushed;
+            }
+
+            return 0;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public int flush() throws IOException
+    {
+        if (!_lock.tryLock())
+            return 0;
+
+        try
+        {
+            if (_buffer == null)
+                return 0;
+
+            int result = flushBuffer();
+            if (!_endp.isBlocking())
+            {
+                long now = System.currentTimeMillis();
+                long end = now + _endp.getMaxIdleTime();
+                while (_buffer.length() > 0)
+                {
+                    boolean ready = _endp.blockWritable(end - now);
+                    if (!ready)
+                    {
+                        now = System.currentTimeMillis();
+                        if (now < end)
+                            continue;
+                        throw new IOException("Write timeout");
+                    }
+
+                    result += flushBuffer();
+                }
+            }
+            _buffer.compact();
+            return result;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public boolean isBufferEmpty()
+    {
+        _lock.lock();
+        try
+        {
+            return _buffer == null || _buffer.length() == 0;
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    public void returnBuffer()
+    {
+        _lock.lock();
+        try
+        {
+            if (_buffer != null && _buffer.length() == 0)
+            {
+                _buffers.returnBuffer(_buffer);
+                _buffer = null;
+            }
+        }
+        finally
+        {
+            _lock.unlock();
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        // Do NOT use synchronized (this)
+        // because it's very easy to deadlock when debugging is enabled.
+        // We do a best effort to print the right toString() and that's it.
+        Buffer buffer = _buffer;
+        return String.format("%s@%x closed=%b buffer=%d",
+                getClass().getSimpleName(),
+                hashCode(),
+                _closed,
+                buffer == null ? -1 : buffer.length());
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketHandler.java b/src/java/org/eclipse/jetty/websocket/WebSocketHandler.java
new file mode 100644
index 0000000..5d5f9e4
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketHandler.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+
+public abstract class WebSocketHandler extends HandlerWrapper implements WebSocketFactory.Acceptor
+{
+    private final WebSocketFactory _webSocketFactory=new WebSocketFactory(this,32*1024);
+    
+    public WebSocketFactory getWebSocketFactory()
+    {
+        return _webSocketFactory;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+    {
+        if (_webSocketFactory.acceptWebSocket(request,response) || response.isCommitted())
+        {
+            baseRequest.setHandled(true);
+            return;
+        }
+        super.handle(target,baseRequest,request,response);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public boolean checkOrigin(HttpServletRequest request, String origin)
+    {
+        return true;
+    }
+    
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketParser.java b/src/java/org/eclipse/jetty/websocket/WebSocketParser.java
new file mode 100644
index 0000000..87a48a3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketParser.java
@@ -0,0 +1,53 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import org.eclipse.jetty.io.Buffer;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Parser the WebSocket protocol.
+ *
+ */
+public interface WebSocketParser
+{
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    public interface FrameHandler
+    {
+        void onFrame(byte flags, byte opcode, Buffer buffer);
+        void close(int code,String message);
+    }
+
+    Buffer getBuffer();
+
+    /**
+     * @return an indication of progress, normally bytes filled plus events parsed, or -1 for EOF
+     */
+    int parseNext();
+
+    boolean isBufferEmpty();
+
+    void fill(Buffer buffer);
+
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketParserD00.java b/src/java/org/eclipse/jetty/websocket/WebSocketParserD00.java
new file mode 100644
index 0000000..93cc355
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketParserD00.java
@@ -0,0 +1,212 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Parser the WebSocket protocol.
+ *
+ */
+public class WebSocketParserD00 implements WebSocketParser
+{
+    private static final Logger LOG = Log.getLogger(WebSocketParserD00.class);
+
+    public static final int STATE_START=0;
+    public static final int STATE_SENTINEL_DATA=1;
+    public static final int STATE_LENGTH=2;
+    public static final int STATE_DATA=3;
+
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final FrameHandler _handler;
+    private int _state;
+    private Buffer _buffer;
+    private byte _opcode;
+    private int _length;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffers The buffers to use for parsing.  Only the {@link Buffers#getBuffer()} is used.
+     * This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
+     * is mostly used.
+     * @param endp the endpoint
+     * @param handler the handler to notify when a parse event occurs
+     */
+    public WebSocketParserD00(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _handler=handler;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        return _buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse to next event.
+     * Parse to the next {@link WebSocketParser.FrameHandler} event or until no more data is
+     * available. Fill data from the {@link EndPoint} only as necessary.
+     * @return An indication of progress or otherwise. -1 indicates EOF, 0 indicates
+     * that no bytes were read and no messages parsed. A positive number indicates either
+     * the bytes filled or the messages parsed.
+     */
+    public int parseNext()
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+
+        int progress=0;
+
+        // Loop until an datagram call back or can't fill anymore
+        while(true)
+        {
+            int length=_buffer.length();
+
+            // Fill buffer if we need a byte or need length
+            if (length == 0 || _state==STATE_DATA && length<_length)
+            {
+                // compact to mark (set at start of data)
+                _buffer.compact();
+
+                // if no space, then the data is too big for buffer
+                if (_buffer.space() == 0)
+                    throw new IllegalStateException("FULL");
+
+                // catch IOExceptions (probably EOF) and try to parse what we have
+                try
+                {
+                    int filled=_endp.isOpen()?_endp.fill(_buffer):-1;
+                    if (filled<=0)
+                        return progress;
+                    progress+=filled;
+                    length=_buffer.length();
+                }
+                catch(IOException e)
+                {
+                    LOG.debug(e);
+                    return progress>0?progress:-1;
+                }
+            }
+
+
+            // Parse the buffer byte by byte (unless it is STATE_DATA)
+            byte b;
+            charloop: while (length-->0)
+            {
+                switch (_state)
+                {
+                    case STATE_START:
+                        b=_buffer.get();
+                        _opcode=b;
+                        if (_opcode<0)
+                        {
+                            _length=0;
+                            _state=STATE_LENGTH;
+                        }
+                        else
+                        {
+                            _state=STATE_SENTINEL_DATA;
+                            _buffer.mark(0);
+                        }
+                        continue;
+
+                    case STATE_SENTINEL_DATA:
+                        b=_buffer.get();
+                        if ((b&0xff)==0xff)
+                        {
+                            _state=STATE_START;
+                            int l=_buffer.getIndex()-_buffer.markIndex()-1;
+                            progress++;
+                            _handler.onFrame((byte)0,_opcode,_buffer.sliceFromMark(l));
+                            _buffer.setMarkIndex(-1);
+                            if (_buffer.length()==0)
+                            {
+                                _buffers.returnBuffer(_buffer);
+                                _buffer=null;
+                            }
+                            return progress;
+                        }
+                        continue;
+
+                    case STATE_LENGTH:
+                        b=_buffer.get();
+                        _length=_length<<7 | (0x7f&b);
+                        if (b>=0)
+                        {
+                            _state=STATE_DATA;
+                            _buffer.mark(0);
+                        }
+                        continue;
+
+                    case STATE_DATA:
+                        if (_buffer.markIndex()<0)
+                        if (_buffer.length()<_length)
+                            break charloop;
+                        Buffer data=_buffer.sliceFromMark(_length);
+                        _buffer.skip(_length);
+                        _state=STATE_START;
+                        progress++;
+                        _handler.onFrame((byte)0, _opcode, data);
+
+                        if (_buffer.length()==0)
+                        {
+                            _buffers.returnBuffer(_buffer);
+                            _buffer=null;
+                        }
+
+                        return progress;
+                }
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fill(Buffer buffer)
+    {
+        if (buffer!=null && buffer.length()>0)
+        {
+            if (_buffer==null)
+                _buffer=_buffers.getBuffer();
+            _buffer.put(buffer);
+            buffer.clear();
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketParserD06.java b/src/java/org/eclipse/jetty/websocket/WebSocketParserD06.java
new file mode 100644
index 0000000..5539780
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketParserD06.java
@@ -0,0 +1,310 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Parser the WebSocket protocol.
+ *
+ */
+public class WebSocketParserD06 implements WebSocketParser
+{
+    private static final Logger LOG = Log.getLogger(WebSocketParserD06.class);
+
+    public enum State {
+
+        START(0), MASK(4), OPCODE(1), LENGTH_7(1), LENGTH_16(2), LENGTH_63(8), DATA(0), SKIP(1);
+
+        int _needs;
+
+        State(int needs)
+        {
+            _needs=needs;
+        }
+
+        int getNeeds()
+        {
+            return _needs;
+        }
+    }
+
+
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final FrameHandler _handler;
+    private final boolean _masked;
+    private State _state;
+    private Buffer _buffer;
+    private byte _flags;
+    private byte _opcode;
+    private int _bytesNeeded;
+    private long _length;
+    private final byte[] _mask = new byte[4];
+    private int _m;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffers The buffers to use for parsing.  Only the {@link Buffers#getBuffer()} is used.
+     * This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
+     * is mostly used.
+     * @param endp the endpoint
+     * @param handler the handler to notify when a parse event occurs
+     * @param masked whether masking should be handled
+     */
+    public WebSocketParserD06(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean masked)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _handler=handler;
+        _masked=masked;
+        _state=State.START;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        return _buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse to next event.
+     * Parse to the next {@link WebSocketParser.FrameHandler} event or until no more data is
+     * available. Fill data from the {@link EndPoint} only as necessary.
+     * @return An indication of progress or otherwise. -1 indicates EOF, 0 indicates
+     * that no bytes were read and no messages parsed. A positive number indicates either
+     * the bytes filled or the messages parsed.
+     */
+    public int parseNext()
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+
+        int total_filled=0;
+        int events=0;
+
+        // Loop until an datagram call back or can't fill anymore
+        while(true)
+        {
+            int available=_buffer.length();
+
+            // Fill buffer if we need a byte or need length
+            while (available<(_state==State.SKIP?1:_bytesNeeded))
+            {
+                // compact to mark (set at start of data)
+                _buffer.compact();
+
+                // if no space, then the data is too big for buffer
+                if (_buffer.space() == 0)
+                    throw new IllegalStateException("FULL: "+_state+" "+_bytesNeeded+">"+_buffer.capacity());
+
+                // catch IOExceptions (probably EOF) and try to parse what we have
+                try
+                {
+                    int filled=_endp.isOpen()?_endp.fill(_buffer):-1;
+                    if (filled<=0)
+                        return (total_filled+events)>0?(total_filled+events):filled;
+                    total_filled+=filled;
+                    available=_buffer.length();
+                }
+                catch(IOException e)
+                {
+                    LOG.debug(e);
+                    return (total_filled+events)>0?(total_filled+events):-1;
+                }
+            }
+
+            // if we are here, then we have sufficient bytes to process the current state.
+
+            // Parse the buffer byte by byte (unless it is STATE_DATA)
+            byte b;
+            while (_state!=State.DATA && available>=(_state==State.SKIP?1:_bytesNeeded))
+            {
+                switch (_state)
+                {
+                    case START:
+                        _state=_masked?State.MASK:State.OPCODE;
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case MASK:
+                        _buffer.get(_mask,0,4);
+                        available-=4;
+                        _state=State.OPCODE;
+                        _bytesNeeded=_state.getNeeds();
+                        _m=0;
+                        continue;
+
+                    case OPCODE:
+                        b=_buffer.get();
+                        available--;
+                        if (_masked)
+                            b^=_mask[_m++%4];
+                        _opcode=(byte)(b&0xf);
+                        _flags=(byte)(0xf&(b>>4));
+
+                        if (WebSocketConnectionD06.isControlFrame(_opcode)&&!WebSocketConnectionD06.isLastFrame(_flags))
+                        {
+                            _state=State.SKIP;
+                            events++;
+                            _handler.close(WebSocketConnectionD06.CLOSE_PROTOCOL,"fragmented control");
+                        }
+                        else
+                            _state=State.LENGTH_7;
+
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case LENGTH_7:
+                        b=_buffer.get();
+                        available--;
+                        if (_masked)
+                            b^=_mask[_m++%4];
+                        switch(b)
+                        {
+                            case 127:
+                                _length=0;
+                                _state=State.LENGTH_63;
+                                _bytesNeeded=_state.getNeeds();
+                                break;
+                            case 126:
+                                _length=0;
+                                _state=State.LENGTH_16;
+                                _bytesNeeded=_state.getNeeds();
+                                break;
+                            default:
+                                _length=(0x7f&b);
+                                _bytesNeeded=(int)_length;
+                                _state=State.DATA;
+                        }
+                        continue;
+
+                    case LENGTH_16:
+                        b=_buffer.get();
+                        available--;
+                        if (_masked)
+                            b^=_mask[_m++%4];
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            _bytesNeeded=(int)_length;
+                            if (_length>_buffer.capacity())
+                            {
+                                _state=State.SKIP;
+                                events++;
+                                _handler.close(WebSocketConnectionD06.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity());
+                            }
+                            else
+                            {
+                                _state=State.DATA;
+                            }
+                        }
+                        continue;
+
+                    case LENGTH_63:
+                        b=_buffer.get();
+                        available--;
+                        if (_masked)
+                            b^=_mask[_m++%4];
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            _bytesNeeded=(int)_length;
+                            if (_length>=_buffer.capacity())
+                            {
+                                _state=State.SKIP;
+                                events++;
+                                _handler.close(WebSocketConnectionD06.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity());
+                            }
+                            else
+                            {
+                                _state=State.DATA;
+                            }
+                        }
+                        continue;
+
+                    case SKIP:
+                        int skip=Math.min(available,_bytesNeeded);
+                        _buffer.skip(skip);
+                        available-=skip;
+                        _bytesNeeded-=skip;
+                        if (_bytesNeeded==0)
+                            _state=State.START;
+
+                }
+            }
+
+            if (_state==State.DATA && available>=_bytesNeeded)
+            {
+                Buffer data =_buffer.get(_bytesNeeded);
+                if (_masked)
+                {
+                    if (data.array()==null)
+                        data=_buffer.asMutableBuffer();
+                    byte[] array = data.array();
+                    final int end=data.putIndex();
+                    for (int i=data.getIndex();i<end;i++)
+                        array[i]^=_mask[_m++%4];
+                }
+
+                // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length());
+                events++;
+                _handler.onFrame(_flags, _opcode, data);
+                _bytesNeeded=0;
+                _state=State.START;
+
+                if (_buffer.length()==0)
+                {
+                    _buffers.returnBuffer(_buffer);
+                    _buffer=null;
+                }
+
+                return total_filled+events;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fill(Buffer buffer)
+    {
+        if (buffer!=null && buffer.length()>0)
+        {
+            if (_buffer==null)
+                _buffer=_buffers.getBuffer();
+            _buffer.put(buffer);
+            buffer.clear();
+        }
+    }
+
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketParserD08.java b/src/java/org/eclipse/jetty/websocket/WebSocketParserD08.java
new file mode 100644
index 0000000..362414a
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketParserD08.java
@@ -0,0 +1,394 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Parser the WebSocket protocol.
+ *
+ */
+public class WebSocketParserD08 implements WebSocketParser
+{
+    private static final Logger LOG = Log.getLogger(WebSocketParserD08.class);
+
+    public enum State {
+
+        START(0), OPCODE(1), LENGTH_7(1), LENGTH_16(2), LENGTH_63(8), MASK(4), PAYLOAD(0), DATA(0), SKIP(1), SEEK_EOF(1);
+
+        int _needs;
+
+        State(int needs)
+        {
+            _needs=needs;
+        }
+
+        int getNeeds()
+        {
+            return _needs;
+        }
+    }
+
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final FrameHandler _handler;
+    private final boolean _shouldBeMasked;
+    private State _state;
+    private Buffer _buffer;
+    private byte _flags;
+    private byte _opcode;
+    private int _bytesNeeded;
+    private long _length;
+    private boolean _masked;
+    private final byte[] _mask = new byte[4];
+    private int _m;
+    private boolean _skip;
+    private boolean _fragmentFrames=true;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffers The buffers to use for parsing.  Only the {@link Buffers#getBuffer()} is used.
+     * This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
+     * is mostly used.
+     * @param endp the endpoint
+     * @param handler the handler to notify when a parse event occurs
+     * @param shouldBeMasked whether masking should be handled
+     */
+    public WebSocketParserD08(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _handler=handler;
+        _shouldBeMasked=shouldBeMasked;
+        _state=State.START;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if fake fragments should be created for frames larger than the buffer.
+     */
+    public boolean isFakeFragments()
+    {
+        return _fragmentFrames;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param fakeFragments True if fake fragments should be created for frames larger than the buffer.
+     */
+    public void setFakeFragments(boolean fakeFragments)
+    {
+        _fragmentFrames = fakeFragments;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        return _buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse to next event.
+     * Parse to the next {@link WebSocketParser.FrameHandler} event or until no more data is
+     * available. Fill data from the {@link EndPoint} only as necessary.
+     * @return An indication of progress or otherwise. -1 indicates EOF, 0 indicates
+     * that no bytes were read and no messages parsed. A positive number indicates either
+     * the bytes filled or the messages parsed.
+     */
+    public int parseNext()
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+
+        boolean progress=false;
+        int filled=-1;
+
+        // Loop until a datagram call back or can't fill anymore
+        while(!progress && (!_endp.isInputShutdown()||_buffer.length()>0))
+        {
+            int available=_buffer.length();
+
+            // Fill buffer if we need a byte or need length
+            while (available<(_state==State.SKIP?1:_bytesNeeded))
+            {
+                // compact to mark (set at start of data)
+                _buffer.compact();
+
+                // if no space, then the data is too big for buffer
+                if (_buffer.space() == 0)
+                {
+                    // Can we send a fake frame?
+                    if (_fragmentFrames && _state==State.DATA)
+                    {
+                        Buffer data =_buffer.get(4*(available/4));
+                        _buffer.compact();
+                        if (_masked)
+                        {
+                            if (data.array()==null)
+                                data=_buffer.asMutableBuffer();
+                            byte[] array = data.array();
+                            final int end=data.putIndex();
+                            for (int i=data.getIndex();i<end;i++)
+                                array[i]^=_mask[_m++%4];
+                        }
+
+                        // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length());
+                        _bytesNeeded-=data.length();
+                        progress=true;
+                        _handler.onFrame((byte)(_flags&(0xff^WebSocketConnectionD08.FLAG_FIN)), _opcode, data);
+
+                        _opcode=WebSocketConnectionD08.OP_CONTINUATION;
+                    }
+
+                    if (_buffer.space() == 0)
+                        throw new IllegalStateException("FULL: "+_state+" "+_bytesNeeded+">"+_buffer.capacity());
+                }
+
+                // catch IOExceptions (probably EOF) and try to parse what we have
+                try
+                {
+                    filled=_endp.isInputShutdown()?-1:_endp.fill(_buffer);
+                    available=_buffer.length();
+                    // System.err.printf(">> filled %d/%d%n",filled,available);
+                    if (filled<=0)
+                        break;
+                }
+                catch(IOException e)
+                {
+                    LOG.debug(e);
+                    filled=-1;
+                    break;
+                }
+            }
+            // Did we get enough?
+            if (available<(_state==State.SKIP?1:_bytesNeeded))
+                break;
+
+            // if we are here, then we have sufficient bytes to process the current state.
+            // Parse the buffer byte by byte (unless it is STATE_DATA)
+            byte b;
+            while (_state!=State.DATA && available>=(_state==State.SKIP?1:_bytesNeeded))
+            {
+                switch (_state)
+                {
+                    case START:
+                        _skip=false;
+                        _state=_opcode==WebSocketConnectionD08.OP_CLOSE?State.SEEK_EOF:State.OPCODE;
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case OPCODE:
+                        b=_buffer.get();
+                        available--;
+                        _opcode=(byte)(b&0xf);
+                        _flags=(byte)(0xf&(b>>4));
+
+                        if (WebSocketConnectionD08.isControlFrame(_opcode)&&!WebSocketConnectionD08.isLastFrame(_flags))
+                        {
+                            LOG.warn("Fragmented Control from "+_endp);
+                            _handler.close(WebSocketConnectionD08.CLOSE_PROTOCOL,"Fragmented control");
+                            progress=true;
+                            _skip=true;
+                        }
+
+                        _state=State.LENGTH_7;
+                        _bytesNeeded=_state.getNeeds();
+
+                        continue;
+
+                    case LENGTH_7:
+                        b=_buffer.get();
+                        available--;
+                        _masked=(b&0x80)!=0;
+                        b=(byte)(0x7f&b);
+
+                        switch(b)
+                        {
+                            case 0x7f:
+                                _length=0;
+                                _state=State.LENGTH_63;
+                                break;
+                            case 0x7e:
+                                _length=0;
+                                _state=State.LENGTH_16;
+                                break;
+                            default:
+                                _length=(0x7f&b);
+                                _state=_masked?State.MASK:State.PAYLOAD;
+                        }
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case LENGTH_16:
+                        b=_buffer.get();
+                        available--;
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            if (_length>_buffer.capacity() && !_fragmentFrames)
+                            {
+                                progress=true;
+                                _handler.close(WebSocketConnectionD08.CLOSE_BADDATA,"frame size "+_length+">"+_buffer.capacity());
+                                _skip=true;
+                            }
+
+                            _state=_masked?State.MASK:State.PAYLOAD;
+                            _bytesNeeded=_state.getNeeds();
+                        }
+                        continue;
+
+                    case LENGTH_63:
+                        b=_buffer.get();
+                        available--;
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            _bytesNeeded=(int)_length;
+                            if (_length>=_buffer.capacity() && !_fragmentFrames)
+                            {
+                                progress=true;
+                                _handler.close(WebSocketConnectionD08.CLOSE_BADDATA,"frame size "+_length+">"+_buffer.capacity());
+                                _skip=true;
+                            }
+
+                            _state=_masked?State.MASK:State.PAYLOAD;
+                            _bytesNeeded=_state.getNeeds();
+                        }
+                        continue;
+
+                    case MASK:
+                        _buffer.get(_mask,0,4);
+                        _m=0;
+                        available-=4;
+                        _state=State.PAYLOAD;
+                        _bytesNeeded=_state.getNeeds();
+                        break;
+
+                    case PAYLOAD:
+                        _bytesNeeded=(int)_length;
+                        _state=_skip?State.SKIP:State.DATA;
+                        break;
+
+                    case DATA:
+                        break;
+
+                    case SKIP:
+                        int skip=Math.min(available,_bytesNeeded);
+                        progress=true;
+                        _buffer.skip(skip);
+                        available-=skip;
+                        _bytesNeeded-=skip;
+                        if (_bytesNeeded==0)
+                            _state=State.START;
+                        break;
+
+                    case SEEK_EOF:
+                        progress=true;
+                        _buffer.skip(available);
+                        available=0;
+                        break;
+                }
+            }
+
+            if (_state==State.DATA && available>=_bytesNeeded)
+            {
+                if ( _masked!=_shouldBeMasked)
+                {
+                    _buffer.skip(_bytesNeeded);
+                    _state=State.START;
+                    progress=true;
+                    _handler.close(WebSocketConnectionD08.CLOSE_PROTOCOL,"bad mask");
+                }
+                else
+                {
+                    Buffer data =_buffer.get(_bytesNeeded);
+                    if (_masked)
+                    {
+                        if (data.array()==null)
+                            data=_buffer.asMutableBuffer();
+                        byte[] array = data.array();
+                        final int end=data.putIndex();
+                        for (int i=data.getIndex();i<end;i++)
+                            array[i]^=_mask[_m++%4];
+                    }
+
+                    // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length());
+
+                    progress=true;
+                    _handler.onFrame(_flags, _opcode, data);
+                    _bytesNeeded=0;
+                    _state=State.START;
+                }
+
+                break;
+            }
+        }
+
+        return progress?1:filled;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fill(Buffer buffer)
+    {
+        if (buffer!=null && buffer.length()>0)
+        {
+            if (_buffer==null)
+                _buffer=_buffers.getBuffer();
+
+            _buffer.put(buffer);
+            buffer.clear();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void returnBuffer()
+    {
+        if (_buffer!=null && _buffer.length()==0)
+        {
+            _buffers.returnBuffer(_buffer);
+            _buffer=null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return String.format("%s@%x state=%s buffer=%s",
+                getClass().getSimpleName(),
+                hashCode(),
+                _state,
+                _buffer);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java b/src/java/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java
new file mode 100644
index 0000000..9f0f8e1
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java
@@ -0,0 +1,394 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+
+
+/* ------------------------------------------------------------ */
+/**
+ * Parser the WebSocket protocol.
+ *
+ */
+public class WebSocketParserRFC6455 implements WebSocketParser
+{
+    private static final Logger LOG = Log.getLogger(WebSocketParserRFC6455.class);
+
+    public enum State {
+
+        START(0), OPCODE(1), LENGTH_7(1), LENGTH_16(2), LENGTH_63(8), MASK(4), PAYLOAD(0), DATA(0), SKIP(1), SEEK_EOF(1);
+
+        int _needs;
+
+        State(int needs)
+        {
+            _needs=needs;
+        }
+
+        int getNeeds()
+        {
+            return _needs;
+        }
+    }
+
+    private final WebSocketBuffers _buffers;
+    private final EndPoint _endp;
+    private final FrameHandler _handler;
+    private final boolean _shouldBeMasked;
+    private State _state;
+    private Buffer _buffer;
+    private byte _flags;
+    private byte _opcode;
+    private int _bytesNeeded;
+    private long _length;
+    private boolean _masked;
+    private final byte[] _mask = new byte[4];
+    private int _m;
+    private boolean _skip;
+    private boolean _fragmentFrames=true;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param buffers The buffers to use for parsing.  Only the {@link Buffers#getBuffer()} is used.
+     * This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
+     * is mostly used.
+     * @param endp the endpoint
+     * @param handler the handler to notify when a parse event occurs
+     * @param shouldBeMasked whether masking should be handled
+     */
+    public WebSocketParserRFC6455(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked)
+    {
+        _buffers=buffers;
+        _endp=endp;
+        _handler=handler;
+        _shouldBeMasked=shouldBeMasked;
+        _state=State.START;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return True if fake fragments should be created for frames larger than the buffer.
+     */
+    public boolean isFakeFragments()
+    {
+        return _fragmentFrames;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param fakeFragments True if fake fragments should be created for frames larger than the buffer.
+     */
+    public void setFakeFragments(boolean fakeFragments)
+    {
+        _fragmentFrames = fakeFragments;
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isBufferEmpty()
+    {
+        return _buffer==null || _buffer.length()==0;
+    }
+
+    /* ------------------------------------------------------------ */
+    public Buffer getBuffer()
+    {
+        return _buffer;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Parse to next event.
+     * Parse to the next {@link WebSocketParser.FrameHandler} event or until no more data is
+     * available. Fill data from the {@link EndPoint} only as necessary.
+     * @return An indication of progress or otherwise. -1 indicates EOF, 0 indicates
+     * that no bytes were read and no messages parsed. A positive number indicates either
+     * the bytes filled or the messages parsed.
+     */
+    public int parseNext()
+    {
+        if (_buffer==null)
+            _buffer=_buffers.getBuffer();
+
+        boolean progress=false;
+        int filled=-1;
+
+        // Loop until a datagram call back or can't fill anymore
+        while(!progress && (!_endp.isInputShutdown()||_buffer.length()>0))
+        {
+            int available=_buffer.length();
+
+            // Fill buffer if we need a byte or need length
+            while (available<(_state==State.SKIP?1:_bytesNeeded))
+            {
+                // compact to mark (set at start of data)
+                _buffer.compact();
+
+                // if no space, then the data is too big for buffer
+                if (_buffer.space() == 0)
+                {
+                    // Can we send a fake frame?
+                    if (_fragmentFrames && _state==State.DATA)
+                    {
+                        Buffer data =_buffer.get(4*(available/4));
+                        _buffer.compact();
+                        if (_masked)
+                        {
+                            if (data.array()==null)
+                                data=_buffer.asMutableBuffer();
+                            byte[] array = data.array();
+                            final int end=data.putIndex();
+                            for (int i=data.getIndex();i<end;i++)
+                                array[i]^=_mask[_m++%4];
+                        }
+
+                        // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length());
+                        _bytesNeeded-=data.length();
+                        progress=true;
+                        _handler.onFrame((byte)(_flags&(0xff^WebSocketConnectionRFC6455.FLAG_FIN)), _opcode, data);
+
+                        _opcode=WebSocketConnectionRFC6455.OP_CONTINUATION;
+                    }
+
+                    if (_buffer.space() == 0)
+                        throw new IllegalStateException("FULL: "+_state+" "+_bytesNeeded+">"+_buffer.capacity());
+                }
+
+                // catch IOExceptions (probably EOF) and try to parse what we have
+                try
+                {
+                    filled=_endp.isInputShutdown()?-1:_endp.fill(_buffer);
+                    available=_buffer.length();
+                    // System.err.printf(">> filled %d/%d%n",filled,available);
+                    if (filled<=0)
+                        break;
+                }
+                catch(IOException e)
+                {
+                    LOG.debug(e);
+                    filled=-1;
+                    break;
+                }
+            }
+            // Did we get enough?
+            if (available<(_state==State.SKIP?1:_bytesNeeded))
+                break;
+
+            // if we are here, then we have sufficient bytes to process the current state.
+            // Parse the buffer byte by byte (unless it is STATE_DATA)
+            byte b;
+            while (_state!=State.DATA && available>=(_state==State.SKIP?1:_bytesNeeded))
+            {
+                switch (_state)
+                {
+                    case START:
+                        _skip=false;
+                        _state=_opcode==WebSocketConnectionRFC6455.OP_CLOSE?State.SEEK_EOF:State.OPCODE;
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case OPCODE:
+                        b=_buffer.get();
+                        available--;
+                        _opcode=(byte)(b&0xf);
+                        _flags=(byte)(0xf&(b>>4));
+
+                        if (WebSocketConnectionRFC6455.isControlFrame(_opcode)&&!WebSocketConnectionRFC6455.isLastFrame(_flags))
+                        {
+                            LOG.warn("Fragmented Control from "+_endp);
+                            _handler.close(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Fragmented control");
+                            progress=true;
+                            _skip=true;
+                        }
+
+                        _state=State.LENGTH_7;
+                        _bytesNeeded=_state.getNeeds();
+
+                        continue;
+
+                    case LENGTH_7:
+                        b=_buffer.get();
+                        available--;
+                        _masked=(b&0x80)!=0;
+                        b=(byte)(0x7f&b);
+
+                        switch(b)
+                        {
+                            case 0x7f:
+                                _length=0;
+                                _state=State.LENGTH_63;
+                                break;
+                            case 0x7e:
+                                _length=0;
+                                _state=State.LENGTH_16;
+                                break;
+                            default:
+                                _length=(0x7f&b);
+                                _state=_masked?State.MASK:State.PAYLOAD;
+                        }
+                        _bytesNeeded=_state.getNeeds();
+                        continue;
+
+                    case LENGTH_16:
+                        b=_buffer.get();
+                        available--;
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            if (_length>_buffer.capacity() && !_fragmentFrames)
+                            {
+                                progress=true;
+                                _handler.close(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"frame size "+_length+">"+_buffer.capacity());
+                                _skip=true;
+                            }
+
+                            _state=_masked?State.MASK:State.PAYLOAD;
+                            _bytesNeeded=_state.getNeeds();
+                        }
+                        continue;
+
+                    case LENGTH_63:
+                        b=_buffer.get();
+                        available--;
+                        _length = _length*0x100 + (0xff&b);
+                        if (--_bytesNeeded==0)
+                        {
+                            _bytesNeeded=(int)_length;
+                            if (_length>=_buffer.capacity() && !_fragmentFrames)
+                            {
+                                progress=true;
+                                _handler.close(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"frame size "+_length+">"+_buffer.capacity());
+                                _skip=true;
+                            }
+
+                            _state=_masked?State.MASK:State.PAYLOAD;
+                            _bytesNeeded=_state.getNeeds();
+                        }
+                        continue;
+
+                    case MASK:
+                        _buffer.get(_mask,0,4);
+                        _m=0;
+                        available-=4;
+                        _state=State.PAYLOAD;
+                        _bytesNeeded=_state.getNeeds();
+                        break;
+
+                    case PAYLOAD:
+                        _bytesNeeded=(int)_length;
+                        _state=_skip?State.SKIP:State.DATA;
+                        break;
+
+                    case DATA:
+                        break;
+
+                    case SKIP:
+                        int skip=Math.min(available,_bytesNeeded);
+                        progress=true;
+                        _buffer.skip(skip);
+                        available-=skip;
+                        _bytesNeeded-=skip;
+                        if (_bytesNeeded==0)
+                            _state=State.START;
+                        break;
+
+                    case SEEK_EOF:
+                        progress=true;
+                        _buffer.skip(available);
+                        available=0;
+                        break;
+                }
+            }
+
+            if (_state==State.DATA && available>=_bytesNeeded)
+            {
+                if ( _masked!=_shouldBeMasked)
+                {
+                    _buffer.skip(_bytesNeeded);
+                    _state=State.START;
+                    progress=true;
+                    _handler.close(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Not masked");
+                }
+                else
+                {
+                    Buffer data =_buffer.get(_bytesNeeded);
+                    if (_masked)
+                    {
+                        if (data.array()==null)
+                            data=_buffer.asMutableBuffer();
+                        byte[] array = data.array();
+                        final int end=data.putIndex();
+                        for (int i=data.getIndex();i<end;i++)
+                            array[i]^=_mask[_m++%4];
+                    }
+
+                    // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length());
+
+                    progress=true;
+                    _handler.onFrame(_flags, _opcode, data);
+                    _bytesNeeded=0;
+                    _state=State.START;
+                }
+
+                break;
+            }
+        }
+
+        return progress?1:filled;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void fill(Buffer buffer)
+    {
+        if (buffer!=null && buffer.length()>0)
+        {
+            if (_buffer==null)
+                _buffer=_buffers.getBuffer();
+
+            _buffer.put(buffer);
+            buffer.clear();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public void returnBuffer()
+    {
+        if (_buffer!=null && _buffer.length()==0)
+        {
+            _buffers.returnBuffer(_buffer);
+            _buffer=null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public String toString()
+    {
+        return String.format("%s@%x state=%s buffer=%s",
+                getClass().getSimpleName(),
+                hashCode(),
+                _state,
+                _buffer);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServlet.java b/src/java/org/eclipse/jetty/websocket/WebSocketServlet.java
new file mode 100644
index 0000000..71c2e2f
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServlet.java
@@ -0,0 +1,128 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/* ------------------------------------------------------------ */
+/**
+ * Servlet to upgrade connections to WebSocket
+ * <p/>
+ * The request must have the correct upgrade headers, else it is
+ * handled as a normal servlet request.
+ * <p/>
+ * The initParameter "bufferSize" can be used to set the buffer size,
+ * which is also the max frame byte size (default 8192).
+ * <p/>
+ * The initParameter "maxIdleTime" can be used to set the time in ms
+ * that a websocket may be idle before closing. (default is 300000)
+ * <p/>
+ * The initParameter "maxTextMessageSize" can be used to set the size in characters
+ * that a websocket may be accept before closing. (Default is 16768)
+ * <p/>
+ * The initParameter "maxBinaryMessageSize" can be used to set the size in bytes
+ * that a websocket may be accept before closing. (Default is -1 - or unlimited)
+ * <p/>
+ * The initParameter "minVersion" can be used to set the minimum protocol version
+ * accepted. (Default 13 - the RFC6455 version)
+ */
+@SuppressWarnings("serial")
+public abstract class WebSocketServlet extends HttpServlet implements WebSocketFactory.Acceptor
+{
+    private final Logger LOG = Log.getLogger(getClass());
+    private WebSocketFactory _webSocketFactory;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.GenericServlet#init()
+     */
+    @Override
+    public void init() throws ServletException
+    {
+        try
+        {
+            String bs = getInitParameter("bufferSize");
+            _webSocketFactory = new WebSocketFactory(this, bs == null ? 8192 : Integer.parseInt(bs));
+            _webSocketFactory.start();
+
+            String max = getInitParameter("maxIdleTime");
+            if (max != null)
+                _webSocketFactory.setMaxIdleTime(Integer.parseInt(max));
+
+            max = getInitParameter("maxTextMessageSize");
+            if (max != null)
+                _webSocketFactory.setMaxTextMessageSize(Integer.parseInt(max));
+
+            max = getInitParameter("maxBinaryMessageSize");
+            if (max != null)
+                _webSocketFactory.setMaxBinaryMessageSize(Integer.parseInt(max));
+            
+            String min = getInitParameter("minVersion");
+            if (min != null)
+                _webSocketFactory.setMinVersion(Integer.parseInt(min));
+        }
+        catch (ServletException x)
+        {
+            throw x;
+        }
+        catch (Exception x)
+        {
+            throw new ServletException(x);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+    {
+        if (_webSocketFactory.acceptWebSocket(request, response) || response.isCommitted())
+            return;
+        super.service(request, response);
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean checkOrigin(HttpServletRequest request, String origin)
+    {
+        return true;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void destroy()
+    {
+        try
+        {
+            _webSocketFactory.stop();
+        }
+        catch (Exception x)
+        {
+            LOG.ignore(x);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServletConnection.java b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnection.java
new file mode 100644
index 0000000..56425b3
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnection.java
@@ -0,0 +1,28 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public interface WebSocketServletConnection extends WebSocketConnection
+{
+    void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException;
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD00.java b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD00.java
new file mode 100644
index 0000000..9e98940
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD00.java
@@ -0,0 +1,105 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.QuotedStringTokenizer;
+
+public class WebSocketServletConnectionD00 extends WebSocketConnectionD00 implements WebSocketServletConnection
+{
+    private final WebSocketFactory factory;
+
+    public WebSocketServletConnectionD00(WebSocketFactory factory, WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol)
+            throws IOException
+    {
+        super(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol);
+        this.factory = factory;
+    }
+
+    public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
+    {
+        String uri = request.getRequestURI();
+        String query = request.getQueryString();
+        if (query != null && query.length() > 0)
+        {
+            uri += "?" + query;
+        }
+        uri = new HttpURI(uri).toString();
+        String host = request.getHeader("Host");
+
+        String origin = request.getHeader("Sec-WebSocket-Origin");
+        if (origin == null)
+        {
+            origin = request.getHeader("Origin");
+        }
+        if (origin != null)
+        {
+            origin = QuotedStringTokenizer.quoteIfNeeded(origin,"\r\n");
+        }
+
+        String key1 = request.getHeader("Sec-WebSocket-Key1");
+
+        if (key1 != null)
+        {
+            String key2 = request.getHeader("Sec-WebSocket-Key2");
+            setHixieKeys(key1,key2);
+
+            response.setHeader("Upgrade","WebSocket");
+            response.addHeader("Connection","Upgrade");
+            if (origin != null)
+            {
+                response.addHeader("Sec-WebSocket-Origin",origin);
+            }
+            response.addHeader("Sec-WebSocket-Location",(request.isSecure()?"wss://":"ws://") + host + uri);
+            if (subprotocol != null)
+            {
+                response.addHeader("Sec-WebSocket-Protocol",subprotocol);
+            }
+            response.sendError(101, "WebSocket Protocol Handshake");
+        }
+        else
+        {
+            response.setHeader("Upgrade","WebSocket");
+            response.addHeader("Connection","Upgrade");
+            response.addHeader("WebSocket-Origin",origin);
+            response.addHeader("WebSocket-Location",(request.isSecure()?"wss://":"ws://") + host + uri);
+            if (subprotocol != null)
+            {
+                response.addHeader("WebSocket-Protocol",subprotocol);
+            }
+            response.sendError(101,"Web Socket Protocol Handshake");
+            response.flushBuffer();
+
+            onFrameHandshake();
+            onWebsocketOpen();
+        }
+    }
+
+    @Override
+    public void onClose()
+    {
+        super.onClose();
+        factory.removeConnection(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD06.java b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD06.java
new file mode 100644
index 0000000..65578b9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD06.java
@@ -0,0 +1,63 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.io.EndPoint;
+
+public class WebSocketServletConnectionD06 extends WebSocketConnectionD06 implements WebSocketServletConnection
+{
+    private final WebSocketFactory factory;
+
+    public WebSocketServletConnectionD06(WebSocketFactory factory, WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol)
+            throws IOException
+    {
+        super(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol);
+        this.factory = factory;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
+    {
+        String key = request.getHeader("Sec-WebSocket-Key");
+
+        response.setHeader("Upgrade","WebSocket");
+        response.addHeader("Connection","Upgrade");
+        response.addHeader("Sec-WebSocket-Accept",hashKey(key));
+        if (subprotocol!=null)
+        {
+            response.addHeader("Sec-WebSocket-Protocol",subprotocol);
+        }
+
+        response.sendError(101);
+
+        onFrameHandshake();
+        onWebSocketOpen();
+    }
+
+    @Override
+    public void onClose()
+    {
+        super.onClose();
+        factory.removeConnection(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD08.java b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD08.java
new file mode 100644
index 0000000..8c0a14b
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionD08.java
@@ -0,0 +1,69 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.io.EndPoint;
+
+public class WebSocketServletConnectionD08 extends WebSocketConnectionD08 implements WebSocketServletConnection
+{
+    private final WebSocketFactory factory;
+
+    public WebSocketServletConnectionD08(WebSocketFactory factory, WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol,
+            List<Extension> extensions, int draft) throws IOException
+    {
+        super(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol,extensions,draft);
+        this.factory = factory;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
+    {
+        String key = request.getHeader("Sec-WebSocket-Key");
+
+        response.setHeader("Upgrade","WebSocket");
+        response.addHeader("Connection","Upgrade");
+        response.addHeader("Sec-WebSocket-Accept",hashKey(key));
+        if (subprotocol != null)
+        {
+            response.addHeader("Sec-WebSocket-Protocol",subprotocol);
+        }
+
+        for (Extension ext : getExtensions())
+        {
+            response.addHeader("Sec-WebSocket-Extensions",ext.getParameterizedName());
+        }
+
+        response.sendError(101);
+
+        onFrameHandshake();
+        onWebSocketOpen();
+    }
+
+    @Override
+    public void onClose()
+    {
+        super.onClose();
+        factory.removeConnection(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionRFC6455.java b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionRFC6455.java
new file mode 100644
index 0000000..4ca1fe9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/WebSocketServletConnectionRFC6455.java
@@ -0,0 +1,69 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+import java.io.IOException;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.io.EndPoint;
+
+public class WebSocketServletConnectionRFC6455 extends WebSocketConnectionRFC6455 implements WebSocketServletConnection
+{
+    private final WebSocketFactory factory;
+
+    public WebSocketServletConnectionRFC6455(WebSocketFactory factory, WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol,
+            List<Extension> extensions, int draft) throws IOException
+    {
+        super(websocket,endpoint,buffers,timestamp,maxIdleTime,protocol,extensions,draft);
+        this.factory = factory;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void handshake(HttpServletRequest request, HttpServletResponse response, String subprotocol) throws IOException
+    {
+        String key = request.getHeader("Sec-WebSocket-Key");
+
+        response.setHeader("Upgrade","WebSocket");
+        response.addHeader("Connection","Upgrade");
+        response.addHeader("Sec-WebSocket-Accept",hashKey(key));
+        if (subprotocol != null)
+        {
+            response.addHeader("Sec-WebSocket-Protocol",subprotocol);
+        }
+
+        for (Extension ext : getExtensions())
+        {
+            response.addHeader("Sec-WebSocket-Extensions",ext.getParameterizedName());
+        }
+
+        response.sendError(101);
+
+        onFrameHandshake();
+        onWebSocketOpen();
+    }
+
+    @Override
+    public void onClose()
+    {
+        super.onClose();
+        factory.removeConnection(this);
+    }
+}
diff --git a/src/java/org/eclipse/jetty/websocket/ZeroMaskGen.java b/src/java/org/eclipse/jetty/websocket/ZeroMaskGen.java
new file mode 100644
index 0000000..dbcd9fd
--- /dev/null
+++ b/src/java/org/eclipse/jetty/websocket/ZeroMaskGen.java
@@ -0,0 +1,28 @@
+//
+//  ========================================================================
+//  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.websocket;
+
+
+public class ZeroMaskGen implements MaskGen
+{
+    public void genMask(byte[] mask)
+    {
+        mask[0]=mask[1]=mask[2]=mask[3]=0;
+    }
+}
diff --git a/src/java/org/eclipse/jetty/xml/ConfigurationProcessor.java b/src/java/org/eclipse/jetty/xml/ConfigurationProcessor.java
new file mode 100644
index 0000000..8b7fe25
--- /dev/null
+++ b/src/java/org/eclipse/jetty/xml/ConfigurationProcessor.java
@@ -0,0 +1,38 @@
+//
+//  ========================================================================
+//  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.xml;
+
+import java.net.URL;
+
+/**
+ * A ConfigurationProcessor for non XmlConfiguration format files.
+ * <p>
+ * A file in non-XmlConfiguration file format may be processed by a {@link ConfigurationProcessor}
+ * instance that is returned from a {@link ConfigurationProcessorFactory} instance discovered by the
+ * <code>ServiceLoader</code> mechanism.  This is used to allow spring configuration files to be used instead of 
+ * jetty.xml
+ *
+ */
+public interface ConfigurationProcessor
+{
+    public void init(URL url, XmlParser.Node root, XmlConfiguration configuration);
+    
+    public Object configure( Object obj) throws Exception;
+    public Object configure() throws Exception;
+}
diff --git a/src/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java b/src/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java
new file mode 100644
index 0000000..fc7476c
--- /dev/null
+++ b/src/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java
@@ -0,0 +1,24 @@
+//
+//  ========================================================================
+//  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.xml;
+
+public interface ConfigurationProcessorFactory
+{
+    ConfigurationProcessor getConfigurationProcessor(String dtd, String tag);
+}
diff --git a/src/java/org/eclipse/jetty/xml/XmlConfiguration.java b/src/java/org/eclipse/jetty/xml/XmlConfiguration.java
new file mode 100644
index 0000000..0526ec9
--- /dev/null
+++ b/src/java/org/eclipse/jetty/xml/XmlConfiguration.java
@@ -0,0 +1,1299 @@
+//
+//  ========================================================================
+//  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.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.util.ArrayQueue;
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.Loader;
+import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.xml.XmlParser.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/* ------------------------------------------------------------ */
+/**
+ * Configure Objects from XML. This class reads an XML file conforming to the configure.dtd DTD and uses it to configure and object by calling set, put or other
+ * methods on the object.
+ *
+ * <p>
+ * The actual XML file format may be changed (eg to spring XML) by implementing the {@link ConfigurationProcessorFactory} interfaces to be found by the
+ * <code>ServiceLoader</code> by using the DTD and first tag element in the file. Note that DTD will be null if validation is off.
+ *
+ */
+public class XmlConfiguration
+{
+    private static final Logger LOG = Log.getLogger(XmlConfiguration.class);
+
+    private static final Class<?>[] __primitives =
+    { Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE };
+
+    private static final Class<?>[] __primitiveHolders =
+    { Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class };
+
+    private static final Class<?>[] __supportedCollections =
+    { ArrayList.class,ArrayQueue.class,HashSet.class,Queue.class,List.class,Set.class,Collection.class,};
+
+    private static final Iterable<?> __factoryLoader;
+
+    private static final XmlParser __parser = initParser();
+
+    static
+    {
+        Iterable<?> loader=null;
+        try
+        {
+            // Use reflection to look up 1.6 service loader
+            // loader=ServiceLoader.load(ConfigurationProcessorFactory.class);
+            Class<?> slc = ClassLoader.getSystemClassLoader().loadClass("java.util.ServiceLoader");
+            Method load = slc.getMethod("load",Class.class);
+            loader=(Iterable<?>)load.invoke(null,ConfigurationProcessorFactory.class);
+        }
+        catch(Exception e)
+        {
+            LOG.ignore(e);
+        }
+        finally
+        {
+            __factoryLoader=loader;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private URL _url;
+    private String _dtd;
+    private ConfigurationProcessor _processor;
+    private final Map<String, Object> _idMap = new HashMap<String, Object>();
+    private final Map<String, String> _propertyMap = new HashMap<String, String>();
+
+    /* ------------------------------------------------------------ */
+    private synchronized static XmlParser initParser()
+    {
+        XmlParser parser = new XmlParser();
+        URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true);
+        URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true);
+        parser.redirectEntity("configure.dtd",config76);
+        parser.redirectEntity("configure_1_0.dtd",config60);
+        parser.redirectEntity("configure_1_1.dtd",config60);
+        parser.redirectEntity("configure_1_2.dtd",config60);
+        parser.redirectEntity("configure_1_3.dtd",config60);
+        parser.redirectEntity("configure_6_0.dtd",config60);
+        parser.redirectEntity("configure_7_6.dtd",config76);
+
+        parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config76);
+        parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config76);
+        parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config76);
+
+        parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config76);
+        parser.redirectEntity("-//Jetty//Configure//EN",config76);
+
+        return parser;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Reads and parses the XML configuration file.
+     *
+     * @param configuration the URL of the XML configuration
+     * @throws IOException if the configuration could not be read
+     * @throws SAXException if the configuration could not be parsed
+     */
+    public XmlConfiguration(URL configuration) throws SAXException, IOException
+    {
+        synchronized (__parser)
+        {
+            _url=configuration;
+            setConfig(__parser.parse(configuration.toString()));
+            _dtd=__parser.getDTD();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Reads and parses the XML configuration string.
+     *
+     * @param configuration String of XML configuration commands excluding the normal XML preamble.
+     * The String should start with a "&lt;Configure ....&gt;" element.
+     * @throws IOException if the configuration could not be read
+     * @throws SAXException if the configuration could not be parsed
+     */
+    public XmlConfiguration(String configuration) throws SAXException, IOException
+    {
+        configuration = "<?xml version=\"1.0\"  encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Mort Bay Consulting//DTD Configure 1.2//EN\" \"http://jetty.eclipse.org/configure_1_2.dtd\">"
+                + configuration;
+        InputSource source = new InputSource(new StringReader(configuration));
+        synchronized (__parser)
+        {
+            setConfig( __parser.parse(source));
+            _dtd=__parser.getDTD();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Reads and parses the XML configuration stream.
+     *
+     * @param configuration An input stream containing a complete configuration file
+     * @throws IOException if the configuration could not be read
+     * @throws SAXException if the configuration could not be parsed
+     */
+    public XmlConfiguration(InputStream configuration) throws SAXException, IOException
+    {
+        InputSource source = new InputSource(configuration);
+        synchronized (__parser)
+        {
+            setConfig(__parser.parse(source));
+            _dtd=__parser.getDTD();
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void setConfig(XmlParser.Node config)
+    {
+        if ("Configure".equals(config.getTag()))
+        {
+            _processor=new JettyXmlConfiguration();
+        }
+        else if (__factoryLoader!=null)
+        {
+            for ( Object factory : __factoryLoader)
+            {
+                // use reflection to get 1.6 methods
+                Method gcp;
+                try
+                {
+                    gcp = factory.getClass().getMethod("getConfigurationProcessor",String.class,String.class);
+                    _processor = (ConfigurationProcessor) gcp.invoke(factory,_dtd,config.getTag());
+                }
+                catch (Exception e)
+                {
+                    LOG.warn(e);
+                }
+                if (_processor!=null)
+                    break;
+            }
+
+            if (_processor==null)
+                throw new IllegalStateException("Unknown configuration type: "+config.getTag()+" in "+this);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Unknown XML tag:"+config.getTag());
+        }
+        _processor.init(_url,config,this);
+    }
+
+
+    /* ------------------------------------------------------------ */
+    public Map<String, Object> getIdMap()
+    {
+        return _idMap;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param map the ID map
+     * @deprecated use {@link #getIdMap()}.put(...)
+     */
+    @Deprecated
+    public void setIdMap(Map<String, Object> map)
+    {
+        _idMap.clear();
+        _idMap.putAll(map);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @param map the properties map
+     * @deprecated use {@link #getProperties()}.putAll(...)
+     */
+    @Deprecated
+    public void setProperties(Map<String, String> map)
+    {
+        _propertyMap.clear();
+        _propertyMap.putAll(map);
+    }
+
+    /* ------------------------------------------------------------ */
+    public Map<String, String> getProperties()
+    {
+        return _propertyMap;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Applies the XML configuration script to the given object.
+     *
+     * @param obj The object to be configured, which must be of a type or super type
+     * of the class attribute of the &lt;Configure&gt; element.
+     * @throws Exception if the configuration fails
+     * @return the configured object
+     */
+    public Object configure(Object obj) throws Exception
+    {
+        return _processor.configure(obj);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Applies the XML configuration script.
+     * If the root element of the configuration has an ID, an object is looked up by ID and its type checked
+     * against the root element's type.
+     * Otherwise a new object of the type specified by the root element is created.
+     *
+     * @return The newly created configured object.
+     * @throws Exception if the configuration fails
+     */
+    public Object configure() throws Exception
+    {
+        return _processor.configure();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Initialize a new Object defaults.
+     * <p>This method must be called by any {@link ConfigurationProcessor} when it 
+     * creates a new instance of an object before configuring it, so that a derived 
+     * XmlConfiguration class may inject default values.
+     * @param object
+     */
+    public void initializeDefaults(Object object)
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private static class JettyXmlConfiguration implements ConfigurationProcessor
+    {
+        XmlParser.Node _root;
+        XmlConfiguration _configuration;
+
+        public void init(URL url, XmlParser.Node root, XmlConfiguration configuration)
+        {
+            _root=root;
+            _configuration=configuration;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Object configure(Object obj) throws Exception
+        {
+            // Check the class of the object
+            Class<?> oClass = nodeClass(_root);
+            if (oClass != null && !oClass.isInstance(obj))
+            {
+                String loaders = (oClass.getClassLoader()==obj.getClass().getClassLoader())?"":"Object Class and type Class are from different loaders.";
+                throw new IllegalArgumentException("Object of class '"+obj.getClass().getCanonicalName()+"' is not of type '" + oClass.getCanonicalName()+"'. "+loaders);
+            }
+            configure(obj,_root,0);
+            return obj;
+        }
+
+        /* ------------------------------------------------------------ */
+        public Object configure() throws Exception
+        {
+            Class<?> oClass = nodeClass(_root);
+
+            String id = _root.getAttribute("id");
+            Object obj = id == null?null:_configuration.getIdMap().get(id);
+
+            if (obj == null && oClass != null)
+            {
+                obj = oClass.newInstance();
+                _configuration.initializeDefaults(obj);
+            }
+
+            if (oClass != null && !oClass.isInstance(obj))
+                throw new ClassCastException(oClass.toString());
+
+            configure(obj,_root,0);
+            return obj;
+        }
+
+        /* ------------------------------------------------------------ */
+        private static Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException
+        {
+            String className = node.getAttribute("class");
+            if (className == null)
+                return null;
+
+            return Loader.loadClass(XmlConfiguration.class,className,true);
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Recursive configuration routine.
+         * This method applies the nested Set, Put, Call, etc. elements to the given object.
+         *
+         * @param obj the object to configure
+         * @param cfg the XML nodes of the configuration
+         * @param i the index of the XML nodes
+         * @throws Exception if the configuration fails
+         */
+        public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception
+        {
+            String id = cfg.getAttribute("id");
+            if (id != null)
+                _configuration.getIdMap().put(id,obj);
+
+            for (; i < cfg.size(); i++)
+            {
+                Object o = cfg.get(i);
+                if (o instanceof String)
+                    continue;
+                XmlParser.Node node = (XmlParser.Node)o;
+
+                try
+                {
+                    String tag = node.getTag();
+                    if ("Set".equals(tag))
+                        set(obj,node);
+                    else if ("Put".equals(tag))
+                        put(obj,node);
+                    else if ("Call".equals(tag))
+                        call(obj,node);
+                    else if ("Get".equals(tag))
+                        get(obj,node);
+                    else if ("New".equals(tag))
+                        newObj(obj,node);
+                    else if ("Array".equals(tag))
+                        newArray(obj,node);
+                    else if ("Ref".equals(tag))
+                        refObj(obj,node);
+                    else if ("Property".equals(tag))
+                        propertyObj(node);
+                    else
+                        throw new IllegalStateException("Unknown tag: " + tag);
+                }
+                catch (Exception e)
+                {
+                    LOG.warn("Config error at " + node,e.toString());
+                    throw e;
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Call a set method. This method makes a best effort to find a matching set method. The type of the value is used to find a suitable set method by 1.
+         * Trying for a trivial type match. 2. Looking for a native type match. 3. Trying all correctly named methods for an auto conversion. 4. Attempting to
+         * construct a suitable value from original value. @param obj
+         *
+         * @param node
+         */
+        private void set(Object obj, XmlParser.Node node) throws Exception
+        {
+            String attr = node.getAttribute("name");
+            String name = "set" + attr.substring(0,1).toUpperCase(Locale.ENGLISH) + attr.substring(1);
+            Object value = value(obj,node);
+            Object[] arg =
+            { value };
+
+            Class<?> oClass = nodeClass(node);
+            if (oClass != null)
+                obj = null;
+            else
+                oClass = obj.getClass();
+
+            Class<?>[] vClass =
+            { Object.class };
+            if (value != null)
+                vClass[0] = value.getClass();
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("XML " + (obj != null?obj.toString():oClass.getName()) + "." + name + "(" + value + ")");
+
+            // Try for trivial match
+            try
+            {
+                Method set = oClass.getMethod(name,vClass);
+                set.invoke(obj,arg);
+                return;
+            }
+            catch (IllegalArgumentException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (NoSuchMethodException e)
+            {
+                LOG.ignore(e);
+            }
+
+            // Try for native match
+            try
+            {
+                Field type = vClass[0].getField("TYPE");
+                vClass[0] = (Class<?>)type.get(null);
+                Method set = oClass.getMethod(name,vClass);
+                set.invoke(obj,arg);
+                return;
+            }
+            catch (NoSuchFieldException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (IllegalArgumentException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (IllegalAccessException e)
+            {
+                LOG.ignore(e);
+            }
+            catch (NoSuchMethodException e)
+            {
+                LOG.ignore(e);
+            }
+
+            // Try a field
+            try
+            {
+                Field field = oClass.getField(attr);
+                if (Modifier.isPublic(field.getModifiers()))
+                {
+                    field.set(obj,value);
+                    return;
+                }
+            }
+            catch (NoSuchFieldException e)
+            {
+                LOG.ignore(e);
+            }
+
+            // Search for a match by trying all the set methods
+            Method[] sets = oClass.getMethods();
+            Method set = null;
+            for (int s = 0; sets != null && s < sets.length; s++)
+            {
+                Class<?>[] paramTypes = sets[s].getParameterTypes();
+                if (name.equals(sets[s].getName()) && paramTypes.length == 1)
+                {
+
+                    // lets try it
+                    try
+                    {
+                        set = sets[s];
+                        sets[s].invoke(obj,arg);
+                        return;
+                    }
+                    catch (IllegalArgumentException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        LOG.ignore(e);
+                    }
+
+                    try
+                    {
+                        for (Class<?> c : __supportedCollections)
+                            if (paramTypes[0].isAssignableFrom(c))
+                            {
+                                sets[s].invoke(obj,convertArrayToCollection(value,c));
+                                return;
+                            }
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                }
+            }
+
+            // Try converting the arg to the last set found.
+            if (set != null)
+            {
+                try
+                {
+                    Class<?> sClass = set.getParameterTypes()[0];
+                    if (sClass.isPrimitive())
+                    {
+                        for (int t = 0; t < __primitives.length; t++)
+                        {
+                            if (sClass.equals(__primitives[t]))
+                            {
+                                sClass = __primitiveHolders[t];
+                                break;
+                            }
+                        }
+                    }
+                    Constructor<?> cons = sClass.getConstructor(vClass);
+                    arg[0] = cons.newInstance(arg);
+                    _configuration.initializeDefaults(arg[0]);
+                    set.invoke(obj,arg);
+                    return;
+                }
+                catch (NoSuchMethodException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (IllegalAccessException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (InstantiationException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+
+            // No Joy
+            throw new NoSuchMethodException(oClass + "." + name + "(" + vClass[0] + ")");
+        }
+
+        /**
+         * @param array the array to convert
+         * @param collectionType the desired collection type
+         * @return a collection of the desired type if the array can be converted
+         */
+        private static Collection<?> convertArrayToCollection(Object array, Class<?> collectionType)
+        {
+            Collection<?> collection = null;
+            if (array.getClass().isArray())
+            {
+                if (collectionType.isAssignableFrom(ArrayList.class))
+                    collection = convertArrayToArrayList(array);
+                else if (collectionType.isAssignableFrom(HashSet.class))
+                    collection = new HashSet<Object>(convertArrayToArrayList(array));
+                else if (collectionType.isAssignableFrom(ArrayQueue.class))
+                {
+                    ArrayQueue<Object> q= new ArrayQueue<Object>();
+                    q.addAll(convertArrayToArrayList(array));
+                    collection=q;
+                }
+            }
+            if (collection==null)
+                throw new IllegalArgumentException("Can't convert \"" + array.getClass() + "\" to " + collectionType);
+            return collection;
+        }
+
+        /* ------------------------------------------------------------ */
+        private static ArrayList<Object> convertArrayToArrayList(Object array)
+        {
+            int length = Array.getLength(array);
+            ArrayList<Object> list = new ArrayList<Object>(length);
+            for (int i = 0; i < length; i++)
+                list.add(Array.get(array,i));
+            return list;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Call a put method.
+         *
+         * @param obj @param node
+         */
+        private void put(Object obj, XmlParser.Node node) throws Exception
+        {
+            if (!(obj instanceof Map))
+                throw new IllegalArgumentException("Object for put is not a Map: " + obj);
+            @SuppressWarnings("unchecked")
+            Map<Object, Object> map = (Map<Object, Object>)obj;
+
+            String name = node.getAttribute("name");
+            Object value = value(obj,node);
+            map.put(name,value);
+            if (LOG.isDebugEnabled())
+                LOG.debug("XML " + obj + ".put(" + name + "," + value + ")");
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Call a get method. Any object returned from the call is passed to the configure method to consume the remaining elements. @param obj @param node
+         *
+         * @return @exception Exception
+         */
+        private Object get(Object obj, XmlParser.Node node) throws Exception
+        {
+            Class<?> oClass = nodeClass(node);
+            if (oClass != null)
+                obj = null;
+            else
+                oClass = obj.getClass();
+
+            String name = node.getAttribute("name");
+            String id = node.getAttribute("id");
+            if (LOG.isDebugEnabled())
+                LOG.debug("XML get " + name);
+
+            try
+            {
+                // try calling a getXxx method.
+                Method method = oClass.getMethod("get" + name.substring(0,1).toUpperCase(Locale.ENGLISH) + name.substring(1),(java.lang.Class[])null);
+                obj = method.invoke(obj,(java.lang.Object[])null);
+                configure(obj,node,0);
+            }
+            catch (NoSuchMethodException nsme)
+            {
+                try
+                {
+                    Field field = oClass.getField(name);
+                    obj = field.get(obj);
+                    configure(obj,node,0);
+                }
+                catch (NoSuchFieldException nsfe)
+                {
+                    throw nsme;
+                }
+            }
+            if (id != null)
+                _configuration.getIdMap().put(id,obj);
+            return obj;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Call a method. A method is selected by trying all methods with matching names and number of arguments. Any object returned from the call is passed to
+         * the configure method to consume the remaining elements. Note that if this is a static call we consider only methods declared directly in the given
+         * class. i.e. we ignore any static methods in superclasses. @param obj
+         *
+         * @param node @return @exception Exception
+         */
+        private Object call(Object obj, XmlParser.Node node) throws Exception
+        {
+            String id = node.getAttribute("id");
+            Class<?> oClass = nodeClass(node);
+            if (oClass != null)
+                obj = null;
+            else if (obj != null)
+                oClass = obj.getClass();
+            if (oClass == null)
+                throw new IllegalArgumentException(node.toString());
+
+            int size = 0;
+            int argi = node.size();
+            for (int i = 0; i < node.size(); i++)
+            {
+                Object o = node.get(i);
+                if (o instanceof String)
+                    continue;
+                if (!((XmlParser.Node)o).getTag().equals("Arg"))
+                {
+                    argi = i;
+                    break;
+                }
+                size++;
+            }
+
+            Object[] arg = new Object[size];
+            for (int i = 0, j = 0; j < size; i++)
+            {
+                Object o = node.get(i);
+                if (o instanceof String)
+                    continue;
+                arg[j++] = value(obj,(XmlParser.Node)o);
+            }
+
+            String method = node.getAttribute("name");
+            if (LOG.isDebugEnabled())
+                LOG.debug("XML call " + method);
+
+            try
+            {
+                Object n= TypeUtil.call(oClass,method,obj,arg);
+                if (id != null)
+                    _configuration.getIdMap().put(id,n);
+                configure(n,node,argi);
+                return n;
+            }
+            catch (NoSuchMethodException e)
+            {
+                IllegalStateException ise = new IllegalStateException("No Method: " + node + " on " + oClass);
+                ise.initCause(e);
+                throw ise;
+            }
+
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Create a new value object.
+         *
+         * @param obj @param node @return @exception Exception
+         */
+        private Object newObj(Object obj, XmlParser.Node node) throws Exception
+        {
+            Class<?> oClass = nodeClass(node);
+            String id = node.getAttribute("id");
+            int size = 0;
+            int argi = node.size();
+            for (int i = 0; i < node.size(); i++)
+            {
+                Object o = node.get(i);
+                if (o instanceof String)
+                    continue;
+                if (!((XmlParser.Node)o).getTag().equals("Arg"))
+                {
+                    argi = i;
+                    break;
+                }
+                size++;
+            }
+
+            Object[] arg = new Object[size];
+            for (int i = 0, j = 0; j < size; i++)
+            {
+                Object o = node.get(i);
+                if (o instanceof String)
+                    continue;
+                arg[j++] = value(obj,(XmlParser.Node)o);
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("XML new " + oClass);
+
+            // Lets just try all constructors for now
+            Constructor<?>[] constructors = oClass.getConstructors();
+            for (int c = 0; constructors != null && c < constructors.length; c++)
+            {
+                if (constructors[c].getParameterTypes().length != size)
+                    continue;
+
+                Object n = null;
+                boolean called = false;
+                try
+                {
+                    n = constructors[c].newInstance(arg);
+                    _configuration.initializeDefaults(n);
+                    called = true;
+                }
+                catch (IllegalAccessException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (InstantiationException e)
+                {
+                    LOG.ignore(e);
+                }
+                catch (IllegalArgumentException e)
+                {
+                    LOG.ignore(e);
+                }
+                if (called)
+                {
+                    if (id != null)
+                        _configuration.getIdMap().put(id,n);
+                    configure(n,node,argi);
+                    return n;
+                }
+            }
+
+            throw new IllegalStateException("No Constructor: " + node + " on " + obj);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Reference an id value object.
+         *
+         * @param obj @param node @return @exception NoSuchMethodException @exception ClassNotFoundException @exception InvocationTargetException
+         */
+        private Object refObj(Object obj, XmlParser.Node node) throws Exception
+        {
+            String id = node.getAttribute("id");
+            obj = _configuration.getIdMap().get(id);
+            if (obj == null)
+                throw new IllegalStateException("No object for id=" + id);
+            configure(obj,node,0);
+            return obj;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Create a new array object.
+         */
+        private Object newArray(Object obj, XmlParser.Node node) throws Exception
+        {
+
+            // Get the type
+            Class<?> aClass = java.lang.Object.class;
+            String type = node.getAttribute("type");
+            final String id = node.getAttribute("id");
+            if (type != null)
+            {
+                aClass = TypeUtil.fromName(type);
+                if (aClass == null)
+                {
+                    if ("String".equals(type))
+                        aClass = java.lang.String.class;
+                    else if ("URL".equals(type))
+                        aClass = java.net.URL.class;
+                    else if ("InetAddress".equals(type))
+                        aClass = java.net.InetAddress.class;
+                    else
+                        aClass = Loader.loadClass(XmlConfiguration.class,type,true);
+                }
+            }
+
+            Object al = null;
+
+            for (Object nodeObject : node)
+            {
+                XmlParser.Node item = (Node)nodeObject;
+                String nid = item.getAttribute("id");
+                Object v = value(obj,item);
+                al = LazyList.add(al,(v == null && aClass.isPrimitive())?0:v);
+                if (nid != null)
+                    _configuration.getIdMap().put(nid,v);
+            }
+
+            Object array = LazyList.toArray(al,aClass);
+            if (id != null)
+                _configuration.getIdMap().put(id,array);
+            return array;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Create a new map object.
+         */
+        private Object newMap(Object obj, XmlParser.Node node) throws Exception
+        {
+            String id = node.getAttribute("id");
+
+            Map<Object, Object> map = new HashMap<Object, Object>();
+            if (id != null)
+                _configuration.getIdMap().put(id,map);
+
+            for (Object o : node)
+            {
+                if (o instanceof String)
+                    continue;
+                XmlParser.Node entry = (XmlParser.Node)o;
+                if (!entry.getTag().equals("Entry"))
+                    throw new IllegalStateException("Not an Entry");
+
+                XmlParser.Node key = null;
+                XmlParser.Node value = null;
+
+                for (Object object : entry)
+                {
+                    if (object instanceof String)
+                        continue;
+                    XmlParser.Node item = (XmlParser.Node)object;
+                    if (!item.getTag().equals("Item"))
+                        throw new IllegalStateException("Not an Item");
+                    if (key == null)
+                        key = item;
+                    else
+                        value = item;
+                }
+
+                if (key == null || value == null)
+                    throw new IllegalStateException("Missing Item in Entry");
+                String kid = key.getAttribute("id");
+                String vid = value.getAttribute("id");
+
+                Object k = value(obj,key);
+                Object v = value(obj,value);
+                map.put(k,v);
+
+                if (kid != null)
+                    _configuration.getIdMap().put(kid,k);
+                if (vid != null)
+                    _configuration.getIdMap().put(vid,v);
+            }
+
+            return map;
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Get a Property.
+         *
+         * @param node
+         * @return
+         * @exception Exception
+         */
+        private Object propertyObj(XmlParser.Node node) throws Exception
+        {
+            String id = node.getAttribute("id");
+            String name = node.getAttribute("name");
+            String defaultValue = node.getAttribute("default");
+            Object prop;
+            Map<String,String> property_map=_configuration.getProperties();
+            if (property_map != null && property_map.containsKey(name))
+                prop = property_map.get(name);
+            else
+                prop = defaultValue;
+            if (id != null)
+                _configuration.getIdMap().put(id,prop);
+            if (prop != null)
+                configure(prop,node,0);
+            return prop;
+        }
+
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Get the value of an element. If no value type is specified, then white space is trimmed out of the value. If it contains multiple value elements they
+         * are added as strings before being converted to any specified type. @param node
+         */
+        private Object value(Object obj, XmlParser.Node node) throws Exception
+        {
+            Object value;
+
+            // Get the type
+            String type = node.getAttribute("type");
+
+            // Try a ref lookup
+            String ref = node.getAttribute("ref");
+            if (ref != null)
+            {
+                value = _configuration.getIdMap().get(ref);
+            }
+            else
+            {
+                // handle trivial case
+                if (node.size() == 0)
+                {
+                    if ("String".equals(type))
+                        return "";
+                    return null;
+                }
+
+                // Trim values
+                int first = 0;
+                int last = node.size() - 1;
+
+                // Handle default trim type
+                if (type == null || !"String".equals(type))
+                {
+                    // Skip leading white
+                    Object item;
+                    while (first <= last)
+                    {
+                        item = node.get(first);
+                        if (!(item instanceof String))
+                            break;
+                        item = ((String)item).trim();
+                        if (((String)item).length() > 0)
+                            break;
+                        first++;
+                    }
+
+                    // Skip trailing white
+                    while (first < last)
+                    {
+                        item = node.get(last);
+                        if (!(item instanceof String))
+                            break;
+                        item = ((String)item).trim();
+                        if (((String)item).length() > 0)
+                            break;
+                        last--;
+                    }
+
+                    // All white, so return null
+                    if (first > last)
+                        return null;
+                }
+
+                if (first == last)
+                    // Single Item value
+                    value = itemValue(obj,node.get(first));
+                else
+                {
+                    // Get the multiple items as a single string
+                    StringBuilder buf = new StringBuilder();
+                    for (int i = first; i <= last; i++)
+                    {
+                        Object item = node.get(i);
+                        buf.append(itemValue(obj,item));
+                    }
+                    value = buf.toString();
+                }
+            }
+
+            // Untyped or unknown
+            if (value == null)
+            {
+                if ("String".equals(type))
+                    return "";
+                return null;
+            }
+
+            // Try to type the object
+            if (type == null)
+            {
+                if (value instanceof String)
+                    return ((String)value).trim();
+                return value;
+            }
+
+            if (isTypeMatchingClass(type,String.class))
+                return value.toString();
+
+            Class<?> pClass = TypeUtil.fromName(type);
+            if (pClass != null)
+                return TypeUtil.valueOf(pClass,value.toString());
+
+            if (isTypeMatchingClass(type,URL.class))
+            {
+                if (value instanceof URL)
+                    return value;
+                try
+                {
+                    return new URL(value.toString());
+                }
+                catch (MalformedURLException e)
+                {
+                    throw new InvocationTargetException(e);
+                }
+            }
+
+            if (isTypeMatchingClass(type,InetAddress.class))
+            {
+                if (value instanceof InetAddress)
+                    return value;
+                try
+                {
+                    return InetAddress.getByName(value.toString());
+                }
+                catch (UnknownHostException e)
+                {
+                    throw new InvocationTargetException(e);
+                }
+            }
+
+            for (Class<?> collectionClass : __supportedCollections)
+            {
+                if (isTypeMatchingClass(type,collectionClass))
+                    return convertArrayToCollection(value,collectionClass);
+            }
+
+            throw new IllegalStateException("Unknown type " + type);
+        }
+
+        /* ------------------------------------------------------------ */
+        private static boolean isTypeMatchingClass(String type, Class<?> classToMatch)
+        {
+            return classToMatch.getSimpleName().equalsIgnoreCase(type) || classToMatch.getName().equals(type);
+        }
+
+        /* ------------------------------------------------------------ */
+        /*
+         * Get the value of a single element. @param obj @param item @return @exception Exception
+         */
+        private Object itemValue(Object obj, Object item) throws Exception
+        {
+            // String value
+            if (item instanceof String)
+                return item;
+
+            XmlParser.Node node = (XmlParser.Node)item;
+            String tag = node.getTag();
+            if ("Call".equals(tag))
+                return call(obj,node);
+            if ("Get".equals(tag))
+                return get(obj,node);
+            if ("New".equals(tag))
+                return newObj(obj,node);
+            if ("Ref".equals(tag))
+                return refObj(obj,node);
+            if ("Array".equals(tag))
+                return newArray(obj,node);
+            if ("Map".equals(tag))
+                return newMap(obj,node);
+            if ("Property".equals(tag))
+                return propertyObj(node);
+
+            if ("SystemProperty".equals(tag))
+            {
+                String name = node.getAttribute("name");
+                String defaultValue = node.getAttribute("default");
+                return System.getProperty(name,defaultValue);
+            }
+
+            if ("Env".equals(tag))
+            {
+                String name = node.getAttribute("name");
+                String defaultValue = node.getAttribute("default");
+                String value=System.getenv(name);
+                return value==null?defaultValue:value;
+            }
+
+            LOG.warn("Unknown value tag: " + node,new Throwable());
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * Run the XML configurations as a main application. The command line is used to obtain properties files (must be named '*.properties') and XmlConfiguration
+     * files.
+     * <p>
+     * Any property file on the command line is added to a combined Property instance that is passed to each configuration file via
+     * {@link XmlConfiguration#setProperties(Map)}.
+     * <p>
+     * Each configuration file on the command line is used to create a new XmlConfiguration instance and the {@link XmlConfiguration#configure()} method is used
+     * to create the configured object. If the resulting object is an instance of {@link LifeCycle}, then it is started.
+     * <p>
+     * Any IDs created in a configuration are passed to the next configuration file on the command line using {@link #getIdMap()} and {@link #setIdMap(Map)} .
+     * This allows objects with IDs created in one config file to be referenced in subsequent config files on the command line.
+     *
+     * @param args
+     *            array of property and xml configuration filenames or {@link Resource}s.
+     * @throws Exception if the XML configurations cannot be run
+     */
+    public static void main(final String[] args) throws Exception
+    {
+
+        final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
+
+        AccessController.doPrivileged(new PrivilegedAction<Object>()
+        {
+            public Object run()
+            {
+                try
+                {
+
+                    Properties properties = null;
+
+                    // Look for properties from start.jar
+                    try
+                    {
+                        Class<?> config = XmlConfiguration.class.getClassLoader().loadClass("org.eclipse.jetty.start.Config");
+                        properties = (Properties)config.getMethod("getProperties").invoke(null);
+                        LOG.debug("org.eclipse.jetty.start.Config properties = {}",properties);
+                    }
+                    catch (NoClassDefFoundError e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (ClassNotFoundException e)
+                    {
+                        LOG.ignore(e);
+                    }
+                    catch (Exception e)
+                    {
+                        LOG.warn(e);
+                    }
+
+                    // If no start.config properties, use clean slate
+                    if (properties == null)
+                    {
+                        properties = new Properties();
+                        // Add System Properties
+                        Enumeration<?> ensysprop = System.getProperties().propertyNames();
+                        while (ensysprop.hasMoreElements())
+                        {
+                            String name = (String)ensysprop.nextElement();
+                            properties.put(name,System.getProperty(name));
+                        }
+                    }
+
+                    // For all arguments, load properties or parse XMLs
+                    XmlConfiguration last = null;
+                    Object[] obj = new Object[args.length];
+                    for (int i = 0; i < args.length; i++)
+                    {
+                        if (args[i].toLowerCase(Locale.ENGLISH).endsWith(".properties"))
+                        {
+                            properties.load(Resource.newResource(args[i]).getInputStream());
+                        }
+                        else
+                        {
+                            XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
+                            if (last != null)
+                                configuration.getIdMap().putAll(last.getIdMap());
+                            if (properties.size() > 0)
+                            {
+                                Map<String, String> props = new HashMap<String, String>();
+                                for (Object key : properties.keySet())
+                                {
+                                    props.put(key.toString(),String.valueOf(properties.get(key)));
+                                }
+                                configuration.getProperties().putAll(props);
+                            }
+                            obj[i] = configuration.configure();
+                            last = configuration;
+                        }
+                    }
+
+                    // For all objects created by XmlConfigurations, start them if they are lifecycles.
+                    for (int i = 0; i < args.length; i++)
+                    {
+                        if (obj[i] instanceof LifeCycle)
+                        {
+                            LifeCycle lc = (LifeCycle)obj[i];
+                            if (!lc.isRunning())
+                                lc.start();
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    LOG.debug(Log.EXCEPTION,e);
+                    exception.set(e);
+                }
+                return null;
+            }
+        });
+
+        Throwable th = exception.get();
+        if (th != null)
+        {
+            if (th instanceof RuntimeException)
+                throw (RuntimeException)th;
+            else if (th instanceof Exception)
+                throw (Exception)th;
+            else if (th instanceof Error)
+                throw (Error)th;
+            throw new Error(th);
+        }
+    }
+}
diff --git a/src/java/org/eclipse/jetty/xml/XmlParser.java b/src/java/org/eclipse/jetty/xml/XmlParser.java
new file mode 100644
index 0000000..6bf6628
--- /dev/null
+++ b/src/java/org/eclipse/jetty/xml/XmlParser.java
@@ -0,0 +1,820 @@
+//
+//  ========================================================================
+//  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.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.jetty.util.LazyList;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.Resource;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/*--------------------------------------------------------------*/
+/**
+ * XML Parser wrapper. This class wraps any standard JAXP1.1 parser with convieniant error and
+ * entity handlers and a mini dom-like document tree.
+ * <P>
+ * By default, the parser is created as a validating parser only if xerces is present. This can be 
+ * configured by setting the "org.eclipse.jetty.xml.XmlParser.Validating" system property.
+ * 
+ * 
+ */
+public class XmlParser
+{
+    private static final Logger LOG = Log.getLogger(XmlParser.class);
+
+    private Map<String,URL> _redirectMap = new HashMap<String,URL>();
+    private SAXParser _parser;
+    private Map<String,ContentHandler> _observerMap;
+    private Stack<ContentHandler> _observers = new Stack<ContentHandler>();
+    private String _xpath;
+    private Object _xpaths;
+    private String _dtd;
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Construct
+     */
+    public XmlParser()
+    {
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+        boolean validating_dft = factory.getClass().toString().startsWith("org.apache.xerces.");
+        String validating_prop = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validating_dft ? "true" : "false");
+        boolean validating = Boolean.valueOf(validating_prop).booleanValue();
+        setValidating(validating);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Constructor.
+     */
+    public XmlParser(boolean validating)
+    {
+        setValidating(validating);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setValidating(boolean validating)
+    {
+        try
+        {
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            factory.setValidating(validating);
+            _parser = factory.newSAXParser();
+            
+            try
+            {
+                if (validating)
+                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/validation/schema", validating);
+            }
+            catch (Exception e)
+            {
+                if (validating)
+                    LOG.warn("Schema validation may not be supported: ", e);
+                else
+                    LOG.ignore(e);
+            }
+
+            _parser.getXMLReader().setFeature("http://xml.org/sax/features/validation", validating);
+            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", true);
+            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespace-prefixes", false);  
+            try
+            {
+                if (validating)
+                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", validating);
+            }
+            catch (Exception e)
+            {
+                LOG.warn(e.getMessage());
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.warn(Log.EXCEPTION, e);
+            throw new Error(e.toString());
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param name
+     * @param entity
+     */
+    public synchronized void redirectEntity(String name, URL entity)
+    {
+        if (entity != null)
+            _redirectMap.put(name, entity);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     * @return Returns the xpath.
+     */
+    public String getXpath()
+    {
+        return _xpath;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Set an XPath A very simple subset of xpath is supported to select a partial tree. Currently
+     * only path like "/node1/nodeA | /node1/nodeB" are supported.
+     * 
+     * @param xpath The xpath to set.
+     */
+    public void setXpath(String xpath)
+    {
+        _xpath = xpath;
+        StringTokenizer tok = new StringTokenizer(xpath, "| ");
+        while (tok.hasMoreTokens())
+            _xpaths = LazyList.add(_xpaths, tok.nextToken());
+    }
+
+    /* ------------------------------------------------------------ */
+    public String getDTD()
+    {
+        return _dtd;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Add a ContentHandler. Add an additional _content handler that is triggered on a tag name. SAX
+     * events are passed to the ContentHandler provided from a matching start element to the
+     * corresponding end element. Only a single _content handler can be registered against each tag.
+     * 
+     * @param trigger Tag local or q name.
+     * @param observer SAX ContentHandler
+     */
+    public synchronized void addContentHandler(String trigger, ContentHandler observer)
+    {
+        if (_observerMap == null)
+            _observerMap = new HashMap();
+        _observerMap.put(trigger, observer);
+    }
+
+    /* ------------------------------------------------------------ */
+    public synchronized Node parse(InputSource source) throws IOException, SAXException
+    {
+        _dtd=null;
+        Handler handler = new Handler();
+        XMLReader reader = _parser.getXMLReader();
+        reader.setContentHandler(handler);
+        reader.setErrorHandler(handler);
+        reader.setEntityResolver(handler);
+        if (LOG.isDebugEnabled())
+            LOG.debug("parsing: sid=" + source.getSystemId() + ",pid=" + source.getPublicId());
+        _parser.parse(source, handler);
+        if (handler._error != null)
+            throw handler._error;
+        Node doc = (Node) handler._top.get(0);
+        handler.clear();
+        return doc;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Parse String URL.
+     */
+    public synchronized Node parse(String url) throws IOException, SAXException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("parse: " + url);
+        return parse(new InputSource(url));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Parse File.
+     */
+    public synchronized Node parse(File file) throws IOException, SAXException
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("parse: " + file);
+        return parse(new InputSource(Resource.toURL(file).toString()));
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Parse InputStream.
+     */
+    public synchronized Node parse(InputStream in) throws IOException, SAXException
+    {
+        _dtd=null;
+        Handler handler = new Handler();
+        XMLReader reader = _parser.getXMLReader();
+        reader.setContentHandler(handler);
+        reader.setErrorHandler(handler);
+        reader.setEntityResolver(handler);
+        _parser.parse(new InputSource(in), handler);
+        if (handler._error != null)
+            throw handler._error;
+        Node doc = (Node) handler._top.get(0);
+        handler.clear();
+        return doc;
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class NoopHandler extends DefaultHandler
+    {
+        Handler _next;
+        int _depth;
+
+        NoopHandler(Handler next)
+        {
+            this._next = next;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
+        {
+            _depth++;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            if (_depth == 0)
+                _parser.getXMLReader().setContentHandler(_next);
+            else
+                _depth--;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    private class Handler extends DefaultHandler
+    {
+        Node _top = new Node(null, null, null);
+        SAXParseException _error;
+        private Node _context = _top;
+        private NoopHandler _noop;
+
+        Handler()
+        {
+            _noop = new NoopHandler(this);
+        }
+
+        /* ------------------------------------------------------------ */
+        void clear()
+        {
+            _top = null;
+            _error = null;
+            _context = null;
+        }
+
+        /* ------------------------------------------------------------ */
+        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
+        {
+            String name = null;
+            if (_parser.isNamespaceAware())
+                name = localName;
+
+            if (name == null || "".equals(name))
+                name = qName;
+
+            Node node = new Node(_context, name, attrs);
+            
+
+            // check if the node matches any xpaths set?
+            if (_xpaths != null)
+            {
+                String path = node.getPath();
+                boolean match = false;
+                for (int i = LazyList.size(_xpaths); !match && i-- > 0;)
+                {
+                    String xpath = (String) LazyList.get(_xpaths, i);
+
+                    match = path.equals(xpath) || xpath.startsWith(path) && xpath.length() > path.length() && xpath.charAt(path.length()) == '/';
+                }
+
+                if (match)
+                {
+                    _context.add(node);
+                    _context = node;
+                }
+                else
+                {
+                    _parser.getXMLReader().setContentHandler(_noop);
+                }
+            }
+            else
+            {
+                _context.add(node);
+                _context = node;
+            }
+
+            ContentHandler observer = null;
+            if (_observerMap != null)
+                observer = (ContentHandler) _observerMap.get(name);
+            _observers.push(observer);
+
+            for (int i = 0; i < _observers.size(); i++)
+                if (_observers.get(i) != null)
+                    ((ContentHandler) _observers.get(i)).startElement(uri, localName, qName, attrs);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            _context = _context._parent;
+            for (int i = 0; i < _observers.size(); i++)
+                if (_observers.get(i) != null)
+                    ((ContentHandler) _observers.get(i)).endElement(uri, localName, qName);
+            _observers.pop();
+        }
+
+        /* ------------------------------------------------------------ */
+        public void ignorableWhitespace(char buf[], int offset, int len) throws SAXException
+        {
+            for (int i = 0; i < _observers.size(); i++)
+                if (_observers.get(i) != null)
+                    ((ContentHandler) _observers.get(i)).ignorableWhitespace(buf, offset, len);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void characters(char buf[], int offset, int len) throws SAXException
+        {
+            _context.add(new String(buf, offset, len));
+            for (int i = 0; i < _observers.size(); i++)
+                if (_observers.get(i) != null)
+                    ((ContentHandler) _observers.get(i)).characters(buf, offset, len);
+        }
+
+        /* ------------------------------------------------------------ */
+        public void warning(SAXParseException ex)
+        {
+            LOG.debug(Log.EXCEPTION, ex);
+            LOG.warn("WARNING@" + getLocationString(ex) + " : " + ex.toString());
+        }
+
+        /* ------------------------------------------------------------ */
+        public void error(SAXParseException ex) throws SAXException
+        {
+            // Save error and continue to report other errors
+            if (_error == null)
+                _error = ex;
+            LOG.debug(Log.EXCEPTION, ex);
+            LOG.warn("ERROR@" + getLocationString(ex) + " : " + ex.toString());
+        }
+
+        /* ------------------------------------------------------------ */
+        public void fatalError(SAXParseException ex) throws SAXException
+        {
+            _error = ex;
+            LOG.debug(Log.EXCEPTION, ex);
+            LOG.warn("FATAL@" + getLocationString(ex) + " : " + ex.toString());
+            throw ex;
+        }
+
+        /* ------------------------------------------------------------ */
+        private String getLocationString(SAXParseException ex)
+        {
+            return ex.getSystemId() + " line:" + ex.getLineNumber() + " col:" + ex.getColumnNumber();
+        }
+
+        /* ------------------------------------------------------------ */
+        public InputSource resolveEntity(String pid, String sid)
+        {
+            if (LOG.isDebugEnabled())
+                LOG.debug("resolveEntity(" + pid + ", " + sid + ")");
+            
+            if (sid!=null && sid.endsWith(".dtd"))
+                _dtd=sid;
+            
+            URL entity = null;
+            if (pid != null)
+                entity = (URL) _redirectMap.get(pid);
+            if (entity == null)
+                entity = (URL) _redirectMap.get(sid);
+            if (entity == null)
+            {
+                String dtd = sid;
+                if (dtd.lastIndexOf('/') >= 0)
+                    dtd = dtd.substring(dtd.lastIndexOf('/') + 1);
+
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Can't exact match entity in redirect map, trying " + dtd);
+                entity = (URL) _redirectMap.get(dtd);
+            }
+
+            if (entity != null)
+            {
+                try
+                {
+                    InputStream in = entity.openStream();
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("Redirected entity " + sid + " --> " + entity);
+                    InputSource is = new InputSource(in);
+                    is.setSystemId(sid);
+                    return is;
+                }
+                catch (IOException e)
+                {
+                    LOG.ignore(e);
+                }
+            }
+            return null;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * XML Attribute.
+     */
+    public static class Attribute
+    {
+        private String _name;
+        private String _value;
+
+        Attribute(String n, String v)
+        {
+            _name = n;
+            _value = v;
+        }
+
+        public String getName()
+        {
+            return _name;
+        }
+
+        public String getValue()
+        {
+            return _value;
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /* ------------------------------------------------------------ */
+    /**
+     * XML Node. Represents an XML element with optional attributes and ordered content.
+     */
+    public static class Node extends AbstractList<Object>
+    {
+        Node _parent;
+        private ArrayList<Object> _list;
+        private String _tag;
+        private Attribute[] _attrs;
+        private boolean _lastString = false;
+        private String _path;
+
+        /* ------------------------------------------------------------ */
+        Node(Node parent, String tag, Attributes attrs)
+        {
+            _parent = parent;
+            _tag = tag;
+
+            if (attrs != null)
+            {
+                _attrs = new Attribute[attrs.getLength()];
+                for (int i = 0; i < attrs.getLength(); i++)
+                {
+                    String name = attrs.getLocalName(i);
+                    if (name == null || name.equals(""))
+                        name = attrs.getQName(i);
+                    _attrs[i] = new Attribute(name, attrs.getValue(i));
+                }
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public Node getParent()
+        {
+            return _parent;
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getTag()
+        {
+            return _tag;
+        }
+
+        /* ------------------------------------------------------------ */
+        public String getPath()
+        {
+            if (_path == null)
+            {
+                if (getParent() != null && getParent().getTag() != null)
+                    _path = getParent().getPath() + "/" + _tag;
+                else
+                    _path = "/" + _tag;
+            }
+            return _path;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get an array of element attributes.
+         */
+        public Attribute[] getAttributes()
+        {
+            return _attrs;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get an element attribute.
+         * 
+         * @return attribute or null.
+         */
+        public String getAttribute(String name)
+        {
+            return getAttribute(name, null);
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get an element attribute.
+         * 
+         * @return attribute or null.
+         */
+        public String getAttribute(String name, String dft)
+        {
+            if (_attrs == null || name == null)
+                return dft;
+            for (int i = 0; i < _attrs.length; i++)
+                if (name.equals(_attrs[i].getName()))
+                    return _attrs[i].getValue();
+            return dft;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get the number of children nodes.
+         */
+        public int size()
+        {
+            if (_list != null)
+                return _list.size();
+            return 0;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get the ith child node or content.
+         * 
+         * @return Node or String.
+         */
+        public Object get(int i)
+        {
+            if (_list != null)
+                return _list.get(i);
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get the first child node with the tag.
+         * 
+         * @param tag
+         * @return Node or null.
+         */
+        public Node get(String tag)
+        {
+            if (_list != null)
+            {
+                for (int i = 0; i < _list.size(); i++)
+                {
+                    Object o = _list.get(i);
+                    if (o instanceof Node)
+                    {
+                        Node n = (Node) o;
+                        if (tag.equals(n._tag))
+                            return n;
+                    }
+                }
+            }
+            return null;
+        }
+
+        /* ------------------------------------------------------------ */
+        @Override
+        public void add(int i, Object o)
+        {
+            if (_list == null)
+                _list = new ArrayList<Object>();
+            if (o instanceof String)
+            {
+                if (_lastString)
+                {
+                    int last = _list.size() - 1;
+                    _list.set(last, (String) _list.get(last) + o);
+                }
+                else
+                    _list.add(i, o);
+                _lastString = true;
+            }
+            else
+            {
+                _lastString = false;
+                _list.add(i, o);
+            }
+        }
+
+        /* ------------------------------------------------------------ */
+        public void clear()
+        {
+            if (_list != null)
+                _list.clear();
+            _list = null;
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Get a tag as a string.
+         * 
+         * @param tag The tag to get
+         * @param tags IF true, tags are included in the value.
+         * @param trim If true, trim the value.
+         * @return results of get(tag).toString(tags).
+         */
+        public String getString(String tag, boolean tags, boolean trim)
+        {
+            Node node = get(tag);
+            if (node == null)
+                return null;
+            String s = node.toString(tags);
+            if (s != null && trim)
+                s = s.trim();
+            return s;
+        }
+
+        /* ------------------------------------------------------------ */
+        public synchronized String toString()
+        {
+            return toString(true);
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Convert to a string.
+         * 
+         * @param tag If false, only _content is shown.
+         */
+        public synchronized String toString(boolean tag)
+        {
+            StringBuilder buf = new StringBuilder();
+            toString(buf, tag);
+            return buf.toString();
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Convert to a string.
+         * 
+         * @param tag If false, only _content is shown.
+         */
+        public synchronized String toString(boolean tag, boolean trim)
+        {
+            String s = toString(tag);
+            if (s != null && trim)
+                s = s.trim();
+            return s;
+        }
+
+        /* ------------------------------------------------------------ */
+        private synchronized void toString(StringBuilder buf, boolean tag)
+        {
+            if (tag)
+            {
+                buf.append("<");
+                buf.append(_tag);
+
+                if (_attrs != null)
+                {
+                    for (int i = 0; i < _attrs.length; i++)
+                    {
+                        buf.append(' ');
+                        buf.append(_attrs[i].getName());
+                        buf.append("=\"");
+                        buf.append(_attrs[i].getValue());
+                        buf.append("\"");
+                    }
+                }
+            }
+
+            if (_list != null)
+            {
+                if (tag)
+                    buf.append(">");
+                for (int i = 0; i < _list.size(); i++)
+                {
+                    Object o = _list.get(i);
+                    if (o == null)
+                        continue;
+                    if (o instanceof Node)
+                        ((Node) o).toString(buf, tag);
+                    else
+                        buf.append(o.toString());
+                }
+                if (tag)
+                {
+                    buf.append("</");
+                    buf.append(_tag);
+                    buf.append(">");
+                }
+            }
+            else if (tag)
+                buf.append("/>");
+        }
+
+        /* ------------------------------------------------------------ */
+        /**
+         * Iterator over named child nodes.
+         * 
+         * @param tag The tag of the nodes.
+         * @return Iterator over all child nodes with the specified tag.
+         */
+        public Iterator<Node> iterator(final String tag)
+        {
+            return new Iterator<Node>()
+            {
+                int c = 0;
+                Node _node;
+
+                /* -------------------------------------------------- */
+                public boolean hasNext()
+                {
+                    if (_node != null)
+                        return true;
+                    while (_list != null && c < _list.size())
+                    {
+                        Object o = _list.get(c);
+                        if (o instanceof Node)
+                        {
+                            Node n = (Node) o;
+                            if (tag.equals(n._tag))
+                            {
+                                _node = n;
+                                return true;
+                            }
+                        }
+                        c++;
+                    }
+                    return false;
+                }
+
+                /* -------------------------------------------------- */
+                public Node next()
+                {
+                    try
+                    {
+                        if (hasNext())
+                            return _node;
+                        throw new NoSuchElementException();
+                    }
+                    finally
+                    {
+                        _node = null;
+                        c++;
+                    }
+                }
+
+                /* -------------------------------------------------- */
+                public void remove()
+                {
+                    throw new UnsupportedOperationException("Not supported");
+                }
+            };
+        }
+    }
+}
diff --git a/src/resources/jetty-dir.css b/src/resources/jetty-dir.css
new file mode 100644
index 0000000..1686813
--- /dev/null
+++ b/src/resources/jetty-dir.css
@@ -0,0 +1,31 @@
+body 
+{
+	background-color: #FFFFFF;
+	margin: 10px;
+	padding: 5px;
+}
+
+h1
+{
+	text-shadow: #000000 -1px -1px 1px;
+	color: #FC390E;
+	font-weight: bold;
+}
+
+a
+{
+	color: #7036be;
+	font-weight: bold;
+	font-style: normal;
+	text-decoration: none;
+	font-size:inherit;
+}
+
+td
+{
+	font-style: italic;
+	padding: 2px 15px 2px 0px;
+}
+
+
+
diff --git a/src/resources/org/eclipse/jetty/favicon.ico b/src/resources/org/eclipse/jetty/favicon.ico
new file mode 100644
index 0000000..ea9e174
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/favicon.ico
Binary files differ
diff --git a/src/resources/org/eclipse/jetty/http/encoding.properties b/src/resources/org/eclipse/jetty/http/encoding.properties
new file mode 100644
index 0000000..311c802
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/http/encoding.properties
@@ -0,0 +1,4 @@
+text/html	= ISO-8859-1
+text/plain	= ISO-8859-1
+text/xml	= UTF-8
+text/json   = UTF-8
diff --git a/src/resources/org/eclipse/jetty/http/mime.properties b/src/resources/org/eclipse/jetty/http/mime.properties
new file mode 100644
index 0000000..8425ac1
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/http/mime.properties
@@ -0,0 +1,181 @@
+ai	= application/postscript
+aif	= audio/x-aiff
+aifc	= audio/x-aiff
+aiff	= audio/x-aiff
+apk = application/vnd.android.package-archive
+asc	= text/plain
+asf     = video/x.ms.asf
+asx     = video/x.ms.asx
+au	= audio/basic
+avi	= video/x-msvideo
+bcpio	= application/x-bcpio
+bin	= application/octet-stream
+cab     = application/x-cabinet
+cdf	= application/x-netcdf
+class	= application/java-vm
+cpio	= application/x-cpio
+cpt	= application/mac-compactpro
+crt	= application/x-x509-ca-cert
+csh	= application/x-csh
+css	= text/css
+csv     = text/comma-separated-values
+dcr	= application/x-director
+dir	= application/x-director
+dll     = application/x-msdownload
+dms	= application/octet-stream
+doc	= application/msword
+dtd     = application/xml-dtd
+dvi	= application/x-dvi
+dxr	= application/x-director
+eps	= application/postscript
+etx	= text/x-setext
+exe	= application/octet-stream
+ez	= application/andrew-inset
+gif	= image/gif
+gtar	= application/x-gtar
+gz	= application/gzip
+gzip	= application/gzip
+hdf	= application/x-hdf
+hqx	= application/mac-binhex40
+htc = text/x-component
+htm	= text/html
+html	= text/html
+ice	= x-conference/x-cooltalk
+ico	= image/x-icon
+ief	= image/ief
+iges	= model/iges
+igs	= model/iges
+jad     = text/vnd.sun.j2me.app-descriptor
+jar     = application/java-archive
+java	= text/plain
+jnlp	= application/x-java-jnlp-file
+jpe	= image/jpeg
+jpeg	= image/jpeg
+jpg	= image/jpeg
+js	= application/x-javascript
+jsp	= text/html
+kar	= audio/midi
+latex	= application/x-latex
+lha	= application/octet-stream
+lzh	= application/octet-stream
+man	= application/x-troff-man
+mathml	= application/mathml+xml
+me	= application/x-troff-me
+mesh	= model/mesh
+mid	= audio/midi
+midi	= audio/midi
+mif	= application/vnd.mif
+mol     = chemical/x-mdl-molfile
+mov	= video/quicktime
+movie	= video/x-sgi-movie
+mp2	= audio/mpeg
+mp3	= audio/mpeg
+mpe	= video/mpeg
+mpeg	= video/mpeg
+mpg	= video/mpeg
+mpga	= audio/mpeg
+ms	= application/x-troff-ms
+msh	= model/mesh
+msi	= application/octet-stream
+nc	= application/x-netcdf
+oda	= application/oda
+odb     = application/vnd.oasis.opendocument.database
+odc     = application/vnd.oasis.opendocument.chart
+odf     = application/vnd.oasis.opendocument.formula
+odg     = application/vnd.oasis.opendocument.graphics
+odi     = application/vnd.oasis.opendocument.image
+odm     = application/vnd.oasis.opendocument.text-master
+odp     = application/vnd.oasis.opendocument.presentation
+ods     = application/vnd.oasis.opendocument.spreadsheet
+odt     = application/vnd.oasis.opendocument.text
+ogg	= application/ogg
+otc     = application/vnd.oasis.opendocument.chart-template
+otf     = application/vnd.oasis.opendocument.formula-template
+otg     = application/vnd.oasis.opendocument.graphics-template
+oth     = application/vnd.oasis.opendocument.text-web
+oti     = application/vnd.oasis.opendocument.image-template
+otp     = application/vnd.oasis.opendocument.presentation-template
+ots     = application/vnd.oasis.opendocument.spreadsheet-template
+ott     = application/vnd.oasis.opendocument.text-template
+pbm	= image/x-portable-bitmap
+pdb	= chemical/x-pdb
+pdf	= application/pdf
+pgm	= image/x-portable-graymap
+pgn	= application/x-chess-pgn
+png	= image/png
+pnm	= image/x-portable-anymap
+ppm	= image/x-portable-pixmap
+pps     = application/vnd.ms-powerpoint
+ppt	= application/vnd.ms-powerpoint
+ps	= application/postscript
+qt	= video/quicktime
+ra	= audio/x-pn-realaudio
+ram	= audio/x-pn-realaudio
+ras	= image/x-cmu-raster
+rdf	= application/rdf+xml
+rgb	= image/x-rgb
+rm	= audio/x-pn-realaudio
+roff	= application/x-troff
+rpm	= application/x-rpm
+rtf	= application/rtf
+rtx	= text/richtext
+rv      = video/vnd.rn-realvideo
+ser     = application/java-serialized-object
+sgm	= text/sgml
+sgml	= text/sgml
+sh	= application/x-sh
+shar	= application/x-shar
+silo	= model/mesh
+sit	= application/x-stuffit
+skd	= application/x-koan
+skm	= application/x-koan
+skp	= application/x-koan
+skt	= application/x-koan
+smi	= application/smil
+smil	= application/smil
+snd	= audio/basic
+spl	= application/x-futuresplash
+src	= application/x-wais-source
+sv4cpio	= application/x-sv4cpio
+sv4crc	= application/x-sv4crc
+svg	= image/svg+xml
+swf	= application/x-shockwave-flash
+t	= application/x-troff
+tar	= application/x-tar
+tar.gz	= application/x-gtar
+tcl	= application/x-tcl
+tex	= application/x-tex
+texi	= application/x-texinfo
+texinfo	= application/x-texinfo
+tgz	= application/x-gtar
+tif	= image/tiff
+tiff	= image/tiff
+tr	= application/x-troff
+tsv	= text/tab-separated-values
+txt	= text/plain
+ustar	= application/x-ustar
+vcd	= application/x-cdlink
+vrml	= model/vrml
+vxml	= application/voicexml+xml
+wav	= audio/x-wav
+wbmp	= image/vnd.wap.wbmp
+wml	= text/vnd.wap.wml
+wmlc	= application/vnd.wap.wmlc
+wmls	= text/vnd.wap.wmlscript
+wmlsc	= application/vnd.wap.wmlscriptc
+wrl	= model/vrml
+wtls-ca-certificate	= application/vnd.wap.wtls-ca-certificate
+xbm	= image/x-xbitmap
+xht	= application/xhtml+xml
+xhtml	= application/xhtml+xml
+xls	= application/vnd.ms-excel
+xml	= application/xml
+xpm	= image/x-xpixmap
+xsd	= application/xml
+xsl	= application/xml
+xslt	= application/xslt+xml
+xul	= application/vnd.mozilla.xul+xml
+xwd	= image/x-xwindowdump
+xyz	= chemical/x-xyz
+z	= application/compress
+zip	= application/zip
diff --git a/src/resources/org/eclipse/jetty/http/useragents b/src/resources/org/eclipse/jetty/http/useragents
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/http/useragents
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/AbstractHandler-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/AbstractHandler-mbean.properties
new file mode 100644
index 0000000..8b82f1a
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/AbstractHandler-mbean.properties
@@ -0,0 +1 @@
+AbstractHandler: Jetty Handler.
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandler-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandler-mbean.properties
new file mode 100644
index 0000000..faf27f0
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandler-mbean.properties
@@ -0,0 +1,24 @@
+ContextHandler: URI Context
+aliases: True if alias checking is performed on resource
+allowNullPathInfo: Checks if the /context is not redirected to /context/
+classPath: RO: The file classpath
+compactPath: True if URLs are compacted to replace the multiple '/'s with a single '/'
+connectorNames: Names and ports of accepted connectors
+contextAttributes: RO:MBean: Map of context attributes
+contextPath: URI prefix of context
+displayName: RO: Display name of the Context
+errorHandler: MObject: The error handler to use for the context
+initParams: Initial Parameter map for the context
+maxFormContentSize: The maximum content size
+removeContextAttribute(java.lang.String): MBean:ACTION: remove context attribute
+removeContextAttribute(java.lang.String)[0]: name: The attribute name
+resourceBase: Document root for the context
+setContextAttribute(java.lang.String,java.lang.Object): MBean:ACTION: Set context attribute
+setContextAttribute(java.lang.String,java.lang.Object)[0]: name: The attribute name
+setContextAttribute(java.lang.String,java.lang.Object)[1]: value: The attribute value
+setContextAttribute(java.lang.String,java.lang.String): MBean:ACTION: Set context attribute
+setContextAttribute(java.lang.String,java.lang.String)[0]: name: The attribute name
+setContextAttribute(java.lang.String,java.lang.String)[1]: value: The attribute value
+shutdown: False if this context is accepting new requests. True for graceful shutdown, which allows existing requests to complete
+virtualHosts: Virtual hosts accepted by the context
+welcomeFiles: Partial URIs of directory welcome files
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandlerCollection-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandlerCollection-mbean.properties
new file mode 100644
index 0000000..4ab1fef
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/ContextHandlerCollection-mbean.properties
@@ -0,0 +1,2 @@
+ContextHandlerCollection: Context Handler Collection
+mapContexts(): Update the mapping of context path to context
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerCollection-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerCollection-mbean.properties
new file mode 100644
index 0000000..37152f5
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerCollection-mbean.properties
@@ -0,0 +1,2 @@
+HandlerCollection: Handler of multiple Handlers
+handlers: MObject:Wrapped handlers
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerWrapper-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerWrapper-mbean.properties
new file mode 100644
index 0000000..3395f64
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/HandlerWrapper-mbean.properties
@@ -0,0 +1,2 @@
+HandlerWrapper: Handler wrapping another Handler
+handler: MObject:Wrapped handler
diff --git a/src/resources/org/eclipse/jetty/server/handler/jmx/StatisticsHandler-mbean.properties b/src/resources/org/eclipse/jetty/server/handler/jmx/StatisticsHandler-mbean.properties
new file mode 100644
index 0000000..295f4de
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/handler/jmx/StatisticsHandler-mbean.properties
@@ -0,0 +1,28 @@
+StatisticsHandler: Request Statistics gathering
+statsOnMs: Time in milliseconds stats have been collected for.
+statsReset(): Resets statistics.
+requests: Number of requests since statsReset() called.
+requestsActive: Number of requests currently active since statsReset() called.
+requestsActiveMax: Maximum number of active requests since statsReset() called.
+requestTimeMax: Maximum time in milliseconds of request handling since statsReset() called.
+requestTimeTotal: Total time in milliseconds of all request handling since statsReset() called.
+requestTimeMean: Mean of time in milliseconds of request handling since statsReset() called.
+requestTimeStdDev: Standard deviation of time in milliseconds of request handling since statsReset() called.
+dispatched: Number of dispatches since statsReset() called.
+dispatchedActive: Number of dispatches currently active since statsReset() called.
+dispatchedActiveMax: Maximum number of active dispatches since statsReset() called.
+dispatchedTimeMax: Maximum time in milliseconds of dispatched handling since statsReset() called.
+dispatchedTimeTotal: Total time in milliseconds of all dispatched handling since statsReset() called.
+dispatchedTimeMean: Mean of time in milliseconds of dispatch handling since statsReset() called.
+dispatchedTimeStdDev: Standard deviation of time in milliseconds of dispatch handling since statsReset() called.
+suspends: Number of requests suspended since statsReset() called.
+suspendsActive: Number of dispatches currently active since statsReset() called.
+suspendsActiveMax: Maximum number of active dispatches since statsReset() called.
+resumes: Number of requests resumed since statsReset() called.
+expires: Number of requests expired since statsReset() called.
+responses1xx: Number of responses with a 1xx status since statsReset() called.
+responses2xx: Number of responses with a 2xx status since statsReset() called.
+responses3xx: Number of responses with a 3xx status since statsReset() called.
+responses4xx: Number of responses with a 4xx status since statsReset() called.
+responses5xx: Number of responses with a 5xx status since statsReset() called.
+responsesBytesTotal: Total number of bytes of all responses since statsReset() called.
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties
new file mode 100644
index 0000000..fd76672
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/AbstractConnector-mbean.properties
@@ -0,0 +1,19 @@
+AbstractConnector: Abstract implementation of the Connector interface.
+acceptors: The number of acceptor threads.
+acceptQueueSize: The size of the accept queue.
+acceptorPriorityOffset: Priority offset of the acceptor threads. The priority is adjusted by this amount to either favor the acceptance of new threads and newly active connections or to favor the handling of already dispatched connections.
+forwardedForHeader: The header name for forwarded for (default x-forwarded-for). 
+forwardedHostHeader: The header name for forwarded hosts (default x-forwarded-host)
+forwardedServerHeader: The header name for forwarded server (default x-forwarded-server)
+forwarded: Whether reverse proxy handling is on. True if this connector is checking the forwarded for/host/server headers.
+host: Host name of the server.
+hostHeader: Forced value for the host header. Only used if forwarded is true.
+soLingerTime: Enable or disable SO_LINGER with the specified linger time in seconds.
+reuseAddress: Whether the server socket will be opened in SO_REUSEADDR mode.
+name: Name of the connector.
+resolveNames: Whether or not to use DNS when handling forwards. 
+confidentialPort: Port to use for confidential redirections.
+confidentialScheme: Scheme to use for confidential redirections.
+integralPort: Port to use for integral redirections.
+integralScheme: Scheme to use for integral redirections.
+lowResourcesMaxIdleTime: The period in ms that a connection may be idle when the connector has low resources, before it is closed.
diff --git a/src/resources/org/eclipse/jetty/server/jmx/Connector-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/Connector-mbean.properties
new file mode 100644
index 0000000..efd5cef
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/Connector-mbean.properties
@@ -0,0 +1,29 @@
+Connector: HTTP Connector.
+server: MObject:RO:The server for this connector
+requestHeaderSize: The size of a request header buffer
+requestBufferSize: The size of a request content buffer
+responseHeaderSize: The size of a response header buffer
+responseBufferSize: The size of a response content buffer
+integralPort: Port to use for integral redirections
+integralScheme: Scheme to use for integral redirections
+confidentialPort: Port to use for confidential redirections
+confidentialScheme: Scheme to use for confidential redirections
+host: Host name to accept connections on
+port: TCP/IP port to accept connections on
+maxIdleTime: Maximum time in ms that a connection can be idle before being closed
+statsOn: True if statistics collection is turned on.
+statsOnMs: Time in milliseconds stats have been collected for. 
+statsReset(): Reset statistics.
+connections: Number of connections accepted by the server since statsReset() called. Undefined if setStatsOn(false).
+connectionsOpen: Number of connections currently open that were opened since statsReset() called. Undefined if setStatsOn(false).
+connectionsOpenMax: Maximum number of connections opened simultaneously since statsReset() called. Undefined if setStatsOn(false).
+connectionsDurationMean: Mean duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false).
+connectionsDurationStdDev: Standard deviation of duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false).
+connectionsDurationMax: Maximum duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false).
+connectionsDurationTotal: Total duration in milliseconds of all open connection since statsReset() called. Undefined if setStatsOn(false).
+connectionsRequestsMean: Mean number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+connectionsRequestsStdDev: Standard deviation of number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+connectionsRequestsMax: Maximum number of requests per connection since statsReset() called. Undefined if setStatsOn(false).
+requests: Number of requests since statsReset() called. Undefined if setStatsOn(false).
+open(): Open the listening port
+close(): Close the listening port (but allow existing connections to continue for graceful shutdown)
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/server/jmx/Handler-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/Handler-mbean.properties
new file mode 100644
index 0000000..eea633f
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/Handler-mbean.properties
@@ -0,0 +1,3 @@
+Handler: Jetty Handler.
+server: MObject:RO:The Jetty server for this handler
+destroy(): destroy associated resources (eg MBean)
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/server/jmx/HandlerContainer-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/HandlerContainer-mbean.properties
new file mode 100644
index 0000000..374e020
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/HandlerContainer-mbean.properties
@@ -0,0 +1,3 @@
+HandlerContainer: Handler of multiple Handlers
+handlers: MObject:RO:Handlers in this container
+childHandlers: MObject:RO:All contained handlers
diff --git a/src/resources/org/eclipse/jetty/server/jmx/NCSARequestLog-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/NCSARequestLog-mbean.properties
new file mode 100644
index 0000000..0c0e340
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/NCSARequestLog-mbean.properties
@@ -0,0 +1,6 @@
+NCSARequestLog : NCSA standard format request log
+filename : Filename of log
+retainDays : Number of days that the log files are kept
+append : Existing log files are appended to the new one
+extended : Use the extended NCSA format
+LogTimeZone : The timezone
diff --git a/src/resources/org/eclipse/jetty/server/jmx/Server-mbean.properties b/src/resources/org/eclipse/jetty/server/jmx/Server-mbean.properties
new file mode 100644
index 0000000..017711c
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/jmx/Server-mbean.properties
@@ -0,0 +1,9 @@
+Server: Jetty HTTP Servlet server
+connectors: MObject:HTTP Connectors for this server
+version: RO: The version of this server
+sendServerVersion: If true include the server version in HTTP headers
+threadPool: MObject:The server Thread Pool
+contexts: MMBean:RO:The contexts of this server
+startupTime: MBean:RO:The startup time, in milliseconds, since January 1st 1970
+dumpAfterStart: RW:Dump state to stderr after start
+dumpBeforeStop: RW:Dump state to stderr before stop
diff --git a/src/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties b/src/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties
new file mode 100644
index 0000000..dbe718d
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/nio/jmx/SelectChannelConnector-mbean.properties
@@ -0,0 +1,2 @@
+SelectChannelConnector: HTTP connector using NIO ByteChannels and Selectors
+lowResourcesConnections: The number of connections, which if exceeded represents low resources
diff --git a/src/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties b/src/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties
new file mode 100644
index 0000000..92deb5f
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/server/session/jmx/AbstractSessionManager-mbean.properties
@@ -0,0 +1,19 @@
+AbstractSessionManager: Abstract Session Manager
+httpOnly: True if cookies use the http only flag
+idManager: MObject:RO:The ID Manager instance
+maxCookieAge: if greater than zero, the time in seconds a session cookie will last for
+maxInactiveInterval: default maximum time in seconds a session may be idle
+refreshCookieAge: The time in seconds after which a session cookie is re-set
+secureCookies: If true, the secure cookie flag is set on session cookies
+sessionCookie: The set session cookie 
+sessionDomain: The domain of the session cookie or null for the default
+sessionPath: The path of the session cookie or null for the default
+sessionsTotal: The total number of sessions
+sessionIdPathParameterName: The name to use for URL session tracking
+statsReset(): Reset statistics
+sessions: Current instantaneous number of sessions
+sessionsMax: Maximum number of simultaneous sessions since statsReset() was called
+sessionTimeMax: Maximum amount of time in seconds session remained valid since statsReset() was called
+sessionTimeTotal: Total amount of time in seconds sessions remained valid since statsReset() was called
+sessionTimeMean: Mean amount of time in seconds  a session remained valid since statsReset() was called
+sessionTimeStdDev: Standard deviation of amount of time in seconds  a session remained valid since statsReset() was called
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/FilterMapping-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/FilterMapping-mbean.properties
new file mode 100644
index 0000000..afcbe2f
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/FilterMapping-mbean.properties
@@ -0,0 +1,4 @@
+FilterMapping: Filter Mapping
+filterName: RO:Filter Name
+pathSpecs: RO:URL patterns
+servletNames: RO:Servlet Names
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/Holder-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/Holder-mbean.properties
new file mode 100644
index 0000000..7730ff4
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/Holder-mbean.properties
@@ -0,0 +1,5 @@
+Holder: Holder
+name: RO:Name
+displayName: RO:Display Name
+className: RO:Class Name
+initParameters: RO:Initial parameters
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/ServletContextHandler-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/ServletContextHandler-mbean.properties
new file mode 100644
index 0000000..2c1a05a
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/ServletContextHandler-mbean.properties
@@ -0,0 +1,4 @@
+ServletContextHandler: Servlet Context Handler
+securityHandler: MObject: The context's security handler
+servletHandler: MObject: The context's servlet handler
+sessionHandler: MObject: The context's session handler
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/ServletHandler-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/ServletHandler-mbean.properties
new file mode 100644
index 0000000..9326c19
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/ServletHandler-mbean.properties
@@ -0,0 +1,5 @@
+ServletHandler: Servlet Handler
+servlets: MObject:RO:Servlets
+servletMappings: MObject:RO:Mappings of servlets
+filters: MObject:RO:Filters
+filterMappings: MObject:RO:Mappings of filters
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/ServletHolder-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/ServletHolder-mbean.properties
new file mode 100644
index 0000000..3844546
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/ServletHolder-mbean.properties
@@ -0,0 +1,4 @@
+ServletHolder: Servlet Holder
+initOrder: Initialization order
+runAsRole: Role to run servlet as
+forcedPath: Forced servlet path
diff --git a/src/resources/org/eclipse/jetty/servlet/jmx/ServletMapping-mbean.properties b/src/resources/org/eclipse/jetty/servlet/jmx/ServletMapping-mbean.properties
new file mode 100644
index 0000000..efe07ff
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlet/jmx/ServletMapping-mbean.properties
@@ -0,0 +1,3 @@
+ServletMapping: Servlet Mapping
+servletName: RO:Servlet Name
+pathSpecs: RO:URL patterns
diff --git a/src/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties b/src/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties
new file mode 100644
index 0000000..9523d23
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlets/jmx/DoSFilter-mbean.properties
@@ -0,0 +1,18 @@
+DoSFilter: Limit exposure to abuse from request flooding, whether malicious, or as a result of a misconfigured client.
+maxRequestsPerSec: maximum number of requests from a connection per second. Requests in excess of this are first delayed, then throttled.
+delayMs: delay (in milliseconds) that is applied to all requests over the rate limit, before they are considered at all, 0 - no delay, -1 - reject request.
+maxWaitMs: maximum amount of time (in milliseconds) the filter will blocking wait for the throttle semaphore.
+throttledRequests: number of requests over the rate limit able to be considered at once.
+throttleMs: amount of time (in milliseconds) to async wait for semaphore.
+maxRequestMs: maximum amount of time (in milliseconds) to allow the request to process.
+maxIdleTrackerMs: maximum amount of time (in milliseconds) to keep track of request rates for a connection, before deciding that the user has gone away, and discarding it.
+insertHeaders: insert the DoSFilter headers into the response.
+trackSessions: usage rate is tracked by session if a session exists.
+remotePort: usage rate is tracked by IP+port (effectively connection) if session tracking is not used.
+enabled: whether this filter is enabled
+whitelist: comma separated list of IP addresses that will not be rate limited.
+clearWhitelist(): clears the list of IP addresses that will not be rate limited.
+addWhitelistAddress(java.lang.String):ACTION: adds an IP address that will not be rate limited.
+addWhitelistAddress(java.lang.String)[0]:address: the IP address that will not be rate limited.
+removeWhitelistAddress(java.lang.String):ACTION: removes an IP address that will not be rate limited.
+removeWhitelistAddress(java.lang.String)[0]:address: the IP address that will not be rate limited.
diff --git a/src/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties b/src/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties
new file mode 100644
index 0000000..c781d63
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/servlets/jmx/QoSFilter-mbean.properties
@@ -0,0 +1,4 @@
+QoSFilter: Quality of Service Filter.
+maxRequests: maximum number of requests allowed to be processedat the same time.
+waitMs: (short) amount of time (in milliseconds) that the filter would wait for the semaphore to become available before suspending a request.
+suspendMs: amount of time (in milliseconds) that the filter would suspend a request for while waiting for the semaphore to become available.
diff --git a/src/resources/org/eclipse/jetty/util/component/jmx/AggregateLifeCycle-mbean.properties b/src/resources/org/eclipse/jetty/util/component/jmx/AggregateLifeCycle-mbean.properties
new file mode 100644
index 0000000..437f426
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/component/jmx/AggregateLifeCycle-mbean.properties
@@ -0,0 +1,2 @@
+AggregateLifeCycle: A LifeCycle holding other LifeCycles
+dumpStdErr():Object:INFO:Dump the nested Object state to StdErr
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/util/component/jmx/Dumpable-mbean.properties b/src/resources/org/eclipse/jetty/util/component/jmx/Dumpable-mbean.properties
new file mode 100644
index 0000000..6015f73
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/component/jmx/Dumpable-mbean.properties
@@ -0,0 +1,2 @@
+Dumpable: Dumpable Object
+dump():Object:INFO:Dump the nested Object state as a String
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/util/component/jmx/LifeCycle-mbean.properties b/src/resources/org/eclipse/jetty/util/component/jmx/LifeCycle-mbean.properties
new file mode 100644
index 0000000..0c0ab61
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/component/jmx/LifeCycle-mbean.properties
@@ -0,0 +1,9 @@
+LifeCycle: Startable object
+start(): Starts the instance
+stop(): Stops the instance
+running: Instance is started or starting
+started: Instance is started
+starting: Instance is starting
+stopping: Instance is stopping
+stopped: Instance is stopped
+failed: Instance is failed
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/util/log/jmx/Log-mbean.properties b/src/resources/org/eclipse/jetty/util/log/jmx/Log-mbean.properties
new file mode 100644
index 0000000..18abcb1
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/log/jmx/Log-mbean.properties
@@ -0,0 +1,8 @@
+Log: Jetty Logging implementaton
+loggers:MBean: List of all instantiated loggers
+debugEnabled:RW: True if debug enabled for root logger Log.LOG
+isDebugEnabled(java.lang.String):MBean:INFO: True if debug is enabled for the given logger
+isDebugEnabled(java.lang.String)[0]:loggerName: Name of the logger to return isDebugEnabled for
+setDebugEnabled(java.lang.String,java.lang.Boolean):MBean:ACTION: Set debug enabled for the given logger
+setDebugEnabled(java.lang.String,java.lang.Boolean)[0]:loggerName: Name of the logger to set debug enabled
+setDebugEnabled(java.lang.String,java.lang.Boolean)[1]:enabled: true to enable debug, false otherwise
diff --git a/src/resources/org/eclipse/jetty/util/thread/jmx/QueuedThreadPool-mbean.properties b/src/resources/org/eclipse/jetty/util/thread/jmx/QueuedThreadPool-mbean.properties
new file mode 100644
index 0000000..9bdffd8
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/thread/jmx/QueuedThreadPool-mbean.properties
@@ -0,0 +1,16 @@
+QueuedThreadPool: A thread pool with no max bound by default
+minThreads: Minimum number of threads in the pool
+maxThreads: Maximum number threads in the pool
+maxQueued: The maximum size of the job queue or -1 for unbounded.
+name: Name of the thread pool
+daemon: Is pool thread using daemon thread
+threadsPriority: The priority of threads in the pool
+maxIdleTimeMs: Maximum time a thread may be idle in ms
+detailedDump: Full stack detail in dump output
+dump(): Dump thread state
+stopThread(long): Stop a pool thread
+stopThread(long)[0]: id:Thread ID
+interruptThread(long): Interrupt a pool thread
+interruptThread(long)[0]: id:Thread ID
+dumpThread(long): Dump a pool thread stack
+dumpThread(long)[0]: id:Thread ID
diff --git a/src/resources/org/eclipse/jetty/util/thread/jmx/ThreadPool-mbean.properties b/src/resources/org/eclipse/jetty/util/thread/jmx/ThreadPool-mbean.properties
new file mode 100644
index 0000000..9ee55bf
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/util/thread/jmx/ThreadPool-mbean.properties
@@ -0,0 +1,4 @@
+ThreadPool: Pool of threads
+threads: RO:Number of Threads in pool
+idleThreads: RO:Number of idle Threads in pool
+lowOnThreads: RO:Indicates the pool is low on available threads.
diff --git a/src/resources/org/eclipse/jetty/webapp/jmx/WebAppContext-mbean.properties b/src/resources/org/eclipse/jetty/webapp/jmx/WebAppContext-mbean.properties
new file mode 100644
index 0000000..5a09672
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/webapp/jmx/WebAppContext-mbean.properties
@@ -0,0 +1,14 @@
+WebAppContext: Web Application ContextHandler
+configurationClasses: Array of names of configuration classes 
+defaultsDescriptor: Default web.xml descriptor applied before standard web.xml
+overrideDescriptor: Override web.xml descriptor applied after standard web.xml
+serverClasses: Classes and packages hidden by the context classloader
+systemClasses: Classes and packages given priority by context classloader
+war: WAR file location
+distributable: Is the web application distributable
+extractWAR: Is the war file extraced on deploy
+copyWebDir: Is the web application directory copied on deploy
+parentLoaderPriority: Is the parent classloader given priority
+descriptor: The standard web.xml descriptor
+extraClasspath: Extra classpath for the context classloader
+tempDirectory: Temporary directory location
\ No newline at end of file
diff --git a/src/resources/org/eclipse/jetty/xml/configure_6_0.dtd b/src/resources/org/eclipse/jetty/xml/configure_6_0.dtd
new file mode 100644
index 0000000..f79d4b7
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/xml/configure_6_0.dtd
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+This is the document type descriptor for the
+org.eclipse.XmlConfiguration class.  It allows a java object to be
+configured by with a sequence of Set, Put and Call elements.  These tags are
+mapped to methods on the object to be configured as follows:
+
+  <Set  name="Test">value</Set>              ==  obj.setTest("value");
+  <Put  name="Test">value</Put>              ==  obj.put("Test","value");
+  <Call name="test"><Arg>value</Arg></Call>  ==  obj.test("value");
+
+Values themselves may be configured objects that are created with the
+<New> tag or returned from a <Call> tag.
+
+Values are matched to arguments on a best effort approach, but types
+my be specified if a match is not achieved.
+
+-->
+
+<!ENTITY % CONFIG "Set|Get|Put|Call|New|Ref|Array|Map|Property">
+<!ENTITY % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|Property">
+
+<!ENTITY % TYPEATTR "type CDATA #IMPLIED " > <!-- String|Character|Short|Byte|Integer|Long|Boolean|Float|Double|char|short|byte|int|long|boolean|float|double|URL|InetAddress|InetAddrPort| #classname -->
+<!ENTITY % IMPLIEDCLASSATTR "class NMTOKEN #IMPLIED" >
+<!ENTITY % CLASSATTR "class NMTOKEN #REQUIRED" >
+<!ENTITY % NAMEATTR "name NMTOKEN #REQUIRED" >
+<!ENTITY % IMPLIEDNAMEATTR "name NMTOKEN #IMPLIED" >
+<!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" >
+<!ENTITY % IDATTR "id NMTOKEN #IMPLIED" >
+<!ENTITY % REQUIREDIDATTR "id NMTOKEN #REQUIRED" >
+
+
+<!--
+Configure Element.
+This is the root element that specifies the class of object that
+can be configured:
+
+    <Configure class="com.acme.MyClass"> ... </Configure>
+-->
+<!ELEMENT Configure (%CONFIG;)* >
+<!ATTLIST Configure %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Set Element.
+This element maps to a call to a setter method or field on the current object.
+The name and optional type attributes are used to select the setter
+method. If the name given is xxx, then a setXxx method is used, or
+the xxx field is used of setXxx cannot be found.
+A Set element can contain value text and/or the value objects returned
+by other elements such as Call, New, SystemProperty, etc.
+If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+
+A Set with a class attribute is treated as a static set method invocation.
+-->
+<!ELEMENT Set ( %VALUE; )* >
+<!ATTLIST Set %NAMEATTR; %TYPEATTR; %IMPLIEDCLASSATTR; >
+
+
+<!--
+Get Element.
+This element maps to a call to a getter method or field on the current object.
+The name attribute is used to select the get method.
+If the name given is xxx, then a getXxx method is used, or
+the xxx field is used if getXxx cannot be found.
+A Get element can contain other elements such as Set, Put, Call, etc.
+which act on the object returned by the get call.
+
+A Get with a class attribute is treated as a static get method or field.
+-->
+<!ELEMENT Get (%CONFIG;)*>
+<!ATTLIST Get %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Put Element.
+This element maps to a call to a put method on the current object,
+which must implement the Map interface. The name attribute is used
+as the put key and the optional type attribute can force the type
+of the value.
+
+A Put element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Put ( %VALUE; )* >
+<!ATTLIST Put %NAMEATTR; %TYPEATTR; >
+
+
+<!--
+Call Element.
+This element maps to an arbitrary call to a method on the current object,
+The name attribute and Arg elements are used to select the method.
+
+A Call element can contain a sequence of Arg elements followed by
+a sequence of other elements such as Set, Put, Call, etc. which act on any object
+returned by the original call:
+
+ <Call id="o2" name="test">
+   <Arg>value1</Arg>
+   <Set name="Test">Value2</Set>
+ </Call>
+
+This is equivalent to:
+
+ Object o2 = o1.test("value1");
+ o2.setTest("value2");
+
+A Call with a class attribute is treated as a static call.
+-->
+<!ELEMENT Call (Arg*,(%CONFIG;)*)>
+<!ATTLIST Call %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR;>
+
+
+<!--
+Arg Element.
+This element defines a positional argument for the Call element.
+The optional type attribute can force the type of the value.
+
+An Arg element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Arg ( %VALUE; )* >
+<!ATTLIST Arg %TYPEATTR; %IMPLIEDNAMEATTR;  >
+
+
+<!--
+New Element.
+This element allows the creation of a new object as part of a
+value for elements such as Set, Put, Arg, etc. The class attribute determines
+the type of the new object and the contained Arg elements
+are used to select the constructor for the new object.
+
+A New element can contain a sequence of Arg elements followed by
+a sequence of elements such as Set, Put, Call, etc. elements
+which act on the new object:
+
+ <New id="o" class="com.acme.MyClass">
+   <Arg>value1</Arg>
+   <Set name="test">Value2</Set>
+ </New>
+
+This is equivalent to:
+
+ Object o = new com.acme.MyClass("value1");
+ o.setTest("Value2");
+-->
+<!ELEMENT New (Arg*,(%CONFIG;)*)>
+<!ATTLIST New %CLASSATTR; %IDATTR;>
+
+
+<!--
+Ref Element.
+This element allows a previously created object to be referenced by id.
+A Ref element can contain a sequence of elements such as Set, Put, Call, etc.
+which act on the referenced object:
+
+ <Ref id="myobject">
+   <Set name="Test">Value2</Set>
+ </New>
+-->
+<!ELEMENT Ref ((%CONFIG;)*)>
+<!ATTLIST Ref %REQUIREDIDATTR;>
+
+
+<!--
+Array Element.
+This element allows the creation of a new array as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Array type="java.lang.String">
+   <Item>value0</Item>
+   <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+ </Array>
+
+This is equivalent to:
+ String[] a = new String[] { "value0", new String("value1") };
+-->
+<!ELEMENT Array (Item*)>
+<!ATTLIST Array %TYPEATTR; %IDATTR; >
+
+
+<!--
+Map Element.
+This element allows the creation of a new map as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Map>
+   <Entry>
+     <Item>keyName</Item>
+     <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+   </Entry>
+ </Map>
+
+This is equivalent to:
+ Map m = new HashMap();
+ m.put("keyName", new String("value1"));
+-->
+<!ELEMENT Map (Entry*)>
+<!ATTLIST Map %IDATTR; >
+<!ELEMENT Entry (Item,Item)>
+
+
+<!--
+Item Element.
+This element defines an entry for the Array or Map Entry elements.
+The optional type attribute can force the type of the value.
+
+An Item element can contain value text and/or the value object of
+elements such as Call, New, SystemProperty, etc. If no value type
+is specified, then white space is trimmed out of the value.
+If it contains multiple value elements they are added as strings
+before being converted to any specified type.
+-->
+<!ELEMENT Item ( %VALUE; )* >
+<!ATTLIST Item %TYPEATTR; %IDATTR; >
+
+
+<!--
+System Property Element.
+This element allows JVM System properties to be retrieved as
+part of the value of elements such as Set, Put, Arg, etc.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+
+ <SystemProperty name="Test" default="value" />
+
+This is equivalent to:
+
+ System.getProperty("Test","value");
+-->
+<!ELEMENT SystemProperty EMPTY>
+<!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %IDATTR;>
+
+
+<!--
+Property Element.
+This element allows arbitrary properties to be retrieved by name.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+
+A Property element can contain a sequence of elements such as Set, Put, Call, etc.
+which act on the retrieved object:
+
+ <Property name="Server">
+   <Call id="jdbcIdMgr" name="getAttribute">
+     <Arg>jdbcIdMgr</Arg>
+   </Call>
+ </Property>
+-->
+<!ELEMENT Property ((%CONFIG;)*)>
+<!ATTLIST Property %NAMEATTR; %DEFAULTATTR; %IDATTR;>
diff --git a/src/resources/org/eclipse/jetty/xml/configure_7_6.dtd b/src/resources/org/eclipse/jetty/xml/configure_7_6.dtd
new file mode 100644
index 0000000..04bf422
--- /dev/null
+++ b/src/resources/org/eclipse/jetty/xml/configure_7_6.dtd
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+This is the document type descriptor for the
+org.eclipse.XmlConfiguration class.  It allows a java object to be
+configured by with a sequence of Set, Put and Call elements.  These tags are
+mapped to methods on the object to be configured as follows:
+
+  <Set  name="Test">value</Set>              ==  obj.setTest("value");
+  <Put  name="Test">value</Put>              ==  obj.put("Test","value");
+  <Call name="test"><Arg>value</Arg></Call>  ==  obj.test("value");
+
+Values themselves may be configured objects that are created with the
+<New> tag or returned from a <Call> tag.
+
+Values are matched to arguments on a best effort approach, but types
+my be specified if a match is not achieved.
+
+-->
+
+<!ENTITY % CONFIG "Set|Get|Put|Call|New|Ref|Array|Map|Property">
+<!ENTITY % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|Env|Property">
+
+<!ENTITY % TYPEATTR "type CDATA #IMPLIED " > <!-- String|Character|Short|Byte|Integer|Long|Boolean|Float|Double|char|short|byte|int|long|boolean|float|double|URL|InetAddress|InetAddrPort| #classname -->
+<!ENTITY % IMPLIEDCLASSATTR "class NMTOKEN #IMPLIED" >
+<!ENTITY % CLASSATTR "class NMTOKEN #REQUIRED" >
+<!ENTITY % NAMEATTR "name NMTOKEN #REQUIRED" >
+<!ENTITY % IMPLIEDNAMEATTR "name NMTOKEN #IMPLIED" >
+<!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" >
+<!ENTITY % IDATTR "id NMTOKEN #IMPLIED" >
+<!ENTITY % REQUIREDIDATTR "id NMTOKEN #REQUIRED" >
+
+
+<!--
+Configure Element.
+This is the root element that specifies the class of object that
+can be configured:
+
+    <Configure class="com.acme.MyClass"> ... </Configure>
+-->
+<!ELEMENT Configure (%CONFIG;)* >
+<!ATTLIST Configure %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Set Element.
+This element maps to a call to a setter method or field on the current object.
+The name and optional type attributes are used to select the setter
+method. If the name given is xxx, then a setXxx method is used, or
+the xxx field is used of setXxx cannot be found.
+A Set element can contain value text and/or the value objects returned
+by other elements such as Call, New, SystemProperty, etc.
+If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+
+A Set with a class attribute is treated as a static set method invocation.
+-->
+<!ELEMENT Set ( %VALUE; )* >
+<!ATTLIST Set %NAMEATTR; %TYPEATTR; %IMPLIEDCLASSATTR; >
+
+
+<!--
+Get Element.
+This element maps to a call to a getter method or field on the current object.
+The name attribute is used to select the get method.
+If the name given is xxx, then a getXxx method is used, or
+the xxx field is used if getXxx cannot be found.
+A Get element can contain other elements such as Set, Put, Call, etc.
+which act on the object returned by the get call.
+
+A Get with a class attribute is treated as a static get method or field.
+-->
+<!ELEMENT Get (%CONFIG;)*>
+<!ATTLIST Get %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; >
+
+
+<!--
+Put Element.
+This element maps to a call to a put method on the current object,
+which must implement the Map interface. The name attribute is used
+as the put key and the optional type attribute can force the type
+of the value.
+
+A Put element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Put ( %VALUE; )* >
+<!ATTLIST Put %NAMEATTR; %TYPEATTR; >
+
+
+<!--
+Call Element.
+This element maps to an arbitrary call to a method on the current object,
+The name attribute and Arg elements are used to select the method.
+
+A Call element can contain a sequence of Arg elements followed by
+a sequence of other elements such as Set, Put, Call, etc. which act on any object
+returned by the original call:
+
+ <Call id="o2" name="test">
+   <Arg>value1</Arg>
+   <Set name="Test">Value2</Set>
+ </Call>
+
+This is equivalent to:
+
+ Object o2 = o1.test("value1");
+ o2.setTest("value2");
+
+A Call with a class attribute is treated as a static call.
+-->
+<!ELEMENT Call (Arg*,(%CONFIG;)*)>
+<!ATTLIST Call %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR;>
+
+
+<!--
+Arg Element.
+This element defines a positional argument for the Call element.
+The optional type attribute can force the type of the value.
+
+An Arg element can contain value text and/or value elements such as Call,
+New, SystemProperty, etc. If no value type is specified, then white
+space is trimmed out of the value. If it contains multiple value
+elements they are added as strings before being converted to any
+specified type.
+-->
+<!ELEMENT Arg ( %VALUE; )* >
+<!ATTLIST Arg %TYPEATTR; %IMPLIEDNAMEATTR;  >
+
+
+<!--
+New Element.
+This element allows the creation of a new object as part of a
+value for elements such as Set, Put, Arg, etc. The class attribute determines
+the type of the new object and the contained Arg elements
+are used to select the constructor for the new object.
+
+A New element can contain a sequence of Arg elements followed by
+a sequence of elements such as Set, Put, Call, etc. elements
+which act on the new object:
+
+ <New id="o" class="com.acme.MyClass">
+   <Arg>value1</Arg>
+   <Set name="test">Value2</Set>
+ </New>
+
+This is equivalent to:
+
+ Object o = new com.acme.MyClass("value1");
+ o.setTest("Value2");
+-->
+<!ELEMENT New (Arg*,(%CONFIG;)*)>
+<!ATTLIST New %CLASSATTR; %IDATTR;>
+
+
+<!--
+Ref Element.
+This element allows a previously created object to be referenced by id.
+A Ref element can contain a sequence of elements such as Set, Put, Call, etc.
+which act on the referenced object:
+
+ <Ref id="myobject">
+   <Set name="Test">Value2</Set>
+ </New>
+-->
+<!ELEMENT Ref ((%CONFIG;)*)>
+<!ATTLIST Ref %REQUIREDIDATTR;>
+
+
+<!--
+Array Element.
+This element allows the creation of a new array as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Array type="java.lang.String">
+   <Item>value0</Item>
+   <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+ </Array>
+
+This is equivalent to:
+ String[] a = new String[] { "value0", new String("value1") };
+-->
+<!ELEMENT Array (Item*)>
+<!ATTLIST Array %TYPEATTR; %IDATTR; >
+
+
+<!--
+Map Element.
+This element allows the creation of a new map as part of a
+value of elements such as Set, Put, Arg, etc. The type attribute determines
+the type of the new array and the contained Item elements
+are used for each element of the array:
+
+ <Map>
+   <Entry>
+     <Item>keyName</Item>
+     <Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
+   </Entry>
+ </Map>
+
+This is equivalent to:
+ Map m = new HashMap();
+ m.put("keyName", new String("value1"));
+-->
+<!ELEMENT Map (Entry*)>
+<!ATTLIST Map %IDATTR; >
+<!ELEMENT Entry (Item,Item)>
+
+
+<!--
+Item Element.
+This element defines an entry for the Array or Map Entry elements.
+The optional type attribute can force the type of the value.
+
+An Item element can contain value text and/or the value object of
+elements such as Call, New, SystemProperty, etc. If no value type
+is specified, then white space is trimmed out of the value.
+If it contains multiple value elements they are added as strings
+before being converted to any specified type.
+-->
+<!ELEMENT Item ( %VALUE; )* >
+<!ATTLIST Item %TYPEATTR; %IDATTR; >
+
+
+<!--
+System Property Element.
+This element allows JVM System properties to be retrieved as
+part of the value of elements such as Set, Put, Arg, etc.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+
+ <SystemProperty name="Test" default="value" />
+
+This is equivalent to:
+
+ System.getProperty("Test","value");
+-->
+<!ELEMENT SystemProperty EMPTY>
+<!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %IDATTR;>
+
+
+<!--
+Environment variable Element.
+This element allows OS Environment variables to be retrieved as
+part of the value of elements such as Set, Put, Arg, etc.
+The name attribute specifies the env variable name and the optional
+default argument provides a default value.
+
+ <Env name="Test" default="value" />
+
+This is equivalent to:
+
+ String v=System.getEnv("Test");
+ if (v==null) v="value";
+
+-->
+<!ELEMENT Env EMPTY>
+<!ATTLIST Env %NAMEATTR; %DEFAULTATTR; %IDATTR;>
+
+
+<!--
+Property Element.
+This element allows arbitrary properties to be retrieved by name.
+The name attribute specifies the property name and the optional
+default argument provides a default value.
+
+A Property element can contain a sequence of elements such as Set, Put, Call, etc.
+which act on the retrieved object:
+
+ <Property name="Server">
+   <Call id="jdbcIdMgr" name="getAttribute">
+     <Arg>jdbcIdMgr</Arg>
+   </Call>
+ </Property>
+-->
+<!ELEMENT Property ((%CONFIG;)*)>
+<!ATTLIST Property %NAMEATTR; %DEFAULTATTR; %IDATTR;>
