diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..3b09b70
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="org/eclipse/jetty/jmx/|org/eclipse/jetty/util/log/jmx/|org/eclipse/jetty/server/handler/jmx/|org/eclipse/jetty/server/jmx/|org/eclipse/jetty/server/session/jmx/|org/eclipse/jetty/servlet/jmx/|org/eclipse/jetty/security/SpnegoLoginService.java|org/eclipse/jetty/security/SpnegoUserIdentity.java|org/eclipse/jetty/security/SpnegoUserPrincipal.java|org/eclipse/jetty/server/session/JDBCSessionIdManager.java|org/eclipse/jetty/server/session/JDBCSessionManager.java|org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java|org/eclipse/jetty/util/preventers/AWTLeakPreventer.java" including="**/*.java" kind="src" path="src/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/javax.servlet-3.0.0.v201112011016.jar" sourcepath="lib/javax.servlet-3.0.0.v201112011016-sources.jar"/>
+	<classpathentry kind="lib" path="lib/slf4j-api-1.6.1.jar"/>
+	<classpathentry kind="lib" path="lib/slf4j-jdk14-1.6.1.jar"/>
+	<classpathentry kind="lib" path="lib/jetty-util-6.1.26.jar"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..612c8cd
--- /dev/null
+++ b/.project
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+  <name>jetty</name>
+  <projects>
+  </projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..7341ab1
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..f7ed668
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,55 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+NON_ANDROID_SRC := \
+	src/java/org/eclipse/jetty/jmx/ConnectorServer.java \
+	src/java/org/eclipse/jetty/jmx/MBeanContainer.java \
+	src/java/org/eclipse/jetty/jmx/ObjectMBean.java \
+	src/java/org/eclipse/jetty/servlet/jmx/ServletMappingMBean.java \
+	src/java/org/eclipse/jetty/servlet/jmx/FilterMappingMBean.java \
+	src/java/org/eclipse/jetty/servlet/jmx/HolderMBean.java \
+	src/java/org/eclipse/jetty/util/log/jmx/LogMBean.java \
+	src/java/org/eclipse/jetty/server/jmx/ServerMBean.java \
+	src/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java \
+	src/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java \
+	src/java/org/eclipse/jetty/servlet/StatisticsServlet.java \
+	src/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java \
+	src/java/org/eclipse/jetty/security/SpnegoUserIdentity.java \
+	src/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java \
+	src/java/org/eclipse/jetty/security/SpnegoLoginService.java \
+	src/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java \
+	src/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java \
+	src/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java \
+	src/java/org/eclipse/jetty/servlet/listener/IntrospectorCleaner.java \
+	src/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java \
+	src/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java \
+	src/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+
+LOCAL_SRC_FILES := $(filter-out $(NON_ANDROID_SRC), \
+	$(call all-java-files-under, src))
+
+LOCAL_MODULE := jetty
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	jetty-util \
+	servlet-api \
+	slf4j-api \
+	slf4j-jdk14
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#############################################################
+# Pre-built dependency jars
+#############################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+	servlet-api:lib/javax.servlet-3.0.0.v201112011016.jar \
+	jetty-util:lib/jetty-util-6.1.26.jar \
+	slf4j-api:lib/slf4j-api-1.6.1.jar \
+	slf4j-jdk14:lib/slf4j-jdk14-1.6.1.jar \
+
+include $(BUILD_MULTI_PREBUILT)
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/MODULE_LICENSE_ECLIPSE1 b/MODULE_LICENSE_ECLIPSE1
new file mode 100644
index 0000000..79e486c
--- /dev/null
+++ b/MODULE_LICENSE_ECLIPSE1
@@ -0,0 +1,70 @@
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/MODULE_LICENSE_SLF4J b/MODULE_LICENSE_SLF4J
new file mode 100644
index 0000000..37050c9
--- /dev/null
+++ b/MODULE_LICENSE_SLF4J
@@ -0,0 +1,21 @@
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+
+ 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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..66eeea2
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,56 @@
+==============================================================
+ Jetty Web Container
+ Copyright 1995-2014 Mort Bay Consulting Pty Ltd.
+==============================================================
+
+The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd
+unless otherwise noted.
+
+Jetty is dual licensed under both
+
+  * The Apache 2.0 License
+    http://www.apache.org/licenses/LICENSE-2.0.html
+
+      and
+
+  * The Eclipse Public 1.0 License
+    http://www.eclipse.org/legal/epl-v10.html
+
+Jetty may be distributed under either license.
+
+The javax.servlet package used was sourced from the Apache
+Software Foundation and is distributed under the apache 2.0
+license.
+
+The UnixCrypt.java code implements the one way cryptography used by
+Unix systems for simple password protection.  Copyright 1996 Aki Yoshida,
+modified April 2001  by Iris Van den Broeke, Daniel Deville.
+Permission to use, copy, modify and distribute UnixCrypt
+for non-commercial or commercial purposes and without fee is
+granted provided that the copyright notice appears in all copies.
+
+==============================================================
+ SLF4J
+ Copyright (c) 2004-2013 QOS.ch
+==============================================================
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+
+ 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.
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..012a796
--- /dev/null
+++ b/README.android
@@ -0,0 +1,48 @@
+URL: http://www.eclipse.org/jetty/
+Version: 8.1.15.v20140411
+License: Apache 2 or Eclipse 1.0 (see NOTICE file for information on licensing for dependencies)
+
+Description
+-------------------
+Jetty is a lightweight, servlet container implementation in Java.
+
+The pom.xml_saved file is included as a reference for bringing down the complete, original source
+code and dependencies using maven. Note, the file structure generated with pom.xml_saved will
+not match the current file structure, as noted in the Local Modifcations section. Furthermore, not
+all of the original sources are compatible with the android runtime. Incompatible source files are
+listed in the Android.mk file under "NON_ANDROID_SRC".
+
+Local Modifcations
+-------------------
+The complete original source code was downloaded using pom.xml_saved. The pom file creates a separate
+directory for each jetty package. the src directory of the relevant packages were merged into a single
+src directory. The relevant packages which were merged into the single src directory are:
+-jetty-client
+-jetty-continuation
+-jetty-http
+-jetty-io
+-jetty-security
+-jetty-server
+-jetty-servlet
+-jetty-servlets
+-jetty-util
+-jetty-webapp
+-jetty-websocket
+-jetty-xml
+
+All other packages were discarded. Prebuilt dependencies (SLF4J, the servlet api and jetty utils)
+were copied from the maven repository into the lib directory. pom files and sha1 files are included
+with the prebuilt dependencies for reference.
+
+The eclipse files were created manually. The .classpath file includes the prebuilt dependencies in the
+lib directory and excludes the sources files that are not compatible with the android runtime (see
+"NON_ANDROID_SRC" in the Android.mk file). the .project file was copied from one of the .project
+files created by maven.
+
+Updating this Project
+-------------------
+To update this project, the updated packages should be fetched from maven and their src directories should
+be merged with the local src directory. Any new or updated prebuilt dependencies should be copied into
+the lib directory. The Android.mk file (.classpath file for eclipse) should be updated accordingly. It
+may be necessary to add more files to "NON_ANDROID_SRC" in the Android.mk file (the excluding element
+in .classpath for eclipse).
diff --git a/VERSION.txt b/VERSION.txt
new file mode 100644
index 0000000..c41d18f
--- /dev/null
+++ b/VERSION.txt
@@ -0,0 +1,6209 @@
+jetty-8.1.15.v20140411 - 11 April 2014
+ + 397167 Remote Access documentation is wrong
+ + 419799 complete after exceptions thrown from async error pages
+ + 420776 complete error pages after startAsync
+ + 421197 fix method comment and ensure close synchronized
+ + 422137 Added maxQueued to QueuedThreadPool MBean
+ + 424180 improve bad message errors
+ + 425038 WebSocketClient leaks file handles when exceptions are thrown from
+   open()
+ + 425551 Memory Leak in SelectConnector$ConnectTimeout.expired.
+ + 426658 backport Bug 425930 to jetty-8
+ + 427761 allow endpoints to be interrupted
+ + 428708 JDBCSessionIdManager when clearing expired sessions failed, jetty
+   should still be able to startup
+ + 428710 JDBCSession(Id)Manager use 'read committed isolation level'
+ + 430968 Use wrapped response with async dispatch
+ + 432452 ConnectHandler does not timeout sockets in FIN_WAIT2.
+
+jetty-8.1.14.v20131031 - 31 October 2013
+ + 417772 fixed low resources idle timeout
+ + 418636 Name anonymous filter and holders with classname-hashcode
+ + 419432 Allow to override the SslContextFactory on a per-destination basis.
+ + 420048 DefaultServlet alias checks configured resourceBase
+ + 420530 AbstractLoginModule never fails a login
+
+jetty-7.6.14.v20131031 - 31 October 2013
+ + 417772 fixed low resources idle timeout
+ + 418636 Name anonymous filter and holders with classname-hashcode
+ + 419432 Allow to override the SslContextFactory on a per-destination basis.
+ + 420048 DefaultServlet alias checks configured resourceBase
+ + 420530 AbstractLoginModule never fails a login
+
+jetty-8.1.13.v20130916 - 16 September 2013
+ + 412629 PropertyFileLoginModule doesn't cache user configuration file even
+   for refreshInterval=0
+ + 413484 setAttribute in nosql session management better handles _dirty status
+ + 413684 deprecated unsafe alias checkers
+ + 414235 RequestLogHandler configured on a context fails to handle forwarded
+   requests
+ + 414393 StringIndexOutofBoundsException with > 8k multipart content without
+   CR or LF
+ + 414431 Avoid debug NPE race
+ + 414507 Ensure AnnotationParser ignores parent dir hierarchy when checking
+   for hidden dirnames
+ + 414652 WebSocket's sendMessage() may hang on congested connections.
+ + 415192 <jsp-file> maps to JspPropertyGroupServlet instead of JspServlet
+ + 415401 Add XmlConfiguration.initializeDefaults that allows to set default
+   values for any XmlConfiguration that may be overridden in the config file
+ + 416266 HttpServletResponse.encodeURL() encodes on first request when only
+   SessionTrackingMode.COOKIE is used
+ + 416585 WebInfConfiguration examines webapp classloader first instead of its
+   parent when looking for container jars
+ + 416787 StringIndexOutOfBounds with a pathMap of ""
+ + 416990 JMX names statically unique
+
+jetty-7.6.13.v20130916 - 16 September 2013
+ + 412629 PropertyFileLoginModule doesn't cache user configuration file even
+   for refreshInterval=0
+ + 413484 setAttribute in nosql session management better handles _dirty status
+ + 413684 deprecated unsafe alias checkers
+ + 414235 RequestLogHandler configured on a context fails to handle forwarded
+   requests
+ + 414393 StringIndexOutofBoundsException with > 8k multipart content without
+   CR or LF
+ + 414431 Avoid debug NPE race
+ + 414507 Ensure AnnotationParser ignores parent dir hierarchy when checking
+   for hidden dirnames
+ + 414652 WebSocket's sendMessage() may hang on congested connections.
+ + 415192 <jsp-file> maps to JspPropertyGroupServlet instead of JspServlet
+ + 415401 Add XmlConfiguration.initializeDefaults that allows to set default
+   values for any XmlConfiguration that may be overridden in the config file
+ + 416585 WebInfConfiguration examines webapp classloader first instead of its
+   parent when looking for container jars
+ + 416990 JMX names statically unique
+
+jetty-8.1.12.v20130726 - 26 July 2013
+ + 396706 CGI support parameters
+ + 397193 MongoSessionManager refresh updates last access time
+ + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7
+ + 408529 Etags set in 304 response
+ + 408600 set correct jetty.url in all pom files
+ + 408642 setContentType from addHeader
+ + 408662 In pax-web servlet services requests even if init() has not finished
+   running
+ + 408806 getParameter returns null on Multipart request if called before
+   request.getPart()/getParts()
+ + 408909 GzipFilter setting of headers when reset and/or not compressed
+ + 409028 Jetty HttpClient does not work with proxy CONNECT method.
+ + 409133 Empty <welcome-file> causes StackOverflowError
+ + 409436 NPE on context restart using dynamic servlet registration
+ + 409449 Ensure servlets, filters and listeners added via dynamic
+   registration, annotations or descriptors are cleaned on context restarts
+ + 409556 FileInputStream not closed in DirectNIOBuffer
+ + 410405 Avoid NPE for requestDispatcher(../)
+ + 410630 MongoSessionManager conflicting session update op
+ + 410750 NoSQLSessions: implement session context data persistence across
+   server restarts
+ + 410893 async support defaults to false for spec created servlets and filters
+ + 411135 HttpClient may send proxied https requests to the proxy instead of
+   the target server.
+ + 411216 RequestLogHandler handles async completion
+ + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued
+   parameters 411459  MultiPartFilter.Wrapper getParameter should use charset
+   encoding of part
+ + 411755 MultiPartInputStreamParser fails on base64 encoded content
+ + 411909 GzipFilter flushbuffer() results in erroneous finish() call
+ + 412712 HttpClient does not send the terminal chunk after partial writes.
+ + 412750 HttpClient close expired connections fix
+ + 413371 Default JSON.Converters for List and Set.
+ + 413372 JSON Enum uses name rather than toString()
+ + 413684 Trailing slash shows JSP source
+ + 413812 Make RateTracker serializable
+
+jetty-7.6.12.v20130726 - 26 July 2013
+ + 396706 CGI support parameters
+ + 397193 MongoSessionManager refresh updates last access time
+ + 407342 ReloadedSessionMissingClassTest uses class compiled with jdk7
+ + 408529 Etags set in 304 response
+ + 408600 set correct jetty.url in all pom files
+ + 408642 setContentType from addHeader
+ + 408662 In pax-web servlet services requests even if init() has not finished
+   running
+ + 408909 GzipFilter setting of headers when reset and/or not compressed
+ + 409028 Jetty HttpClient does not work with proxy CONNECT method.
+ + 409133 Empty <welcome-file> causes StackOverflowError
+ + 409556 FileInputStream not closed in DirectNIOBuffer
+ + 410630 MongoSessionManager conflicting session update op
+ + 410750 NoSQLSessions: implement session context data persistence across
+   server restarts
+ + 411135 HttpClient may send proxied https requests to the proxy instead of
+   the target server.
+ + 411216 RequestLogHandler handles async completion
+ + 411458 MultiPartFilter getParameterMap doesn't preserve multivalued
+   parameters 411459  MultiPartFilter.Wrapper getParameter should use charset
+   encoding of part
+ + 411755 MultiPartInputStreamParser fails on base64 encoded content
+ + 411909 GzipFilter flushbuffer() results in erroneous finish() call
+ + 412712 HttpClient does not send the terminal chunk after partial writes.
+ + 412750 HttpClient close expired connections fix
+ + 413371 Default JSON.Converters for List and Set.
+ + 413372 JSON Enum uses name rather than toString()
+ + 413684 Trailing slash shows JSP source
+ + 413812 Make RateTracker serializable
+
+jetty-8.1.11.v20130520 - 20 May 2013
+ + 402844 STOP.PORT & STOP.KEY behaviour has changed
+ + 403281 jetty.sh waits for started or failure before returning
+ + 403513 jetty:run goal cannot be executed twice during the maven build
+ + 403570 Asynchronous Request Logging
+ + 404010 fix cast exception in mongodb session manager
+ + 404128 Add Vary headers rather than set them
+ + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if
+   listFiles() returns null
+ + 404325 data constraint redirection does send default port
+ + 404517 Close connection if request received after half close
+ + 404789 Support IPv6 addresses in DoSFilter white list.
+ + 404958 Fixed Resource.newSystemResource striped / handling
+ + 405281 allow filemappedbuffers to not be used
+ + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest
+ + 406437 Digest Auth supports out of order nc
+ + 406618 Jetty startup in OSGi Equinox fails when using option
+   jetty.home.bundle=org.eclipse.jetty.osgi.boot
+ + 406923 CR line termination
+ + 407136 @PreDestroy called after Servlet.destroy()
+ + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager
+ + 407931 Add toggle for failing on servlet availability
+ + 407976 JDBCSessionIdManager potentially leaves server in bad state after
+   startup
+ + 408077 HashSessionManager leaves file handles open after being stopped
+ + 408446 Multipart parsing issue with boundry and charset in ContentType
+   header
+
+jetty-8.1.10.v20130312 - 12 March 2013
+ + 376273 Early EOF because of SSL Protocol Error on
+   https://api-3t.paypal.com/nvp.
+ + 381521 allow compress methods to be configured
+ + 392129 fixed handling of timeouts after startAsync
+ + 394064 ensure that JarFile instances are closed on JarFileResource.release()
+ + 398649 ServletContextListener.contextDestroyed() is not called on
+   ContextHandler unregistration
+ + 399703 made encoding error handling consistent
+ + 399799 do not hold lock while calling invalidation listeners
+ + 399967 Shutdown hook calls destroy
+ + 400040 NullPointerException in HttpGenerator.prepareBuffers
+ + 400142 ConcurrentModificationException in JDBC SessionManger
+ + 400144 When loading a session fails the JDBCSessionManger produces duplicate
+   session IDs
+ + 400312 ServletContextListener.contextInitialized() is not called when added
+   in ServletContainerInitializer.onStartup
+ + 400457 Thread context classloader hierarchy not searched when finding
+   webapp's java:comp/env
+ + 400859 limit max size of writes from cached content
+ + 401211 Remove requirement for jetty-websocket.jar in WEB-INF/lib
+ + 401317 Make Safari 5.x websocket support minVersion level error more clear
+ + 401382 Prevent parseAvailable from parsing next chunk when previous has not
+   been consumed. Handle no content-type in chunked request.
+ + 401474 Performance problem in org.eclipse.jetty.annotation.AnnotationParser
+ + 401485 zip file closed exception
+ + 401531 StringIndexOutOfBoundsException for "/*" <url-pattern> of
+   <jsp-property-group> fix for multiple mappings to *.jsp
+ + 401908 Enhance DosFilter to allow dynamic configuration of attributes.
+ + 402048 org.eclipse.jetty.server.ShutdownMonitor doesn't stop after the jetty
+   server is stopped
+ + 402485 reseed secure random
+ + 402735 jetty.sh to support status which is == check
+ + 402833 Test harness for global error page and hide exception message from
+   reason string
+
+jetty-7.6.11.v20130520 - 20 May 2013
+ + 402844 STOP.PORT & STOP.KEY behaviour has changed
+ + 403281 jetty.sh waits for started or failure before returning
+ + 403513 jetty:run goal cannot be executed twice during the maven build
+ + 403570 Asynchronous Request Logging
+ + 404010 fix cast exception in mongodb session manager
+ + 404128 Add Vary headers rather than set them
+ + 404283 org.eclipse.jetty.util.Scanner.scanFile() dies with an NPE if
+   listFiles() returns null
+ + 404325 data constraint redirection does send default port
+ + 404517 Close connection if request received after half close
+ + 404789 Support IPv6 addresses in DoSFilter white list.
+ + 404958 Fixed Resource.newSystemResource striped / handling
+ + 405281 allow filemappedbuffers to not be used
+ + 405537 NPE in rendering JSP using SPDY and wrapped ServletRequest
+ + 406437 Digest Auth supports out of order nc
+ + 406923 CR line termination
+ + 407136 @PreDestroy called after Servlet.destroy()
+ + 407173 java.lang.IllegalStateException: null when using JDBCSessionManager
+ + 407976 JDBCSessionIdManager potentially leaves server in bad state after
+   startup
+ + 408077 HashSessionManager leaves file handles open after being stopped
+ + 408446 Multipart parsing issue with boundry and charset in ContentType
+   header
+
+jetty-7.6.10.v20130312 - 12 March 2013
+ + 376273 Early EOF because of SSL Protocol Error on
+   https://api-3t.paypal.com/nvp.
+ + 381521 allow compress methods to be configured
+ + 394064 ensure that JarFile instances are closed on JarFileResource.release()
+ + 398649 ServletContextListener.contextDestroyed() is not called on
+   ContextHandler unregistration
+ + 399703 made encoding error handling consistent
+ + 399799 do not hold lock while calling invalidation listeners
+ + 399967 Shutdown hook calls destroy
+ + 400040 NullPointerException in HttpGenerator.prepareBuffers
+ + 400142 ConcurrentModificationException in JDBC SessionManger
+ + 400144 When loading a session fails the JDBCSessionManger produces duplicate
+   session IDs
+ + 400457 Thread context classloader hierarchy not searched when finding
+   webapp's java:comp/env
+ + 400859 limit max size of writes from cached content
+ + 401211 Remove requirement for jetty-websocket.jar in WEB-INF/lib
+ + 401317 Make Safari 5.x websocket support minVersion level error more clear
+ + 401382 Prevent parseAvailable from parsing next chunk when previous has not
+   been consumed. Handle no content-type in chunked request.
+ + 401474 Performance problem in org.eclipse.jetty.annotation.AnnotationParser
+ + 401531 StringIndexOutOfBoundsException for "/*" <url-pattern> of
+   <jsp-property-group> fix for multiple mappings to *.jsp
+ + 401908 Enhance DosFilter to allow dynamic configuration of attributes.
+ + 402048 org.eclipse.jetty.server.ShutdownMonitor doesn't stop after the jetty
+   server is stopped
+ + 402485 reseed secure random
+ + 402735 jetty.sh to support status which is == check
+ + 402833 Test harness for global error page and hide exception message from
+   reason string
+
+jetty-8.1.9.v20130131 - 31 January 2013
+ + 362226 HttpConnection "wait" call causes thread resource exhaustion
+ + 367638 throw exception for excess form keys
+ + 381521 Only set Vary header when content could be compressed
+ + 382237 support non java JSON classes
+ + 391248 fixing localhost checking in statistics servlet
+ + 391249 fix for invalid XML node dispatchedTimeMean in statistics servlet
+ + 391345 fix missing br tag in statistics servlet
+ + 391623 Add option to --stop to wait for target jetty to stop
+ + 392417 Prevent Cookie parsing interpreting unicode chars
+ + 392492 expect headers only examined for requests>=HTTP/1.1
+ + 393075 1xx 204 and 304 ignore all headers suggesting content
+ + 393158 java.lang.IllegalStateException when sending an empty InputStream
+ + 393220 remove dead code from ServletHandler and log ServletExceptions in
+   warn instead of debug
+ + 393947 additional tests
+ + 393968 fix typo in javadoc
+ + 394294 A web-bundle started before jetty-osgi should be deployed as a webapp
+   when jetty-osgi starts
+ + 394514 Preserve URI parameters in sendRedirect
+ + 394541 remove continuation jar from distro, add as dep to test-jetty-webapp
+ + 394719 remove regex from classpath matching
+ + 394811 Make JAASLoginService log login failures to DEBUG instead of WARN.
+   Same for some other exceptions.
+ + 394829 Session can not be restored after SessionManager.setIdleSavePeriod
+   has saved the session
+ + 394839 Allow multipart mime with no boundary
+ + 394870 Make enablement of remote access to test webapp configurable in
+   override-web.xml
+ + 395215 Multipart mime with just LF and no CRLF
+ + 395380 add ValidUrlRule to jetty-rewrite
+ + 395394 allow logging from boot classloader
+ + 396253 FilterRegistration wrong order
+ + 396459 Log specific message for empty request body for multipart mime
+   requests
+ + 396500 HttpClient Exchange takes forever to complete when less content sent
+   than Content-Length
+ + 396574 add JETTY_HOME as a location for pid to be found
+ + 396886 MultiPartFilter strips bad escaping on filename="..."
+ + 397110 Accept %uXXXX encodings in URIs
+ + 397111 Tolerate empty or excessive whitespace preceeding MultiParts
+ + 397112 Requests with byte-range throws NPE if requested file has no mimetype
+   (eg no file extension)
+ + 397130 maxFormContentSize set in jetty.xml is ignored
+ + 397190 improve ValidUrlRule to iterate on codepoints
+ + 397321 Wrong condition in default start.config for annotations
+ + 397535 Support pluggable alias checking to support symbolic links
+ + 398337 UTF-16 percent encoding in UTF-16 form content
+ + 399132 check parent dir of session store against file to be removed
+ + JETTY-1533 handle URL with no path
+
+jetty-7.6.9.v20130131 - 31 January 2013
+ + 362226 HttpConnection "wait" call causes thread resource exhaustion
+ + 367638 throw exception for excess form keys
+ + 381521 Only set Vary header when content could be compressed
+ + 382237 support non java JSON classes
+ + 391248 fixing localhost checking in statistics servlet
+ + 391249 fix for invalid XML node dispatchedTimeMean in statistics servlet
+ + 391345 fix missing br tag in statistics servlet
+ + 391623 Add option to --stop to wait for target jetty to stop
+ + 392417 Prevent Cookie parsing interpreting unicode chars
+ + 392492 expect headers only examined for requests>=HTTP/1.1
+ + 393075 1xx 204 and 304 ignore all headers suggesting content
+ + 393220 remove dead code from ServletHandler and log ServletExceptions in
+   warn instead of debug
+ + 393947 additional tests
+ + 393968 fix typo in javadoc
+ + 394514 Preserve URI parameters in sendRedirect
+ + 394541 remove continuation jar from distro, add as dep to test-jetty-webapp
+ + 394719 remove regex from classpath matching
+ + 394811 Make JAASLoginService log login failures to DEBUG instead of WARN.
+   Same for some other exceptions.
+ + 394829 Session can not be restored after SessionManager.setIdleSavePeriod
+   has saved the session
+ + 394839 Allow multipart mime with no boundary
+ + 395215 Multipart mime with just LF and no CRLF
+ + 395380 add ValidUrlRule to jetty-rewrite
+ + 395394 allow logging from boot classloader
+ + 396459 Log specific message for empty request body for multipart mime
+   requests
+ + 396500 HttpClient Exchange takes forever to complete when less content sent
+   than Content-Length
+ + 396574 add JETTY_HOME as a location for pid to be found
+ + 396886 MultiPartFilter strips bad escaping on filename="..."
+ + 397110 Accept %uXXXX encodings in URIs
+ + 397111 Tolerate empty or excessive whitespace preceeding MultiParts
+ + 397112 Requests with byte-range throws NPE if requested file has no mimetype
+   (eg no file extension)
+ + 397130 maxFormContentSize set in jetty.xml is ignored
+ + 397190 improve ValidUrlRule to iterate on codepoints
+ + 397321 Wrong condition in default start.config for annotations
+ + 397535 Support pluggable alias checking to support symbolic links
+ + 398337 UTF-16 percent encoding in UTF-16 form content
+ + 399132 check parent dir of session store against file to be removed
+ + JETTY-1533 handle URL with no path
+
+jetty-8.1.8.v20121106 - 06 November 2012
+ + 371170 MongoSessionManager LastAccessTimeTest fails
+ + 388675 Non utf8 encoded query strings not decoded to parameter map using
+   queryEncoding
+ + 388706 Avoid unnecessary indirection through Charset.name
+ + 389390 AnnotationConfiguration is ignored if the metadata-complete attribute
+   is present in an override descriptor regardless of the value
+ + 389452 if web-fragment metadata-complete==true still scan its related jar if
+   there there is a ServletContainerInitializer, ensure webapp restarts work
+ + 389686 Fix reference to org.eclipse.jetty.util.log.stderr.LONG system
+   property in javadoc for StdErrLog
+ + 389956 Bad __context set in WebAppContext.start sequence with respect to ENC
+   setup
+ + 389965 OPTIONS should allow spaces in comma separated list
+ + 390108 Servlet 3.0 API for programmatic login doesn't appear to work
+ + 390161 Apply DeferredAuthentication fix to jaspi
+ + 390163 Implement ServletRegistration.Dynamic.setServletSecurity
+ + 390503 http-method-omission element not being processed
+ + 390560 The method AnnotationParser.getAnnotationHandlers(String) always
+   returns a empty collection.
+ + 391080 Multipart temp files can be left on disk from Request.getPart and
+   getParts
+ + 391082 No exception if multipart input stream incomplete
+ + 391188 Files written with Request.getPart().write(filename) should not be
+   auto-deleted
+ + 391483 fix bad javadoc example in shutdown handler
+ + 391622 Be lenient on RFC6265 restriction on duplicate cookie names in same
+   response
+ + 391623 Add option to --stop to wait for target jetty to stop
+ + 391877 org.eclipse.jetty.webapp.FragmentDescriptor incorrectly reporting
+   duplicate others for after ordering
+ + 392239 Allow no error-code or exception for error-pages
+ + 392525 Add option to --stop-wait to specify timeout
+ + 392641 JDBC Sessions not scavenged if expired during downtime
+ + 392812 MongoSessionIDManager never purges old sessions
+ + 393014 Mongodb purgevalid using query for purgeinvalid
+ + 393015 Mongodb purge not rescheduled
+ + 393075 Jetty WebSocket client cannot connect to Tomcat WebSocket Server
+ + 393218 add xsd=application/xml mime mapping to defaults
+ + 393363 Use Locale.ENGLISH for all toUpperCase and toLowerCase calls
+ + 393368 min websocket version
+ + 393383 delay onClose call until closeOut is done
+ + 393494 HashSessionManager can't delete unrestorable sessions on Windows
+ + JETTY-1547 Jetty does not honor web.xml
+   web-app/jsp-config/jsp-property-group/default-content-type
+
+jetty-7.6.8.v20121106 - 06 November 2012
+ + 371170 MongoSessionManager LastAccessTimeTest fails
+ + 388675 Non utf8 encoded query strings not decoded to parameter map using
+   queryEncoding
+ + 389686 Fix reference to org.eclipse.jetty.util.log.stderr.LONG system
+   property in javadoc for StdErrLog
+ + 389956 Bad __context set in WebAppContext.start sequence with respect to ENC
+   setup
+ + 389965 OPTIONS should allow spaces in comma separated list
+ + 390161 Apply DeferredAuthentication fix to jaspi
+ + 390560 The method AnnotationParser.getAnnotationHandlers(String) always
+   returns a empty collection.
+ + 391483 fix bad javadoc example in shutdown handler
+ + 391622 Be lenient on RFC6265 restriction on duplicate cookie names in same
+   response
+ + 391623 Add option to --stop to wait for target jetty to stop
+ + 392239 Allow no error-code or exception for error-pages
+ + 392525 Add option to --stop-wait to specify timeout
+ + 392641 JDBC Sessions not scavenged if expired during downtime
+ + 392812 MongoSessionIDManager never purges old sessions
+ + 393014 Mongodb purgevalid using query for purgeinvalid
+ + 393015 Mongodb purge not rescheduled
+ + 393075 Jetty WebSocket client cannot connect to Tomcat WebSocket Server
+ + 393218 add xsd=application/xml mime mapping to defaults
+ + 393363 Use Locale.ENGLISH for all toUpperCase and toLowerCase calls
+ + 393368 min websocket version
+ + 393383 delay onClose call until closeOut is done
+ + 393494 HashSessionManager can't delete unrestorable sessions on Windows
+
+jetty-8.1.7.v20120910 - 10 September 2012
+ + 388895 Update dependencies for jetty-jndi
+ + fix busy logging statement re: sessions
+
+jetty-8.1.6.v20120903 - 03 September 2012
+ + 347130 Empty getResourcePaths due to ZipFileClosedException
+ + 367591 Support Env variables in XmlConfiguration.
+ + 377055 Prevent webapp classloader leaks
+ + 379207 backported fixes from jetty-9 to make hierarchy work
+ + 379423 Jetty URL Decoding fails for certain international characters
+ + 383304 Reset PrintWriter on response recycle
+ + 384847 better name
+ + 385049 fix issue with pipelined connections when switching protocols
+ + 385651 Message 'Address already in use' not specific enough
+ + 386010 JspRuntimeContext rewraps System.err
+ + 386591 add UnixCrypt note to about.html
+ + 386714 used deferred auth for form login and error pages
+ + 387896 populate session in SessionAuthentication as a valueBound in addition
+   to activation so it is populate when needed
+ + 387943 Catch CNFE when no jstl jars are installed
+ + 387953 jstl does not work with jetty-7 in osgi
+ + 388072 GZipFilter incorrectly gzips when Accept-Encoding: gzip; q=0
+ + 388073 null session id from cookie causes NPE fixed
+ + 388102 Jetty HttpClient memory leaks when sending larger files
+ + 388393 WebAppProvider doesn't work alongside OSGi deployer
+ + 388502 handle earlyEOF with 500
+ + 388652 Do not flush on handle return if request is suspended
+ + JETTY-1501 Setting custom error response message changes page title
+ + JETTY-1515 Include cookies on 304 responses from DefaultServlet.
+ + JETTY-1527 handle requests with URIs like http://host  (ie no / )
+ + JETTY-1529 Ensure new session that has just been authenticated does not get
+   renewed
+ + JETTY-1532 HTTP headers decoded with platform's default encoding
+ + JETTY-1541 fixed different behaviour for single byte writes
+ + 385925 make SslContextFactory.setProtocols and
+   SslContextFactory.setCipherSuites preserve the order of the given parameters
+
+jetty-8.1.5.v20120716 - 16 June 2012
+ + 376717 Balancer Servlet with round robin support, contribution, added
+   missing license
+ + 379250 Server is added to shutdown hook twice
+ + 380866 maxIdleTime set to 0 after session migration
+ + 381399 Unable to stop a jetty instance that has not finished starting
+ + 381401 Print log warning when stop attempt made with incorrect STOP.KEY
+ + 381402 Make ContextHandler take set of protected directories
+ + 381521 set Vary:Accept-Encoding header for content that might be compressed
+ + 381639 CrossOriginFilter does not support Access-Control-Expose-Headers.
+ + 381712 Support all declared servlets that implement
+   org.apache.jasper.servlet.JspServlet
+ + 381825 leave URI params in forwarded requestURI
+ + 381876 Monitor should wait for child to finish before exiting.
+ + 382343 Jetty XML support for Map is broken.
+ + 383251 500 for SocketExceptions
+ + 383881 WebSocketHandler sets request as handled
+ + 384254 revert change to writable when not dispatched
+ + 384280 Implement preliminary ServletRegistrations
+ + 384847 CrossOriginFilter is not working.
+ + 384896 JDBCSessionManager fails to load existing sessions on oracle when
+   contextPath is /
+ + 384980 Jetty client unable to recover from Time outs when connection count
+   per address hits max.
+ + 385138 add getter for session path and max cookie age that seemed to
+   disappear in a merge long ago
+ + JETTY-1523 It is imposible to map servlet to "/" using
+   WebApplicationInitializer
+ + JETTY-1525 Show handle status in response debug message
+ + JETTY-1530 refine search control on ldap login module
+
+jetty-8.1.4.v20120524 - 24 May 2012
+ + 367608 ignore the aysncrequestreadtest as it is known to fail and is waiting
+   for a fix
+ + 371853 Support bundleentry: protocol for webapp embedded as directory in
+   osgi bundle
+ + 373620 Add ch.qos.logback.access.jetty to the Import-Package for
+   jetty-osgi-boot-logback bundle
+ + 376152 apply context resources recursively
+ + 376801 Make JAAS login modules useable without jetty infrastructure
+ + 377323 Request#getParts() throws ServletException when it should be throwing
+   IllegalStateException
+ + 377391 Manifest updates to jetty-osgi-boot-logback
+ + 377492 NPE if jsp taglibs bundle not deployed
+ + 377550 set charset when content type is set
+ + 377587 ConnectHandler write will block on partial write
+ + 377610 New session not timed out if an old session is invalidated in scope
+   of same request
+ + 377709 Support for RequestParameterCallback missing
+ + 378242 Re-extract war on restart if incomplete extraction
+ + 378273 Remove default Bundle-Localization header
+ + 378487 Null out contextPath on Request.recycle
+ + 379015 Use factored jetty xml config files for defaults
+ + 379046 avoid closing idle connections from selector thread
+ + 379089 DefaultServlet ignores its resourceBase and uses context's
+   ResourceCollection when listing diretories
+ + 379194 ProxyServlet enhancement to enable easy creation of alternative
+   HttpClient implementations
+ + 379909 FormAuthenticator Rembers only the URL of first Request before
+   authentication
+ + 380034 last modified times taken from JarEntry for JarFile resources
+ + 380212 Clear buffer if parsing fails due to full buffer
+ + 380222 JettyPolicyRuntimeTest failure
+
+jetty-8.1.3.v20120416 - 16 April 2012
+ + 349110 MultiPartFilter records the content-type in request params
+ + 367172 Remove detection for slf4j NOPLogger
+ + 372678 Embedded Examples need updates for new LoginService requirement
+ + 373269 Make ServletHandler.notFound() method impl do nothing - override to
+   send back 404.
+ + 373421 address potential race condition related to the nonce queue removing
+   the same nonce twice
+ + 373952 bind called too frequently on refresh
+ + 374018 correctly handle requestperminuted underflow
+ + 374152 jetty-all-server MANIFEST contains wrong import:
+   javax.servlet.annotation;version="[2.6,3)"
+ + 374252 SslConnection.onClose() does not forward to nested connection.
+ + 374258 SPDY leaks SSLEngines. Made the test more reliable.
+ + 374367 NPE in QueuedThreadPool.dump() with early java6 jvms
+ + 374475 Response.sendRedirect does not encode UTF-8 characters properly
+ + 374881 Set copyWebInf to false by default
+ + 374891 enhancement to how ProxyServlet determines the proxy target
+ + 375009 Filter initialization error will throw MultiException
+ + 375083 Flow control should take in account window size changes from
+   concurrent SETTINGS
+ + 375096 If starting a server instance fails in osgi it is cleaned up.
+ + 375490 NPE with --help on command line
+ + 375509 Stalled stream stalls other streams or session control frames. Now
+   using a "death pill" instead of a boolean in order to avoid race conditions
+   where DataInfos were read from the queue (but the boolean not updated yet),
+   and viceversa.
+ + 375594 fixed SSL tests so they are not order dependent
+ + 375709 Ensure resolveTempDirectory failure does not deadlock; improve error
+   message
+ + 375906 Part.getHeader method not case insensitive
+ + 375970 HttpServletRequest.getRemoteAddr() returns null when HTTP is over
+   SPDY.
+ + 376201 HalfClosed state not handled properly. Addendum to restore previous
+   behavior, where a closed stream was also half closed.
+ + 376324 <max-file-size> is not respected in <multipart-config>
+ + JETTY-1495 Ensure dynamic servlet addition does not cause servlets to be
+   inited.
+ + JETTY-1500 form parameters from multipart request not available via
+   request.getParameter
+ + JETTY-1504 HttpServletResponseWrapper ignored when using asyncContext?
+
+jetty-8.1.2.v20120308 - 08 March 2012
+ + 370387 SafariWebsocketDraft0Test failure during build.
+ + 371168 Update ClientCrossContextSessionTest
+ + 372093 handle quotes in Require-Bundle manifest string
+ + 372457 Big response + slow clients + pipelined requests cause Jetty spinning
+   and eventually closing connections. Added a TODO for a method renaming that
+   will happen in the next major release (to avoid break implementers).
+ + 372487 JDBCSessionManager does not work with Oracle
+ + 372806 Command line should accept relative paths for xml config files
+ + 373037 jetty.server.Response.setContentLength(int) should not close a Writer
+   when length=0
+ + 373162 add improved implementation for getParameterMap(), needs a test
+   though and the existing setup doesn't seem like it would easily support the
+   needed test so need to do that still
+ + 373306 Set default user agent extraction pattern for UserAgentFilter
+ + 373567 cert validation issue with ocsp and crldp always being enabled when
+   validating turned on fixed
+ + 373603 NullPointer in WebServletAnnotation
+ + JETTY-1409 GzipFilter will double-compress application/x-gzip content
+ + JETTY-1489 WebAppProvider attempts to deploy .svn folder
+ + JETTY-1494 .
+
+jetty-8.1.1.v20120215 - 15 February 2012
+ + 369121 simplified test
+ + 370120 jvm arguments added via start.ini and --exec are missing spaces
+ + 370137 SslContextFactory does not respect order for
+   [included|excluded]Protocols() and [included|excluded]CipherSuites().
+ + 370368 resolve stack overflow in mongo db session manager
+ + 370386 Remove META-INF from jetty distro
+ + 371040 nosqlsession needs to call correct super contructor for new sessions
+ + 371041 valid was not being set to new mongo db sessions, and the call to
+   mongodb api was wrong in isIdInUse
+ + 371162 NPE protection for nested security handlers
+ + JETTY-1484 Add option for HashSessionManager to delete session files if it
+   can't restore them
+
+jetty-8.1.0.v20120127 - 27 January 2012
+ + 368773 allow authentication to be set by non securityHandler handlers
+ + 368992 avoid update key while flushing during a write
+ + 369216 turned off the shared resource cache
+ + 369349 replace quotes with a space escape method
+
+jetty-8.1.0.RC5 - 20 January 2012
+ + 359329 Prevent reinvocation of LoginModule.login with jaspi for already
+   authed user
+ + 368632 Remove superfluous removal of org.apache.catalina.jsp_file
+ + 368633 fixed configure.dtd resource mappings
+ + 368635 moved lifecycle state reporting from toString to dump
+ + 368773 process data constraints without realm
+ + 368787 always set token view to new header buffers in httpparser
+ + 368821 improved test harness
+ + 368920 JettyAwareLogger always formats the arguments.
+ + 368948 POM for jetty-jndi references unknown version for javax.activation.
+ + 368992 NPE in HttpGenerator.prepareBuffers() test case.
+ + JETTY-1475 made output state fields volatile to provide memory barrier for
+   non dispatched thread IO
+
+jetty-8.1.0.RC4 - 13 January 2012
+ + 365048 jetty Http client does not send proxy authentication when requesting
+   a Https-resource through a web-proxy.
+ + 366774 removed XSS vulnerbility
+ + 367099 Upgrade jetty-websocket for RFC 6455 - Addendum.
+ + 367433 added tests to investigate
+ + 367435 improved D00 test harness
+ + 367485 HttpExchange canceled before response do not release connection.
+ + 367502 WebSocket connections should be closed when application context is
+   stopped.
+ + 367548 jetty-osgi-boot must not import the nested package twice
+ + 367591 corrected configuration.xml version to 7.6
+ + 367635 Added support for start.d directory
+ + 367716 simplified maxIdleTime logic
+ + 368035 WebSocketClientFactory does not invoke super.doStop().
+ + 368060 do not encode sendRedirect URLs
+ + 368112 NPE on <jsp-config><taglib> element parsing web.xml
+ + 368113 Support servlet mapping to ""
+ + 368114 Protect against non-Strings in System properties for Log
+ + 368189 WebSocketClientFactory should not manage external thread pool. 368240
+   - Improve AggregateLifeCycle handling of shared lifecycles
+ + 368215 Remove debug from jaspi
+ + 368240 Better handling of locally created ThreadPool. Forgot to null out
+   field.
+ + 368291 Change warning to info for NoSuchFieldException on
+   BeanELResolver.properties
+ + 367638 limit number of form parameters to avoid DOS
+ + JETTY-1467 close half closed when idle
+
+jetty-8.1.0.RC2 - 22 December 2011
+ + 359329 jetty-jaspi must exports its packages. jetty-plus must import
+   javax.security
+ + 364638 HttpParser closes if data received while seeking EOF. Tests fixed to
+   cope
+ + 364921 Made test less time sensitive
+ + 364936 use Resource for opening URL streams
+ + 365267 NullPointerException in bad Address
+ + 365375 ResourceHandler should be a HandlerWrapper
+ + 365750 Support WebSocket over SSL, aka wss://
+ + 365932 Produce jetty-websocket aggregate jar for android use
+ + 365947 Set headers for Auth failure and retry in http-spi
+ + 366316 Superfluous printStackTrace on 404
+ + 366342 Dont persist DosFilter trackers in http session
+ + 366730 pass the time idle to onIdleExpire
+ + 367048 test harness for guard on suspended requests
+ + 367175 SSL 100% CPU spin in case of blocked write and RST.
+ + 367219 WebSocketClient.open() fails when URI uses default ports.
+ + 367383 jsp-config element must be returned for
+   ServletContext.getJspConfigDescriptor
+ + JETTY-1460 suppress PrintWriter exceptions
+ + JETTY-1463 websocket D0 parser should return progress even if no fill done
+ + JETTY-1465 NPE in ContextHandler.toString
+
+jetty-8.1.0.RC1 - 06 December 2011
+ + 360245 The version of the javax.servlet packages to import is 2.6 instead of
+   3.0
+ + 365370 ServletHandler can fall through to nested handler
+
+jetty-8.1.0.RC0 - 30 November 2011
+ + 352565 cookie httponly flag ignored
+ + 353285 ServletSecurity annotation ignored
+ + 357163 jetty 8 ought to proxy jetty8 javadocs
+ + 357209 JSP tag listeners not called
+ + 360051 SocketConnectionTest.testServerClosedConnection is excluded.
+ + 361135 Allow session cookies to NEVER be marked as secure, even on HTTPS
+   requests.
+ + 362249 update shell scripts to jetty8
+ + 363878 Add ecj compiler to jetty-8 for jsp
+ + 364283 can't parse the servlet multipart-config for the web.xml
+ + 364430 Support web.xml enabled state for servlets
+
+jetty-7.6.0.RC5 - 20 January 2012
+ + 359329 Prevent reinvocation of LoginModule.login with jaspi for already
+   authed user
+ + 368632 Remove superfluous removal of org.apache.catalina.jsp_file
+ + 368633 fixed configure.dtd resource mappings
+ + 368635 moved lifecycle state reporting from toString to dump
+ + 368773 process data constraints without realm
+ + 368787 always set token view to new header buffers in httpparser
+ + 368821 improved test harness
+ + 368920 JettyAwareLogger always formats the arguments.
+ + 368948 POM for jetty-jndi references unknown version for javax.activation.
+ + 368992 avoid non-blocking flush when writing to avoid setting !_writable
+   without _writeblocked
+ + JETTY-1475 made output state fields volatile to provide memory barrier for
+   non dispatched thread IO
+
+jetty-7.6.0.RC4 - 13 January 2012
+ + 365048 jetty Http client does not send proxy authentication when requesting
+   a Https-resource through a web-proxy.
+ + 366774 removed XSS vulnerbility
+ + 367099 Upgrade jetty-websocket for RFC 6455 - Addendum.
+ + 367716 simplified maxIdleTime logic
+ + 368035 WebSocketClientFactory does not invoke super.doStop().
+ + 368060 do not encode sendRedirect URLs
+ + 368114 Protect against non-Strings in System properties for Log
+ + 368189 WebSocketClientFactory should not manage external thread pool.
+ + 368215 Remove debug from jaspi
+ + 368240 Improve AggregateLifeCycle handling of shared lifecycles
+ + 368291 Change warning to info for NoSuchFieldException on
+   BeanELResolver.properties
+
+jetty-7.6.0.RC3 - 05 January 2012
+ + 367433 added tests to investigate
+ + 367435 improved D00 test harness
+ + 367485 HttpExchange canceled before response do not release connection.
+ + 367502 WebSocket connections should be closed when application context is
+   stopped.
+ + 367591 corrected configuration.xml version to 7.6
+ + 367635 Added support for start.d directory
+ + 367638 limit number of form parameters to avoid DOS
+ + JETTY-1467 close half closed when idle
+
+jetty-7.6.0.RC2 - 22 December 2011
+ + 364638 HttpParser closes if data received while seeking EOF. Tests fixed to
+   cope
+ + 364921 Made test less time sensitive for ssl
+ + 364936 use Resource for opening URL streams
+ + 365267 NullPointerException in bad Address
+ + 365375 ResourceHandler should be a HandlerWrapper
+ + 365750 Support WebSocket over SSL, aka wss://
+ + 365932 Produce jetty-websocket aggregate jar for android use
+ + 365947 Set headers for Auth failure and retry in http-spi
+ + 366316 Superfluous printStackTrace on 404
+ + 366342 Dont persist DosFilter trackers in http session
+ + 366730 pass the time idle to onIdleExpire
+ + 367048 test harness for guard on suspended requests
+ + 367175 SSL 100% CPU spin in case of blocked write and RST.
+ + 367219 WebSocketClient.open() fails when URI uses default ports.
+ + JETTY-1460 suppress PrintWriter exceptions
+ + JETTY-1463 websocket D0 parser should return progress even if no fill done
+ + JETTY-1465 NPE in ContextHandler.toString
+
+jetty-7.6.0.RC1 - 04 December 2011
+ + 352565 cookie httponly flag ignored
+ + 353285 ServletSecurity annotation ignored
+ + 357163 jetty 8 ought to proxy jetty8 javadocs
+ + 357209 JSP tag listeners not called
+ + 360051 SocketConnectionTest.testServerClosedConnection is excluded.
+ + 361135 Allow session cookies to NEVER be marked as secure, even on HTTPS
+   requests.
+ + 362249 update shell scripts to jetty8
+ + 363878 Add ecj compiler to jetty-8 for jsp
+ + 364283 can't parse the servlet multipart-config for the web.xml
+ + 364430 Support web.xml enabled state for servlets
+ + 365370 ServletHandler can fall through to nested handler
+
+jetty-7.6.0.RC0 - 29 November 2011
+ + Refactored NIO layer for better half close handling
+ + 349110 fixed bypass chunk handling
+ + 360546 handle set count exceeding max integer
+ + 362111 StdErrLog.isDebugEnabled() returns true too often
+ + 362113 Improve Test Coverage of org.eclipse.jetty.util.log classes
+ + 362407 setTrustStore(Resource) -> setTrustStoreResource(R)
+ + 362447 add setMaxNonceAge() to DigestAuthenticator
+ + 362468 NPE at line org.eclipse.jetty.io.BufferUtil.putHexInt
+ + 362614 NPE in accepting connection
+ + 362626 IllegalStateException thrown when SslContextFactory preconfigured
+   with SSLContext
+ + 362696 expand virtual host configuration options to ContextHandler and add
+   associated test case for new behavior
+ + 362742 improved UTF8 exception reason
+ + 363124 improved websocket close handling
+ + 363381 Throw IllegalStateException if Request uri is null on getServerName
+ + 363408 GzipFilter should not attempt to compress HTTP status 204
+ + 363488 ShutdownHandler use stopper thread
+ + 363718 Setting java.rmi.server.hostname in jetty-jmx.xml
+ + 363757 partial fix
+ + 363785 StdErrLog must use system-dependent EOL.
+ + 363943 ignore null attribute values
+ + 363993 EOFException parsing HEAD response in HttpTester
+ + 364638 SCEP does idle timestamp checking. New setCheckForIdle method
+   controls onIdleExpired callback. 364921 a second onIdleExpired callback will
+   result in close rather than a shutdown output.
+ + 364657 Support HTTP only cookies from standard API
+ + JETTY-1442 add _hostHeader setter for ProxyRule
+
+jetty-8.0.4.v20111024 - 24 October 2011
+ + 358263 JDBCSessionIdManager add setDatasource(DataSource) method
+ + 358649 Replace existing StdErrLog system properties for DEBUG/IGNORED with
+   LEVEL instead.
+ + 360836 Accept parameters with bad UTF-8. Use replacement character
+ + 360912 CrossOriginFilter does not send Access-Control-Allow-Origin on
+   responses. 355103 Make allowCredentials default to true in
+   CrossOriginFilter.
+ + 360938 Connections closed after a while.
+ + 361135 secure cookies for sessions
+ + 361319 Log initialization does not catch correct exceptions on all jvms
+ + 361325 359292 Allow KeyStore to be set
+ + 361456 release timer task on connection failed
+ + 361655 ExecutorThreadPool.isLowOnThreads() returns wrong value.
+ + JETTY-1444 start threadpool before selector manager
+
+jetty-7.5.4.v20111024 - 24 October 2011
+ + 358263 JDBCSessionIdManager add setDatasource(DataSource) method
+ + 358649 Replace existing StdErrLog system properties for DEBUG/IGNORED with
+   LEVEL instead.
+ + 360836 Accept parameters with bad UTF-8. Use replacement character
+ + 360912 CrossOriginFilter does not send Access-Control-Allow-Origin on
+   responses. 355103 Make allowCredentials default to true in
+   CrossOriginFilter.
+ + 360938 Connections closed after a while.
+ + 361319 Log initialization does not catch correct exceptions on all jvms
+ + 361325 359292 Allow KeyStore to be set
+ + 361456 release timer task on connection failed
+ + 361655 ExecutorThreadPool.isLowOnThreads() returns wrong value.
+ + JETTY-1444 start threadpool before selector manager
+
+jetty-8.0.3.v20111011 - 11 October 2011
+ + 348978 migrate jetty-http-spi
+ + 358649 StdErrLog system properties for package/class logging LEVEL.
+
+jetty-8.0.2.v20111006 - 06 October 2011
+ + 336443 add missing comma in DigestAuthenticator string
+ + 342161 ScannerTest fails intermittently on Mac OS X
+ + 346419 testing HttpClient FDs
+ + 353267 Request._parameters initialization bug
+ + 353509 jetty-client unit tests are running too long
+ + 353627 Basic Auth checks that Basic method has been send
+ + 356144 Allow SelectorManager thread priority to be set
+ + 356274 Start SSL socket factory in call to open()
+ + 357163 jetty 8 ought to proxy jetty8 javadocs
+ + 357178 websockets draft 14 support
+ + 357188 Send content buffer directly
+ + 357209 JSP tag listeners not called
+ + 357216 Logging via Log4J does not expand braces in format strings
+ + 357240 more half close refinements
+ + 357338 remove debug
+ + 357672 resolve issue with serializing pojos with mongodb session manager,
+   thanks to john simone for the discovery and fix
+ + 357959 Include javadoc in distribution
+ + 358027 NullPointerException in ResourceHandler with jetty-stylesheet.css
+ + 358035 idle time only active if > 0
+ + 358147 Add catch for UnknownHostException to fix leaky file descriptor in
+   client
+ + 358164 Dispatch from servlet to handler
+ + 358263 add method for osgi users to register a driver as Class.forName does
+   not work for them
+ + 358649 StdErrLog system properties for package/class logging LEVEL.
+ + 358674 Still allows sslv3 for now
+ + 358687 Updated jsp does not scan for system tlds Fixed pattern.
+ + 358784 JSP broken on Java 1.5
+ + 358925 bit more javadoc on usage
+ + 358959 File descriptor leak with UnresolvedAddressException
+ + 359309 adjust previous test for servletPath to include pathInfo
+ + 359673 updated websocket version handling
+ + 359675 Principal != String, fix for issue in property file login manager
+ + 360051 SocketConnectionTest.testServerClosedConnection is excluded.
+ + 360066 jsps referenced in web.xml <jsp-file> elements do not compile
+ + JETTY-1130 Access Sessions from HashSessionIdManager
+ + JETTY-1277 Fixed sendRedirect encoding of relative locations
+ + JETTY-1322 idle sweeper checks for closed endp
+ + JETTY-1377 extra logging for busy selector
+ + JETTY-1378 new sys property for the latest jsp-impl to force the use of the
+   JDTCompiler when running in OSGi.
+ + JETTY-1414 applied to PropertyUserStore
+ + JETTY-1415 Start/Stop Server and Client only once in test, code format
+ + JETTY-1420 Set Host header for new request in RedirectListener
+ + JETTY-1421 Implement RedirectListener.onException,onConnectionFailed
+ + JETTY-1423 force connection to be closed returned
+ + JETTY-1430 local JNDI contexts don't carry environment
+ + JETTY-1434 Add a jsp that exercises jstl.
+ + JETTY-1439 space in directory installation path causes classloader problem
+
+jetty-7.5.3.v20111011 - 11 October 2011
+ + 348978 migrate jetty-http-spi
+ + 358649 StdErrLog system properties for package/class logging LEVEL.
+
+jetty-7.5.2.v20111006 - 06 October 2011
+ + 336443 check nonce count is increasing
+ + 342161 ScannerTest fails intermittently on Mac OS X
+ + 346419 testing HttpClient FDs
+ + 353267 Request._parameters initialization bug
+ + 353509 jetty-client unit tests are running too long
+ + 353627 Basic Auth checks that Basic method has been send
+ + 356144 Allow SelectorManager thread priority to be set
+ + 356274 Start SSL socket factory in call to open()
+ + 357178 websockets draft 14 support
+ + 357188 Send content buffer directly
+ + 357209 JSP tag listeners not called
+ + 357216 Logging via Log4J does not expand braces in format strings
+ + 357240 more half close refinements
+ + 357338 remove debug
+ + 357672 resolve issue with serializing pojos with mongodb session manager,
+   thanks to john simone for the discovery and fix
+ + 357959 Include javadoc in distribution
+ + 358027 NullPointerException in ResourceHandler with jetty-stylesheet.css
+ + 358035 idle time only active if > 0
+ + 358147 Add catch for UnknownHostException to fix leaky file descriptor in
+   client
+ + 358164 Dispatch from servlet to handler
+ + 358263 add method for osgi users to register a driver as Class.forName does
+   not work for them
+ + 358649 StdErrLog system properties for package/class logging LEVEL.
+ + 358674 Still allows sslv3 for now
+ + 358687 Updated jsp does not scan for system tlds Fixed pattern.
+ + 358784 JSP broken on Java 1.5
+ + 358925 bit more javadoc on usage
+ + 358959 File descriptor leak with UnresolvedAddressException
+ + 359309 adjust previous test for servletPath to include pathInfo
+ + 359673 updated websocket version handling
+ + 359675 Principal != String, fix for issue in property file login manager
+ + 360051 SocketConnectionTest.testServerClosedConnection is excluded.
+ + 360066 jsps referenced in web.xml <jsp-file> elements do not compile
+ + JETTY-1130 Access Sessions from HashSessionIdManager
+ + JETTY-1277 Fixed sendRedirect encoding of relative locations
+ + JETTY-1322 idle sweeper checks for closed endp
+ + JETTY-1377 extra logging for busy selector
+ + JETTY-1378 new sys property for the latest jsp-impl to force the use of the
+   JDTCompiler when running in OSGi.
+ + JETTY-1414 applied to PropertyUserStore
+ + JETTY-1415 Start/Stop Server and Client only once in test, code format
+ + JETTY-1420 Set Host header for new request in RedirectListener
+ + JETTY-1421 Implement RedirectListener.onException,onConnectionFailed
+ + JETTY-1423 force connection to be closed returned
+ + JETTY-1430 local JNDI contexts don't carry environment
+ + JETTY-1434 Add a jsp that exercises jstl.
+ + JETTY-1439 space in directory installation path causes classloader problem
+
+jetty-8.0.1.v20110908 - 08 September 2011
+ + 350634 Added Resource.newResource(File)
+ + 356190 fix monodb tests  for changed test api
+ + 356428 removed timed waits from test
+ + 356693 reduce visibility to webapp of websocket implementations
+ + 356695 jetty server jars are provided for websockets
+ + 356726 Instead of the sessionDestroyed called sessionCreated after
+   invalidate session
+ + 356751 Add null protection to ServletContextHandler.doStop
+ + 356823 correctly decode close codes.  Send not utf-8 close code.
+ + 357058 Acceptor thread blocking
+
+jetty-7.5.1.v20110908 - 08 September 2011
+ + 350634 Added Resource.newResource(File)
+ + 356190 fix monodb tests  for changed test api
+ + 356428 removed timed waits from test
+ + 356693 reduce visibility to webapp of websocket implementations
+ + 356695 jetty server jars are provided for websockets
+ + 356726 Instead of the sessionDestroyed called sessionCreated after
+   invalidate session
+ + 356751 Add null protection to ServletContextHandler.doStop
+ + 356823 correctly decode close codes.  Send not utf-8 close code.
+ + 357058 Acceptor thread blocking
+
+jetty-8.0.0.v20110901 - 01 September 2011
+ + 352565 cookie httponly flag ignored
+ + 353073 better warnings
+ + 353285 ServletSecurity annotation ignored
+ + 356421 Upgraded websocket to draft 13 support
+
+jetty-7.5.0.v20110901 - 01 September 2011
+ + 356421 Upgraded websocket to draft 13 support
+ + 353073 better warnings
+
+jetty-7.5.0.RC2 - 30 August 2011
+ + 293739 Hide stacks in named log testing. Various other minor log cleanups in
+   output.
+ + 352188 TestClient correctly processes --host option in jetty-websocket
+ + 352222 Moved JmxMonitor functionality from Codehaus
+ + 353014 TimeoutExchangeTest run time reduced
+ + 353073 deprecated non factory method for websocket clients
+ + 353192 Better warning for classes of wrong type
+ + 353623 Added new methods to HttpExchange
+ + 353624 HttpURI accepts java.net.URI object in constructor
+ + 354080 ServletContextHandler allows to replace any subordinate handler when
+   restarted
+ + 355478 set public to HashedSession, looks like honest mistake and not by
+   design to be this way
+ + 355854 remove automatic conversion in favor of issuing a warning for
+   jetty-web.xml that can't be processed
+ + 356128 Moved integration tests from jetty-monitor to test-integration module
+ + 356137 Upgrade to jsp implementation version 2.1.3-b10
+ + 356144 added SelectorManager.setSelectorPriorityDelta(int)
+ + JETTY-1410 handle 1xx in similar fashion to 401s and 302s
+
+jetty-7.5.0.RC1 - 19 August 2011
+ + 276670 SLF4J loggers show correct location information
+ + 335001 Eliminate expected exceptions from log when running in JBoss
+ + 355103 Make allowCredentials default to true in CrossOriginFilter
+ + 355162 Allow creating an empty resource collection
+ + JETTY-1410 HTTP client handles CONTINUE 100 response correctly
+ + JETTY-1414 HashLoginService doesn't refresh realm if specified config
+   filename is not an absolute platform specific value
+
+jetty-8.0.0.RC0 - 16 August 2011
+ + Merge from jetty-7.4.3
+ + Enable annotations by default
+ + 352565 cookie httponly flag ignored
+ + 353285 ServletSecurity annotation ignored
+
+jetty-8.0.0.M3 - 27 May 2011
+ + 324505 Implement API login
+ + 335500 request.getParts() throws a NullPointerException
+ + 343472 isUserInRole does not prevent subsequent login call.
+ + 346180 jsp-2.2 support
+ + Updated to jetty-7.4.2.v20110526
+
+jetty-7.5.0.RC0 - 15 August 2011
+ + 298502 Handle 200 Connect responses with no content-length
+ + 347484 / - > ${/} in some paths in grant codebases
+ + 349005 add javadoc detailing the convenience hack of removing leading /'s
+ + 351516 Refactored sessions to better support nosql session managers
+ + 351576 Do not use deprecated method File.toURL()
+ + 352046 Need try/catch around features set in XmlParser
+ + 352133 Generally resolve java 1.5isms
+ + 352176 xml parsing on startElement should be more flexible on using qName or
+   localName
+ + 352421 HttpURI paths beginning with '.'
+ + 352684 Implemented spinning thread analyzer
+ + 352786 GzipFilter fails to pass parameters to GzipResponseWrapper
+ + 352999 ExpireTest running too long
+ + 353073 WebSocketClient
+ + 353095 maven-jetty-plugin: PermGen leak due to javax.el.BeanELResolver
+ + 353165 addJars can follow symbolic link jar files
+ + 353210 Bundle-Version in o.e.j.o.boot.logback fix
+ + 353465 JAASLoginService ignores callbackHandlerClass
+ + 353563 HttpDestinationQueueTest too slow
+ + 353862 Improve performance of QuotedStringTokenizer.quote()
+ + 354014 Content-Length is passed to wrapped response in GZipFilter
+ + 354204 Charset encodings property file not used
+ + 354397 RewriteRegexRule handles special characters in regex group
+ + 354466 Typo in example config of jetty-plus.xml
+
+jetty-7.4.5.v20110725 - 25 July 2011
+ + 347484 / - > ${/} in some paths in grant codebases
+ + 352133 resolve some 1.5isms
+ + 352421 HttpURI paths beginning with '.'
+ + 352786 GzipFilter fails to pass parameters to GzipResponseWrapper
+
+jetty-7.4.4.v20110707 - 07 July 2011
+ + 308851 Converted all jetty-client module tests to JUnit 4
+ + 345268 JDBCSessionManager does not work with maxInactiveInterval = -1
+ + 350397 SelectChannelConnector does not shutdown gracefully
+ + 350634 Reverted FileResource constructor changes
+ + 351039 Forward dispatch should retain locale
+ + 351199 HttpServletResponse.encodeURL() wrongly encodes an url without path
+   when cookies are disabled
+ + JETTY-1153 Default charset/encoding of HTTP POST requests
+ + JETTY-1380 Jetty Rewrite example does not work in Hightide
+
+jetty-7.4.3.v20110701 - 01 July 2011
+ + 295832 ProxyServlet more extensible and configurable
+ + 302566 GZIP handler for embedded Jetty servers
+ + 308851 Converted HttpExchangeTest and related tests to JUnit 4
+ + 324704 JDBC Session Manager reloading session
+ + 332200 Eliminate expected exceptions from log while using
+   org.eclipse.jetty.jmx bundle
+ + 347468 o.e.j.deploy.binding.GlobalWebappConfigBindingTest fails on Windows
+   platform
+ + 347617 Dynamically install/update/remove OSGi bundles discovered in the
+   contexts folder
+ + 347717 start.jar destroys dependent child of --exec
+ + 347889 OSGi should follow directive visibility:=reexport for
+   META-INF/web-fragments and resources
+ + 347898 Close channel on JVM exceptions
+ + 348652 jetty.sh starts two unix processes
+ + 348935 Close A tag in directory listing
+ + 349344 Passing empty query string to UrlEncoded#decodeTo(String, MultiMap,
+   String) does not yield an empty map
+ + 349738 set buffer sizes for http client in proxy servlet
+ + 349870 proxy servlet protect continuation against fast failing exchanges
+ + 349896 SCEP supports zero maxIdleTime
+ + 349897 draft -09 websockets
+ + 349997 MBeanContainer uses weak references
+ + 350533 Add "Origin" to the list of allowed headers in CrossOriginFilter
+ + 350634 Cleanup FileResource construction
+ + 350642 Don't close SCEP during NIOBuffer manipulation
+ + JETTY-1342 Recreate selector in change task
+ + JETTY-1385 NPE in jetty client's
+   HTttpExchange.setRequestContentSource(InputStream)
+ + JETTY-1390 RewriteHandler handles encoded URIs
+
+jetty-7.4.2.v20110526
+ + 334443 Improve the ability to specify extra class paths using the Jetty
+   Maven Plugin
+ + 336220 tmp directory is not set if you reload a webapp with
+   jetty-maven-plugin
+ + 338364 Fixed expires header for set cookies
+ + 345729 binding for managing server and system classes globally
+ + 345615 Enable SSL Session caching
+ + 345763 Source file is updated during the build
+ + 345873 Update jetty-ssl.xml to new style
+ + 345900 Handle IPv6 with default port
+ + 346014 Fixed full HttpGenerator
+ + 346124 ServletContext resources paths not resolved correctly when using UNC
+   shares
+ + 346179 o.e.j.util.ScannerTest fails on MacOS X platform
+ + 346181 o.e.j.server.StressTest stalls on MacOS X platform
+ + 346998 AbstractLifeCycle.isRunning() returns false if state changes from
+   STARTING to STARTED during call
+ + 346614 HttpConnection.handle() spins in case of SSL truncation attacks
+ + 346764 OrderedGroupBinding deployment binding
+ + 347137 Allow SSL renegotiations by default in HttpClient
+ + 374174 Consistent mbean names
+ + JETTY-1146 Encode jsessionid in sendRedirect
+ + JETTY-1342 Recreate selector if wakeup throws JVM bug
+
+jetty-7.4.1.v20110513
+ + 288563 remove unsupported and deprecated --secure option
+ + 332907 Add context property to ObjectName of JMX MBeans
+ + 336056 Ability to override the computation of the ContextHandler to deploy
+   the DefaultServlet on the HttpService
+ + 340040 Support for a total timeout
+ + 343083 Set nested dispatch type and connection
+ + 343172 Check package implementor for version
+ + 343277 add support for a context white list
+ + 343352 make sure that jetty.osgi.boot is activated when a WAB is registered
+ + 343482 refactored overlay deployer layout to use WAR layout
+ + 343567 HttpClient does not limit the destination's exchange queue
+ + 343680 Handle OSGi bundle jars not ending in ".war"
+ + 343707 'REQUEST' is printed on console for each incoming HTTP request
+ + 343923 flush timeouts applied to outer loop
+ + 343936 Session idle calls unbind and remove listeners
+ + 344059 Websockets draft-07
+ + 344067 Add support for OSGi fragment bundles to add static resources to
+   web-bundles
+ + 344513 Attempting to set ConfigurationClasses in jetty-web.xml causes NPE
+ + 344529 Ability to customize the error handling of the OSGi HttpService
+ + 345047 Readded deprecated ScanningAppDeployer#setMonitoredDir
+ + 345290 Weak references from SessionIdManager. HashSessionManager cleanup.
+ + 345543 Always close endpoint on SSLException
+ + 345656 Disambiguate SslContextFactory#validateCerts property
+ + 345679 Allow setting an initialized KeyStore as keystore/truststore of
+   SslContextFactory
+ + 345704 jetty-nested works with forwarded SSL in cloudfoundry
+ + JETTY-954 WebAppContext eats any start exceptions instead of stopping the
+   server load
+ + JETTY-1314 Handle bad URI encodings
+ + JETTY-1324 Tested not using CESU-8 instead of UTF-8
+ + JETTY-1326 Invoker names not hashCode based
+ + JETTY-1343 IllegalArgumentException for bad % encodings
+ + JETTY-1347 Updated ServletHander javadoc
+
+jetty-7.4.0.v20110414
+ + 342504 Scanner Listener
+ + 342700 refine websocket API for anticipated changes
+ + JETTY-1362 Set root cause of UnavailableException
+ + Various test harness cleanups to avoid random failures
+
+jetty-7.4.0.RC0
+ + 324110 Added test harnesses for merging of QueryStrings.
+ + 337685 Update websocket API in preparation for draft -07
+ + 338627 HashSessionManager.getIdleSavePeriod returns milliseconds instead of
+   seconds
+ + 338807 Ignore content length in 1xx, 204, 304 responses
+ + 338819 Externally control Deployment Manager application lifecycle
+ + 339084 Fixed NPE with servlet 3.0 async listener
+ + 339150 Validate client certificate when it is used for authentication
+ + 339187 In the OSGi manifest of the jetty-all-server aggregate, mark
+   javax.annotation as optional
+ + 339543 Add configuration options for Certificate Revocation checking
+ + 340265 Improve handling of io shutdown in SSL
+ + 340621 Added SizedThreadPool interface
+ + 340636 HashSessionManager lazy loads all sessions
+ + 340838 Update ConnectHandler to perform half closes properly
+ + 340878 Integrations should be able to load their own keystores
+ + 340920 Dynamically assign RMI registry port for integration testing
+ + 340949 Scanner delays file notifications until files are stable
+ + 341006 Move inner enums out into separate file
+ + 341105 Stack trace is printed for an ignored exception
+ + 341145 WebAppContext MBean attribute serverClasses returns empty value
+ + 341171 Locking in HttpDestination blocks all requests to the same address
+ + 341206 Stop order is wrong in HandlerWrapper
+ + 341255 org.eclipse.http usage in AJP/SessionId linkage
+ + 341386 Remote close not detected by HttpClient
+ + 341394 Remove 'Unavailable' JMX attributes of WebAppContext MBean
+ + 341439 Blocking HttpClient does not use soTimeout for timeouts
+ + 341561 Exception when adding o.e.j.s.DoSFilter as managed attribute
+ + 341692 Fixed deadlock if stopped while starting
+ + 341736 Split jetty-nested out of war module
+ + 341726 JSONPojoConverter handles characters
+ + 341992 Overlayed context deployer
+ + 341694 Disable AJP buffer resizing
+ + 341850 Protect QTP dump from bad stacks
+ + JETTY-1245 Pooled Buffers implementation
+ + JETTY-1354 Added jetty-nested
+ + Ensure generated fragment names are unique
+ + Added extra session removal test
+
+jetty-8.0.0.M2 - 16 November 2010
+ + 320073 Reconsile configuration mechanism
+ + 321068 JSF2 fails to initialize
+ + 324493 Registration init parameter handling null check, setInitParameters
+   additive
+ + 324505 Request.login method must throw ServletException if it cant login
+ + 324872 allow disabling listener restriction from using *Registration
+   interfaces
+ + 327416 Change meaning of @HandlesTypes in line with latest interpretation by
+   JSR315
+ + 327489 Change meaning of @MultipartConfig to match servlet spec 3.0
+   maintenance release 3.0a
+ + 328008 Handle update to Servlet Spec 3 Section 8.2.3.h.ii
+ + 330188 Reject web-fragment.xml with same <name> as another already loaded
+   one
+ + 330208 Support new wording on servlet-mapping and filter-mapping merging
+   from servlet3.0a
+ + 330292 request.getParts() returns only one part when the name is the same
+ + Update to jetty-7.2.1.v20101111
+
+jetty-7.3.1.v20110307 - 07 March 2011
+ + 316382 Support a more strict SSL option with certificates
+ + 333481 Handle UCS-4 codepoints in decode and encode
+ + 335329 Moved blocking timeout handling to outside try catch
+ + 336668 policy supports cert validation
+ + 336691 Possible wrong length returned by ChannelEndPoint.flush() in case of
+   RandomAccessFileBuffer
+ + 336781 If xml parser is not validating, turn off external dtd resolution
+ + 336793 Tee data filled and flushed from endpoint
+ + 337258 Scanner start and end cycle notification
+ + 337268 Allow specifying alias of a certificate to be used by SSL connector
+ + 337270 Shared Timer for session management
+ + 337271 Flush SSL endpoint when dispatch thread held forever
+ + 337678 Readded optional async connection mode for HttpClient
+ + 337685 Work in progress on draft 6 websockets
+ + 337746 Fixed Session deIdle recursion
+ + 337784 Improve HashSessionManager for session migrations
+ + 337878 Extra tests of security constraints
+ + 337896 HttpExchange.timeout does not override HttpClient.timeout
+ + 337898 set client HttpConnection max idle time from exchange timeout
+ + 338035 Default acceptors 0.25*CPUs and improved selector/acceptor thread
+   names.
+ + 338068 Leaking ConstraintMappings on redeploy
+ + 338092 ProxyServlet leaks memory
+ + 338607 Removed managed attributes when context is stopped
+ + 338819 Externally control Deployment Manager application lifecycle
+ + JETTY-1304 Allow quoted boundaries in Multipart filter
+ + JETTY-1317 More elegent handling of bad URIs in requests
+ + JETTY-1331 Allow alternate XML configuration processors (eg spring)
+ + JETTY-1335 HttpClient's SelectConnector clean-up
+ + JETTY-1333 HttpClient _timeout and _soTimeout is messed up
+ + JETTY-1337 Workname cannot contain '.'
+ + JETTY-1338 Trust default SecureRandom seed
+
+jetty-7.3.0.v20110203 - 03 February 2011
+ + JETTY-1259 NullPointerException in JDBCSessionIdManager when invalidating
+   session (further update)
+ + 296978 standardizing various Testing Util Classes to jetty-test-helper
+ + 319178 test failure fix in jetty-util on windows
+ + 320457 add SPNEGO support
+ + 324505 Implement API login
+ + 328872 Multi Jetty xml files not loading if directory is referenced in
+   jetty.conf
+ + 329746 client option to set just truststore and use strict ssl context
+ + 331803 Update XML configuration files to use proper arguments for startup
+   command in examples
+ + 332179 Fixed formatting of negative dates
+ + 332432 Scanner.java now always scanning the canonical form of File
+ + 332517 Improved DefaultServlet debug
+ + 332703 Cleanup context scope JNDI at stop
+ + 332796 Annotations inheritance does not work with jetty7
+ + 332799 100% CPU on redeploy session invalidation
+ + 332937 Added Destroyable Dumpable interfaces and reworked dependent
+   lifecycles, specially of JNDI
+ + 333247 fix api compat issue in ConstraintSecurityHandler
+ + 333415 wired up HttpInput.available and added test harnesses
+ + 333481 Handle UTF-32 codepoints in decode and encode
+ + 333608 tlds defined in web.xml are not picked up
+ + 333679 Refactored jetty-jmx. Moved mbeans to modules
+ + 333717 HttpExchange able to return local address used
+ + 333771 System properties are not available inside XML configuration file by
+   using the 'property' tag
+ + 333875 Monitor public constructor
+ + 333892 Improved JVM bug detection
+ + 334062 It should be possible to embed in the jetty.home.bundle the ssl
+   keystore files
+ + 334229 javax-security needs to import the package javax.security.cert in its
+   OSGi manifest
+ + 334311 fix buffer reuse issue in CachedExchange
+ + 335329 Stop SSL spin during handshake and renogotiate
+ + 335361 Fixed 'jetty.sh check' to show current PID when JETTY_PID env.
+   variable is set
+ + 335641 Cleaned up dispatch handling to avoid key.interestOps==0 when
+   undispatched
+ + 335681 Improve ChannelEndPoint.close() to avoid spinning
+ + 335836 Race when updating SelectChannelEndPoint._dispatched
+
+jetty-7.2.2.v20101205 - 05 December 2010
+ + JETTY-1308 327109 (re)fixed AJP handling of empty packets
+ + 331703 Fixed failing OSGI test TestJettyOSGiBootWithJsp.java on MacOSX
+ + 331567 IPAccessHandlerTest failed on MacOS fix
+ + 328789 Clean up tmp files from test harnesses
+ + 331230 Fixed low thread warnings when acceptors>threadpool
+ + 331461 Fixed idle timeout for unflushed HTTP/1.0
+ + JETTY-1307 Check that JarFileResource directories end with /
+ + 330210 Improve performance of writing large bytes arrays
+ + 330208 Support new wording on servlet-mapping and filter-mapping merging
+   from servlet3.0a
+ + 330188 Reject web-fragment.xml with same <name> as another already loaded
+   one
+ + 330229 Jetty tries to parse META-INF/*.tld when jsp-api is not on classpath,
+   causing DTD entity resoluton to fail
+ + 330265 start.jar --stop kills --exec subprocess
+ + 330417 Atomic PUT in PutFilter
+ + 330419 Reloading webapp duplicates StandardDescriptorProcessor
+ + 330686 OSGi: Make org.eclipse.jetty.jsp-2.1 a fragment of
+   org.apache.jasper.glassfish
+ + 330732 Removed System.err debugging
+ + 330764 Command line properties passed to start.jar --exec
+ + JETTY-1297 Improved matching of vhosts so that a vhost match has priority
+
+jetty-7.2.1.v20101111 - 11 November 2010
+ + 324679 Fixed dedection of write before static content
+ + 328199 Ensure blocking connectors always close socket
+ + 328205 Improved SelectManager stopping
+ + 328306 Serialization of FormAuthentication
+ + 328332 Response.getContentType works with setHeader
+ + 328523 Fixed overloaded setters in AppProvider
+ + 328008 Handle update to Servlet Spec 3 Section 8.2.3.h.ii
+ + 328778 Improved javadoc for secure session cookies
+ + 328782 allow per connection max idle time to be set
+ + 328885 web overrides do not override
+ + 328988 Idle saving of session values
+ + 329180 Spin check for Selector to stop
+ + 329410 Enforce XmlConfiguration properties as Map<String,String>
+ + 329602 only clear ServletContext attributes on doStop
+ + 329642 Concurrent modification exception in Deployment Manager
+ + 329643 Improved deployment of resource collections
+ + JETTY-748 Prevent race close of socket by old acceptor threads
+ + JETTY-1291 Extract query parameters even if POST content consumed
+ + JETTY-1295 Contexts mixed up when hot-deploying on virtual hosts
+ + JETTY-1297 Make ServletContext.getContext(String) virtual host aware
+
+jetty-6.1.26 - 10 November 2010
+ + JETTY-748 Prevent race close of socket by old acceptor threads
+ + JETTY-1239 HTAccessHandler [allow from 127.0.0.1] does not work
+ + JETTY-1291 Extract query parameters even if POST content consumed
+ + JETTY-1293 Avoid usage of String.split
+ + JETTY-1296 Always clear changes list in selectManager
+
+jetty-6.1.26.RC0 - 20 October 2010
+ + JETTY-547 Improved usage of shutdownOutput before close.
+ + JETTY-912 add per exchange timeout
+ + JETTY-1051 offer jetty.skip flag for maven plugin
+ + JETTY-1096 exclude maven and plexus classes from jetty plugin
+ + JETTY-1248 Infinite loop creating temp MultiPart files
+ + JETTY-1264 Idle timer deadlock
+ + JETTY-1271 Handle unavailable request
+ + JETTY-1278 J2se6 SPI filter handling fix
+ + JETTY-1283 Allow JSONPojoConvertorFactory to set fromJSON
+ + JETTY-1287 rewrite handler thread safe issue resolved
+ + JETTY-1288 info when atypical classloader set to WebAppContext
+ + JETTY-1289 MRU cache for filter chains
+ + JETTY-1292 close input streams after keystore.load()
+ + 325468 Clean work webapp dir before unpack
+ + 327109 Fixed AJP handling of empty packets
+ + 327562 Implement all X-Forwarded headers in ProxyServlet
+
+jetty-7.2.0.v20101020 - 20 October 2010
+ + 289540 added javadoc into distribution
+ + 297154 add source distribution artifact
+ + 323985 Xmlconfiguration pulls start.jar config properties
+ + 324369 Improved handling of multiple versions of
+   draft-ietf-hybi-thewebsocketprotocol
+ + 326734 Configure Digest maxNonceAge with Security handler init param
+ + 327109 Fixed AJP handling of empty packets
+ + 327183 Allow better configurability of HttpClient for TLS/SSL
+ + 327469 removed needless java6 dependencies
+ + 327562 Implement all X-Forwarded headers in ProxyServlet
+ + 327601 Multipart Filter handles quoted tokens
+ + 327725 Nested ResourceCaches
+ + 328199 Ensure blocking connectors always close socket
+ + 328205 Improved SelectManager stopping
+ + 328273 Added serializable to default user identity
+ + JETTY-1288 Info statement when atypical classloader set on WebAppContext
+ + JETTY-1289 LRU cache for filter chains
+
+jetty-7.2.0.RC0 - 01 October 2010
+ + 314087 Simplified SelectorManager
+ + 319334 Concurrent, sharable ResourceCache
+ + 319370 WebAppClassLoader.Context
+ + 319444 Two nulls are appended to log statements from ContextHanler$Context
+ + 320073 Reconsile configuration mechanism
+ + 320112 Websocket in aggregate jars
+ + 320264 Removed duplicate mime.property entries
+ + 320457 Added rfc2045 support to B64Code
+ + 321232 BasicAuthenticator ignores bad Authorization header.
+ + 321307 HashSessionManager calls passivation listeners.
+ + 321730 SelectChannelEndPoint prints to System.err
+ + 321735 HttpClient onException called for buffer overflow.
+ + 322448 Added jetty-dir.css for directory listings
+ + 322575 NPE in HotSwapHandler if old handler null
+ + 322683 RewriteHandler thread safety
+ + 323196 org.mortbay properties to org.eclipse
+ + 323435 MovedContextHandler permanent redirection
+ + 323464 IPv6 localhost with no Host header
+ + 324110 Merge async dispatch parameters
+ + 324158 Durable download or Orbit jars
+ + 324260 Jetty-6 continuations handle complete calls
+ + 324359 illegal actions on AsyncContext should not change its state.
+ + 324360 validate input on getResource since loop logic obscures subclass
+   input validation.
+ + 324369 Implement draft-ietf-hybi-thewebsocketprotocol-01
+ + 324377 Allow dispatch of ServletRequest and ServletResponse
+ + 324379 Change content type after getWriter
+ + 324501 Fire RequestListener.requestDestroyed in last-to-first order.
+ + 324601 Check session expiry on access
+ + 324679 Allow filter to write before static content
+ + 324811 NPE in Server.dump
+ + 324812 restore WebAppContext constructor used by geronimo integration
+ + 325072 include to DefaultServlet of missing file throws
+   FileNotFoundException
+ + 325105 websocket ondisconnect fixed
+ + 325128 websocket send during onConnect
+ + 325468 Clean work webapp dir before unpack
+ + 326612 Handle X-Forwarded-Proto header
+ + JETTY-912 added per exchange timeout api
+ + JETTY-1063 Plugin problems with spaces in classpath resource references
+ + JETTY-1245 Do not use direct buffers with NIO SSL
+ + JETTY-1249 Apply max idle time to all connectors
+ + JETTY-1250 Parallel start of HandlerCollection
+ + JETTY-1256 annotation and jta jars from Orbit
+ + JETTY-1259 NullPointerException in JDBCSessionIdManager when invalidating
+   session
+ + JETTY-1261 errant listener usage in StandardDescriptorProcessor
+ + JETTY-1263 JDBCSessionIdManager table creation fails on Oracle
+ + JETTY-1265 Reason field option in client response
+ + JETTY-1266 Destroy sessions before filters/servlets
+ + JETTY-1268 Form Auth saves POST data
+ + JETTY-1269 Improve log multithreadedness
+ + JETTY-1270 Websocket closed endp protection
+ + JETTY-1271 handled unavailable exception
+ + JETTY-1279 Make jetty-plus.xml enable plus features for all webapps by
+   default
+ + JETTY-1281 Create new session after authentication
+ + JETTY-1283 JSONPojoConvertorFactory can turn off fromJSON
+ + Fix jetty-plus.xml for new configuration names
+ + Added ignore to Logger interface
+ + Improved debug dump
+
+jetty-7.1.6.v20100715
+ + 319519 Warn about duplicate configuration files
+ + 319655 Reset HEAD status
+ + JETTY-1247 synchronize recylcing of SSL NIO buffers
+ + JETTY-1248 fix parsing of bad multiparts
+ + JETTY-1249 Apply max idle time to all connectors
+ + JETTY-1251 Replace then close selector for JVM bugs
+
+jetty-8.0.0.M1 - 12 July 2010
+ + 306350 Ensure jars excluded by ordering are not scanned for annotations
+ + JETTY-1224 Change jetty-8 merge rules for fragment descriptors and
+   annotations
+ + Ensure <absolute-ordering> in web.xml overrides relative <ordering> in
+   fragments
+ + Ensure empty <absolute-ordering> implies exclusion of all fragments
+ + Ensure servlet-api jar class inheritance hierarchy is scanned
+
+jetty-7.1.5.v20100705
+ + Update ecj to 3.6 Helios release drop
+ + 288194 Add blacklist/whitelist to ProxyServlet and ProxyHandler
+ + 296570 EOFException for HttpExchange when HttpClient.stop called.
+ + 311550 The WebAppProvider should allow setTempDirectory
+ + 316449 Websocket disconnect fix
+ + 316584 Exception on startup if temp path has spaces and extractWAR=false
+ + 316597 Removed null check and fixed name in Resource#hrefEncodeURI
+ + 316970 jetty.sh fails to find JETTY_HOME in standard directories
+ + 316973 jetty.sh claims java installation is invalid
+ + 316976 removed quotes of JAVA_OPTIONS in jetty.sh
+ + 317019 Date HTTP header not sent for HTTP/1.0 requests
+ + 317759 Allow roles and constraints to be added after init
+ + 317906 OPTIONS correctly handles TRACE
+ + 318308 Correct quoting of unicode control characters
+ + 318470 unboxing NPE protection in HttpConnection
+ + 318551 Optional uncheck Printwriter
+ + JETTY-1237 Save local/remote address to be available after close
+ + 317007 Unable to run Jetty OSGi when
+   -Dosgi.compatibility.bootdelegation=false
+ + 316909 CNFE: org.xml.sax.SAXException on org.eclipse.jetty.osgi.boot start
+   with jsp fragment
+ + 317231 Ability to configure jetty with a fragment bundle that contains
+   etc/jetty.xml
+ + 319060 Support web-bundles that are not expanded (bundle is zipped)
+
+jetty-6.1.25 - 26 July 2010
+ + Jetty-6 is now in maintenance mode.
+ + JETTY-1212 Long content lengths
+ + JETTY-1214 Avoid ISE when scavenging invalid session
+ + JETTY-1223 DefaultServlet: NPE when setting relativeResourceBase and
+   resourceBase is not set
+ + JETTY-1226 javax.activation needs to be listed in the system classes
+ + JETTY-1237 Remember local/remote details of endpoint
+ + JETTY-1251 protected against closed selector
+ + COMETD-112 if two threads create the same channel, then create events may
+   occur after subscribe events
+ + 320264 Removed duplicate mime.property entries
+
+jetty-7.1.4.v20100610
+ + 298551 SslSocketConnector does not need keystore stream
+ + 295715 AbstractSessionManager decoupled from Context
+ + 292326 Stop continuations if server is stopped.
+ + 292814 Make QoSFilter and DoSFilter JMX manageable
+ + 293222 Improve request log to handle/show asynchronous latency
+ + 294212 Can not customize session cookie path
+ + 301608 Deregister shutdown hooks
+ + 302350 org.eclipse.jetty.server.NCSARequestLog is missing JavaDoc
+ + 303661 jetty.sh failes if JETTY_HOME is not writeable
+ + 304100 Better document JMX setup in jetty-jmx.xml
+ + 305300 AsyncContext.start dispatches runnable
+ + 314299 Create test harness for JDBCLoginService
+ + 314581 Implement the Sec-Websocket handshake
+ + 315190 CrossOriginFilter avoid headers not understood by WebSocket
+ + 315687 included init script fails to test for JETTY_HOME as empty
+ + 315715 Improved Cookie version handling. Server.setMaxCookieVersion
+ + 315744 Fixed STOP.PORT and STOP.KEY in start.jar
+ + 315748 Removed --fromDaemon from start.jar (replaced with --daemon)
+ + 315925 Improved context xml configuration handling
+ + 315995 Incorrect package name in system classes list
+ + 316119 Fixed maxIdleTime for SocketEndPoint
+ + 316254 Implement @DeclareRoles
+ + 316334 Breaking change on org.eclipse.jetty.client.HttpExchange
+ + 316399 Debug output in MultiPartFilter
+ + 316413 Restarting webapp for packed war fails
+ + 316557 OSGi HttpService failure due to undeployed context handlers
+ + JETTY-547 Delay close after shutdown until request read
+ + JETTY-1231 Support context request log handler
+
+jetty-7.1.3.v20100526
+ + 296567 HttpClient RedirectListener handles new HttpDestination
+ + 297598 JDBCLoginService uses hardcoded credential class
+ + 305898 Websocket handles query string in URI
+ + 307457 Exchanges are left unhandled when connection is lost
+ + 313205 Unable to run test-jdbc-sessions tests
+ + 314177 JSTL support is broken
+ + 314009 jetty.xml configuration file on command line
+ + 314459 support maven3 for builds
+
+jetty-7.1.2.v20100523
+ + 308866 Update test suite to JUnit4 - Module jetty-util
+ + 312948 Recycle SSL crypto buffers
+ + 313196 randomly allocate ports for session test.
+ + 313278 Implement octet ranges in IPAccessHandler
+ + 313336 secure websockets
+ + 314009 updated README.txt
+ + Update links to jetty website and wiki on test webapp
+
+jetty-7.1.1.v20100517
+ + 302344 Make the list of available contexts if root context is not configured
+   optional
+ + 304803 Remove TypeUtil Integer and Long caches
+ + 306226 HttpClient should allow changing the keystore and truststore type
+ + 308857 Update test suite to JUnit4 - Module jetty-jndi
+ + 308856 Update test suite to JUnit4 - Module jetty-jmx
+ + 308860 Update test suite to JUnit4 - Module jetty-rewrite
+ + 308850 Update test suite to JUnit4 - Module jetty-annotations
+ + 308853 Update test suite to JUnit4 - Module jetty-deploy
+ + 308854 Update test suite to JUnit4 - Module jetty-http
+ + 308859 Update test suite to JUnit4 - Module jetty-policy
+ + 308858 Update test suite to JUnit4 - Module jetty-plus
+ + 308863 Update test suite to JUnit4 - Module jetty-servlet
+ + 308855 Update test suite to JUnit4 - Module jetty-io
+ + 308862 Update test suite to JUnit4 - Module jetty-server
+ + 308867 Update test suite to JUnit4 - Module jetty-webapp
+ + 310918 Fixed write blocking for client HttpConnection
+ + 312526 Protect shutdown thread initialization during shutdown
+
+jetty-7.1.0 - 05 May 2010
+ + 306353 fixed cross context dispatch to root context.
+ + 311154 Added deprecated StringBuffer API for backwards compatibility
+ + 311554 Protect shutdown thread from Server#doStop
+ + 312243 Optimized timeout handling
+
+jetty-7.1.0.RC1 - 05 May 2010
+ + 286889 Allow System and Server classes to be set on Server instance and when
+   applied to all webapps
+ + 291448 SessionManager has isCheckingRemoteSessionIdEncoding
+ + 296650 JETTY-1198 reset idle timeout on request body chunks
+ + 297104 HTTP CONNECT does not work correct with SSL destinations
+ + 306782 Close connection when expected 100 continues is not sent
+ + 308848 Update test suite to JUnit4 - Module jetty-ajp
+ + 308861 Update test suite to JUnit4 - Module jetty-security
+ + 308864 Update test suite to JUnit4 - Module jetty-servlets
+ + 308865 Update test suite to JUnit4 - Module jetty-start
+ + 308868 Update test suite to JUnit4 - Module jetty-websocket
+ + 308869 Update test suite to JUnit4 - Module jetty-xml
+ + 309153 Hide extracted WEB-INF/lib when running a non-extracted war
+ + 309369 Added WebSocketLoadTest
+ + 309686 Fixed response buffers usage
+ + 310094 Improved start.jar options handling and configs
+ + 310382 NPE protection when WAR is not a file
+ + 310562 SslSocketConnector fails to start if excludeCipherSuites is set
+ + 310634 Get the localport when opening a server socket.
+ + 310703 Update test suite to JUnit4 - Module tests/test-integration
+ + 310918 Synchronize content exchange
+ + 311154 Use Appendable in preference to StringBuilder/StringBuffer in APIs
+ + 311362 Optional org.eclipse.jetty.util.log.stderr.SOURCE
+ + JETTY-1030 Improve jetty.sh script
+ + JETTY-1142 Replace Set-Cookies with same name
+
+jetty-7.1.0.RC0 - 27 April 2010
+ + 294563 Websocket client connection
+ + 297104 Improve handling of CONNECT method
+ + 306349 ProxyServlet does not work unless deployed at /
+ + 307294 Add AbstractLifeCycle.AbstractLifeCycleListener implementation
+ + 307847 Fixed combining mime type parameters
+ + 307898 Handle large/async websocket messages
+ + 308009 ObjectMBean incorrectly casts getTargetException() to Exception
+ + 308420 convert jetty-plus.xml to use DeploymentManager
+ + 308925 Protect the test webapp from remote access
+ + 309466 Removed synchronization from StdErrLog
+ + 309765 Added JSP module
+ + 310051 _configurationClasses now defaults to null in WebAppContext
+ + 310094 Improved start.jar usage and config files
+ + 310431 Default ErrorHandler as server Bean
+ + 310467 Allow SocketConnector to create generic Connection objects
+ + 310603 Make Logger interface consistent
+ + 310605 Make a clean room implementation of the JSP logger bridge
+ + Add AnnotationConfiguration to jetty-plus.xml
+ + Fix jetty-plus.xml reference to addLifeCycle
+ + JETTY-1200 SSL NIO Endpoint wraps non NIO buffers
+ + JETTY-1202 Use platform default algorithm for SecureRandom
+ + Merged 7.0.2.v20100331
+ + Add NPE protection to ContainerInitializerConfiguration
+ + Temporarily remove jetty-osgi module to clarify jsp version compatibility
+ + JETTY-1212 handle long content lengths
+ + JETTY-1214 avoid ISE when scavenging invalid session
+ + JETTY-903 Stop both caches
+
+jetty-7.0.2.v20100331 - 31 March 2010
+ + 297552 Don't call Continuation timeouts from acceptor tick
+ + 298236 Additional unit tests for jetty-client
+ + 306783 NPE in StdErrLog when Throwable is null
+ + 306840 Suppress content-length in requests with no content
+ + 306880 Support for UPGRADE in HttpClient
+ + 306884 Suspend with timeout <=0 never expires
+ + 306782 httpbis interpretation of 100 continues. Body never skipped
+ + 307589 updated servlet 3.0 continuations for final API
+ + Take excess logging statements out of startup
+ + Ensure webapps with no WEB-INF don't scan WEB-INF/lib
+ + Allow Configuration array to be set on Server instance for all web apps
+
+jetty-6.1.24 - 21 April 2010
+ + JETTY-903 Stop both caches
+ + JETTY-1198 reset idle timeout on request body chunks
+ + JETTY-1200 SSL NIO Endpoint wraps non NIO buffers
+ + JETTY-1211 SetUID loadlibrary name and debug
+ + 308925 Protect the test webapp from remote access
+ + COMETD-99 ClientImpl logs exceptions in listeners with "debug" level
+ + COMETD-100 ClientImpl logs "null" as clientId
+ + COMETD-107 Reloading the application with reload extension does not fire
+   /meta/connect handlers until long poll timeout expires
+ + Upgraded to cometd 1.1.1 client
+
+jetty-6.1.23 - 02 April 2010
+ + JSON parses NaN as null
+ + Updated JSP to 2.1.v20091210
+ + COMETD-28 Improved concurrency usage in Bayeux and channel handling
+ + COMETD-46 reset ContentExchange content on resend
+ + COMETD-58 Extension.rcv() return null causes NPE in
+   AbstractBayeux.PublishHandler.publish
+ + COMETD-59 AcknowledgeExtension does not handle null channel in Message
+ + COMETD-62 Delay add listeners until after client construction
+ + 296569 removeLifeCycleListener() has no effect
+ + 292800 ContextDeployer - recursive setting is undone by FilenameFilter
+ + 300178 HttpClients opens too many connections that are immediately closed
+ + 304658 Inconsistent Expires date format in Set-Cookie headers with maxAge=0
+ + 304698 org.eclipse.jetty.http.HttpFields$DateGenerator.formatCookieDate()
+   uses wrong (?) date format
+ + 306331 Session manager is kept after call to doScope
+ + 306840 suppress content-length in requests without content
+ + Remove references to old content in HttpClient client tests for www.sun.com
+ + JETTY-875 Allow setting of advice field in response to Handshake
+ + JETTY-983 Range handling cleanup
+ + JETTY-1133 Handle multiple URL ; parameters
+ + JETTY-1134 BayeuxClient: Connect msg should be sent as array
+ + JETTY-1149 transient should be volatile in AbstractLifeCycle
+ + JETTY-1153 System property for UrlEncoded charset
+ + JETTY-1155 HttpConnection.close notifies HttpExchange
+ + JETTY-1156 SSL blocking close with JVM Bug busy key fix
+ + JETTY-1157 Don't hold array passed in write(byte[])
+ + JETTY-1158 NPE in StdErrLog when Throwable is null
+ + JETTY-1161 An Extension that measures round-trip delay for cometd messages.
+ + JETTY-1162 Add support for async/sync message delivery to BayeuxClient
+ + JETTY-1163 AJP13 forces 8859-1 encoding
+ + JETTY-1168 Don't hold sessionIdManager lock when invalidating sessions
+ + JETTY-1170 NPE on client when server-side extension returns null
+ + JETTY-1174 Close rather than finish Gzipstreams to avoid JVM leak
+ + JETTY-1175 NPE in TimesyncExtension
+ + JETTY-1176 NPE in StatisticsExtension if client is null
+ + JETTY-1177 Allow error handler to set cacheControl
+ + JETTY-1178 Make continuation servlet to log the incoming JSON in case of
+   parsing errors
+ + JETTY-1180 Extension methods are wrongly called
+ + JETTY-1182 COMETD-76 do not lock client while sending messages.
+ + JETTY-1183 AcknowledgedMessagesClientExtension does not handle correctly
+   message resend when client long polls again
+ + JETTY-1186 Better document JMX setup in jetty-jmx.xml
+ + JETTY-1188 Null old jobs in QueuedThreadPool
+ + JETTY-1191 Limit size of ChannelId cache
+ + JETTY-1192 Fixed Digested POST and HttpExchange onRetry
+ + JETTY-1193 Exception details are lost in AbstractCometdServlet.getMessages
+ + JETTY-1195 Coalesce buffers in ChannelEndPoint.flush()
+ + JETTY-1196 Enable TCP_NODELAY by default in client connectors
+ + JETTY-1197 SetUID module test fails when using Java 1.6 to build
+ + JETTY-1199 FindBugs cleanups
+ + JETTY-1205 Memory leak in browser-to-client mapping
+ + JETTY-1207 NPE protection in FormAuthenticator
+ + JETTY-1202 Use platfrom default algorithm for SecureRandom
+
+jetty-7.0.2.RC0
+ + JSON parses NaN as null
+ + 290765 Reset input for HttpExchange retry.
+ + 292799 WebAppDeployer - start a started context?
+ + 292800 ContextDeployer - recursive setting is undone by FilenameFilter
+ + 294799 when configuring a webapp, don't look for WEB-INF/jetty6-web.xml
+ + 296569 removeLifeCycleListener() has no effect
+ + 296765 JMX Connector Server and ShutdownThread
+ + 297421 Hide server/system classes from WebAppClassLoader.getResources
+ + 297783 Handle HEAD reponses in HttpClient
+ + 298144 Unit test for jetty-client connecting to a server that uses Basic
+   Auth
+ + 298145 Reorganized test harness to separate the HTTP PUT and HTTP GET test
+   URLs
+ + 298234 Unit test for jetty-client handling different HTTP error codes
+ + 298667 DeploymentManager uses ContextProvider and WebAppProvider
+ + 299455 Enum support in JSONPojoConvertor
+ + 300178 HttpClients opens too many connections that are immediately closed
+ + 300733 Jars from lib/ext are not visible for my web application
+ + 300933 AbstractConnector uses concurrent objects for stats
+ + 301089 Improve statistics available in StatisticsHandler and
+   AbstractConnector
+ + 302018 Improve statistics available in AbstractSessionHandler
+ + 302198 Rename HttpClient authorization classes to Authentication
+ + 302244 invalid configuration boolean conversion in FormAuthenticator
+ + 302246 redirect loop using form authenticator
+ + 302556 CrossOriginFilter does not work correctly when
+   Access-Control-Request-Headers header is not present
+ + 302669 WebInfConfiguration.unpack() unpacks WEB-INF/* from a
+   ResourceCollection, breaking JSP reloading with ResourceCollections
+ + 303526 Added include cyphers
+ + 304307 Handle ;jsessionid in FROM Auth
+ + 304532 Skip some tests on IBM JVMs until resolved
+ + 304658 Inconsistent Expires date format in Set-Cookie headers with maxAge=0
+ + 304698 org.eclipse.jetty.http.HttpFields$DateGenerator.formatCookieDate()
+   uses wrong (?) date format
+ + 304781 Reset HttpExchange timeout on slow request content.
+ + 304801 SSL connections FULL fix
+ + 306330 Flush filter chain cache after Invoker servlet
+ + 306331 Session manager is kept after call to doScope
+ + JETTY-776 Make new session-tests module to concentrate all reusable session
+   clustering test code
+ + JETTY-910 Allow request listeners to access session
+ + JETTY-983 Range handling cleanup
+ + JETTY-1151 JETTY-1098 allow UTF-8 with 0 carry bits
+ + JETTY-1153 System property for UrlEncoded charset
+ + JETTY-1155 HttpConnection.close notifies HttpExchange
+ + JETTY-1156 SSL blocking close with JVM Bug busy key fix
+ + JETTY-1157 Don't hold array passed in write(byte[])
+ + JETTY-1163 AJP13 forces 8859-1 encoding
+ + JETTY-1177 Allow error handler to set cacheControl
+ + JETTY-1179 Persistant session tables created on MySQL use wrong datatype
+ + JETTY-1184 shrink thread pool even with frequent small jobs
+ + JETTY-1133 Handle multiple URL ; parameters
+ + JETTY-1174 Close rather than finish Gzipstreams to avoid JVM leak
+ + JETTY-1192 Fixed Digested POST
+ + JETTY-1199 FindBugs cleanups
+ + COMETD-46 reset ContentExchange response content on resend
+ + Added IPAccessHandler
+ + Updated Servlet3Continuation to final 3.0.20100224
+ + 305997 Coalesce buffers in ChannelEndPoint.flush()
+ + 306028 Enable TCP_NODELAY by default in client connectors
+
+jetty-8.0.0.M0 - 28 February 2010
+ + Updated servlet 3.0 spec 20100224
+ + Merged 7.0.1.v20091116
+ + Updated to cometd 1.0.1
+
+jetty-7.0.1.v20091125 - 25 November 2009
+ + 274251 DefaultServlet supports exact match mode.
+ + 288401 HttpExchange.cancel() Method Unimplemented
+ + 289027 deobfuscate HttpClient SSL passwords
+ + 289265 Test harness for async input
+ + 289959 Improved ContextDeployer configuration
+ + 289960 start.jar assumes command line args are configs
+ + 291019 Fix default DEBUG option; "-D.DEBUG=true" now works
+ + 291340 Race condition in onException() notifications
+ + 291543 make bin/*.sh scripts executable in distribution
+ + 291589 Update jetty-rewrite demo
+ + 292642 Fix errors in embedded Jetty examples
+ + 292825 Continuations ISE rather than ignore bad transitions
+ + 292546 Proactively enforce HttpClient idle timeout
+ + 293222 Improved StatisticsHandler for async
+ + 293506 Unable to use jconsole with Jetty when running with security manager
+ + 293557 Add "jad" mime mapping
+ + 294154 Patched jetty-osgi
+ + 294224 HttpClient timeout setting has no effect when connecting to host
+ + 294345 Support for HTTP/301 + HTTP/302 response codes
+ + 294563 Initial websocket implementation
+ + JETTY-937 More JVM bug work arounds. Insert pause if all else fails
+ + JETTY-983 Send content-length with multipart ranges
+ + JETTY-1114 unsynchronised WebAppClassloader.getResource(String)
+ + JETTY-1121 Merge Multipart query parameters
+ + JETTY-1122 Handle multi-byte utf that causes buffer overflow
+ + JETTY-1125 TransparentProxy incorrectly configured for test webapp
+ + JETTY-1129 Filter control characters out of StdErrLog
+ + JETTY-1135 Handle connection closed before accepted during JVM bug work
+   around
+ + JETTY-1144 fixed multi-byte character overflow
+ + JETTY-1148 Reset partially read request reader.
+ + COMETD-34 Support Baeyux MBean
+ + Fixed XSS issue in CookieDump demo servlet.
+ + Improved start.jar usage text for properties
+ + Promoted Jetty Centralized Logging from Sandbox
+ + Promoted Jetty WebApp Verifier from Sandbox
+ + Refactored continuation test harnessess
+ + Fixed client abort asocciation
+ + CQ-3581 jetty OSGi contribution
+ + Moved centralized logging and verifier back to sandbox
+ + CVE-2009-3555 Prevent SSL renegotiate for SSL vulnerability
+ + 295421 Cannot reset() a newly created HttpExchange: IllegalStateException 0
+   => 0
+ + 295562 CrossOriginFilter does not work with default values in Chrome and
+   Safari
+
+jetty-7.0.0.v20091005 - 05 October 2009
+ + 291340 Race condition in onException() notifications
+
+jetty-6.1.21 - 22 September 2009
+ + JETTY-719 Document state machine of jetty http client
+ + JETTY-933 State == HEADER in client
+ + JETTY-936 Improved servlet matching and optimized
+ + JETTY-1038 ChannelId.isParentOf returns the wrong result
+ + JETTY-1061 Catch exceptions from cometd listeners
+ + JETTY-1072 maven plugin handles context path not as documented
+ + JETTY-1080 modified previous fix for windows
+ + JETTY-1084 HEAD command not setting content-type in response under certain
+   circumstances
+ + JETTY-1090 resolve inifinte loop condition for webdav listener
+ + JETTY-1092 MultiPartFilter can be pushed into infinite loop
+ + JETTY-1093 Request.toString throws exception when size exceeds 4k
+ + JETTY-1098 Default form encoding is UTF8
+ + JETTY-1099 Improve cookie handling in BayeuxClient
+ + JETTY-1100 extend setuid feature to allow setting max open file descriptors
+ + JETTY-1102 Wrong usage of deliver() in private chat messages
+ + JETTY-1108 SSL EOF detection
+ + JETTY-1109 Improper handling of cookies in Terracotta tests
+ + JETTY-1112 Response fails if header exceeds buffer size
+ + JETTY-1113 IllegalStateException when adding servlet filters
+   programmatically
+ + JETTY-1114 Unsynchronize webapp classloader getResource
+ + 282543 HttpClient SSL buffer size fix
+ + 288055 fix jetty-client for failed listener state machine
+ + 288153 reset exchange when resending
+ + 288182 PUT request fails during retry
+ + Fix DefaultServletTest for windows
+ + Update Jetty implementation of com.sun.net.httpserver.*
+ + Include tmp directory sweeper in build
+ + Streamline jetty-jboss build, update sar to QueuedThreadPool
+
+jetty-7.0.0.RC6 - 21 September 2009
+ + Fixed XSS issue in CookieDump demo servlet.
+ + 289958 StatisticsServlet incorrectly adds StatisticsHandler
+ + 289960 start.jar assumes command line args are configs
+ + 290081 Eager consume LF after CR
+ + 290761 HttpExchange isDone handles intercepted events.
+ + JETTY-719 Document state machine of jetty http client
+ + JETTY-780 CNFE during startup of webapp with spring-context >= 2.5.1
+ + JETTY-936 274251 Improved servlet matching and optimized'
+ + JETTY-1080 modify previous fix to work on windows
+ + JETTY-1084 HEAD command not setting content-type in response under certain
+   circumstances
+ + JETTY-1086 Use UncheckedPrintWriter & cleaned up HttpStatus.Code usage
+ + JETTY-1090 resolve potential infinite loop with webdav listener
+ + JETTY-1092 MultiPartFilter can be pushed into infinite loop
+ + JETTY-1093 Request.toString throws exception when size exceeds 4k
+ + JETTY-1098 Default form encoding is UTF8
+ + JETTY-1101 Updated servlet3 continuation constructor
+ + JETTY-1105 Custom error pages aren't working
+ + JETTY-1108 SSL EOF detection
+ + JETTY-1112 Response fails if header exceeds buffer size
+ + JETTY-1113 IllegalStateException when adding servlet filters
+   programmatically
+ + 280723 Add non blocking statistics handler
+ + 282543 HttpClient SSL buffer size fix
+ + 283357 org.eclipse.jetty.server.HttpConnectionTest exceptions
+ + 288055 jetty-client fails to resolve failed resolution attempts correctly
+ + 288153 jetty-client resend doesn't reset exchange
+ + 288466 LocalConnector is not thread safe
+ + 288514 AbstractConnector does not handle InterruptedExceptions on shutdown
+ + 288772 Failure to connect does not set status to EXCEPTED
+ + 289146 formalize reload policy functionality
+ + 289156 jetty-client: no longer throw runtime exception for bad authn details
+ + 288182 PUT request fails during retry
+ + 289221 HttpExchange does not timeout when using blocking connector
+ + 289285 org.eclipse.jetty.continuation 7.0.0.RC5 imports the
+   org.mortbay.util.ajax package
+ + 289686 HttpExchange.setStatus() has too coarse synchronization
+ + Tweak DefaultServletTest under windows
+ + Copy VERSION.txt to distro
+ + Remove printlns from jetty-plus
+
+jetty-6.1.20 - 27 August 2009
+ + JETTY-838 Don't log and throw
+ + JETTY-874 Better error on full header.
+ + JETTY-960 Support ldaps
+ + JETTY-1046 maven-jetty-jspc-plugin keepSources takes affect only in
+   packageRoot
+ + JETTY-1057 XSS error page
+ + JETTY-1065 Add RedirectRegexRule to provide match/replace/group redirect
+   support
+ + JETTY-1066 Send 400 error for request URI parse exceptions
+ + JETTY-1068 Avoid busy flush of async SSL
+ + JETTY-1069 Adjust Bayeux Java client backoff algorithm
+ + JETTY-1070 Java Bayeux Client not sending /meta/disconnect on stop
+ + JETTY-1074 JMX thread manipulation
+ + JETTY-1077 HashSSORealm shares Principals between UserRealms
+ + JETTY-1078 Automatic JSON Pojo Conversion
+ + JETTY-1079 ResourceCollection.toString() can throw IllegalStateException
+ + JETTY-1080 Ignore files that would be extracted outside the destination
+   directory when unpacking WARs
+ + JETTY-1081 Handle null content type in GzipFilter
+ + JETTY-1084 Disable GzipFilter for HEAD requests
+ + JETTY-1085 Allow url sessionID if cookie invalid
+ + JETTY-1086 Added UncheckedPrintWriter to avoid ignored EOFs
+ + JETTY-1087 Chunked SSL non blocking input
+ + JETTY-1098 Upgrade jsp to SJSAS-9_1_1-B60F-07_Jan_2009
+ + 283513 Check endp.isOpen when blocking read
+ + 283818 fixed merge of forward parameters
+ + 285006 Fixed NPE in AbstractConnector during shutdown
+ + 286535 ContentExchange status code
+ + 286911 Clean out cache when recycling HTTP fields
+ + COMETD-7 max latency config for lazy messages
+ + Added getSubscriptions to cometd client
+ + Made unSubscribeAll public on cometd client
+ + Removed clearing of queue in unSubscribeAll for cometd client
+ + Update test-jndi and test-annotation examples for atomikos 3.5.5
+ + Clarified cometd interval timeout and allow per client intervals
+ + Update Main.main method to call setWar
+ + Added DebugHandler
+
+jetty-7.0.0.RC5 - 27 August 2009
+ + 286911 Clean out cache when recycling HTTP fields
+ + JETTY-838 Don't log and throw
+ + JETTY-874 Better header full warnings
+ + JETTY-960 Support for ldaps
+ + JETTY-1081 Handle null content type in GzipFilter
+ + JETTY-1084 Disable GzipFilter for HEAD requests
+ + JETTY-1085 Allow url sessionID if cookie invalid
+ + JETTY-1086 Added UncheckedPrintWriter to avoid ignored EOFs
+ + JETTY-1087 Chunked SSL non blocking input
+ + 287496 Use start.ini always and added --exec
+ + 287632 FilterContinuations for blocking jetty6
+
+jetty-6.1.19 - 01 July 2009
+ + JETTY-799 shell script for jetty on cygwin
+ + JETTY-863 Non blocking stats handler
+ + JETTY-937 Further Improvements for sun JVM selector bugs
+ + JETTY-970 BayeuxLoadGenerator latency handling
+ + JETTY-1011 Grizzly uses queued thread pool
+ + JETTY-1028 jetty:run plugin should check for the web.xml from the overlays
+   if not found in src/main/webapp/WEB-INF/
+ + JETTY-1029 Handle quoted cookie paths
+ + JETTY-1031 Handle large pipeline
+ + JETTY-1033 jetty-plus compiled with jdk1.5
+ + JETTY-1034 Cookie parsing
+ + JETTY-1037 reimplemented channel doRemove
+ + JETTY-1040 jetty.client.HttpConnection does not handle non IOExceptions
+ + JETTY-1042 Avoid cookie reuse on shared connection
+ + JETTY-1044 add commons-daemon support as contrib/start-daemon module
+ + JETTY-1045 Handle the case where request.PathInfo() should be "/*"
+ + JETTY-1046 maven-jetty-jspc-plugin keepSources takes affect only in
+   packageRoot
+ + JETTY-1047 Cometd client can grow cookie headers
+ + JETTY-1048 Default servlet can handle partially filtered large static
+   content
+ + JETTY-1049 Improved transparent proxy usability
+ + JETTY-1054 Avoid double deploys
+ + JETTY-1055 Cookie quoting
+ + JETTY-1057 Error page stack trace XSS
+ + JETTY-1058 Handle trailing / with aliases on
+ + JETTY-1062 Don't filter cometd message without data
+
+jetty-7.0.0.RC4 - 18 August 2009
+ + 286185 Implement ability for JSON implementation to automatically register
+   convertors
+ + Added discoverable start options
+ + 286535 ContentExchange status code
+ + 285891 SessionAuthentication is serializable
+ + JETTY-1079 ResourceCollection.toString
+ + 279820 Fixed HotSwapHandler
+ + JETTY-1080 Ignore files that would be extracted outside the destination
+   directory when unpacking WARs
+ + JETTY-1057 XSS error page
+
+jetty-7.0.0.RC3 - 07 August 2009
+ + 277403 remove system properties
+ + JETTY-1074 JMX thread manipulation
+ + Improved deferred authentication handling
+ + 285697 extract parameters if dispatch has query
+ + 282447 concurrent destinations in HttpClient
+ + 283172 fix Windows build, broken on directory creation with the
+   DefaultServlet
+ + 283375 additional error-checking on SSL connector passwords to prevent NPE
+ + 283513 Check endp.isOpen when blocking read
+
+jetty-7.0.0.RC2 - 29 June 2009
+ + 283844 Webapp / TLD errors are not clear
+ + 283375 improved extensibility of SSL connectors
+ + 283818 fixed merge of forward parameters
+ + backport jetty-8 annotation parsing to jetty-7
+ + Disassociate method on IdentityService
+ + 284510 Enhance jetty-start for diagnosis and unit testing
+ + 284475 update jetty.sh for new OPTIONS syntax
+ + Added DebugHandler
+ + Added JavaUtilLog for Jetty logging to java.util.logging framework
+ + 284981 Implement a cross-origin filter
+ + Improved handling of overlays and resourceCollections
+ + 285006 fix AbstractConnector NPE during shutdown.
+
+jetty-7.0.0.RC1 - 15 June 2009
+ + JETTY-1066 283357 400 response for bad URIs
+ + JETTY-1068 Avoid busy flush of async SSL
+ + 283344 Startup on windows is broken
+
+jetty-7.0.0.RC0 - 08 June 2009
+ + JETTY-967 create standalone build for PKCS12Import at codehaus
+ + JETTY-1056 update jetty-ant module for Jetty 7 at codehaus trunk
+ + JETTY-1058 Handle trailing / with aliases
+ + 280843 Buffer pool uses isHeader
+ + 271535 Adding integration tests, and enabling RFC2616 tests
+ + 281287 Handle date headers before 1 Jan 1970
+ + 282807 Better handling of 100 continues if response committed.
+
+jetty-7.0.0.M4 - 01 June 2009
+ + 281059 NPE in QTP with debug on
+ + JETTY-799 shell script for jetty on cygwin
+ + JETTY-1031 Handle large pipeline
+ + JETTY-1034 Cookie parsing
+ + JETTY-1042 Prevent cookie leak between shared connection
+ + JETTY-1048 Fix for large partially filtered static content
+ + JETTY-1049 Improved transparent proxy usability
+ + JETTY-1054 Avoid double deploys
+ + JETTY-1055 Cookie quoting
+ + JETTY-1057 Error page stack trace XSS
+
+jetty-7.0.0.M3 - 20 June 2009
+ + fixed race with expired async listeners
+ + refactored configuration mechanism
+ + added WebAppContext.setConfigurationDiscovered for servlet 3.0 features
+ + 274251 Allow dispatch to welcome files that are servlets (configurable)
+ + 277403 Cleanup system property usage.
+ + 277798 Denial of Service Filter
+ + Portable continuations for jetty6 and servlet3
+ + Refactored continuations to only support response wrapping
+ + Added ContinuationThrowable
+ + 276545 Quoted cookie paths
+ + 279725 Support 100 and 102 expectations
+ + Refactored AbstractBuffers to HttpBuffers for performance
+ + Numerous cleanups from static code analysis
+ + 280707 client.HttpConnection does not catch and handle non-IOExceptions
+ + 281470 Handle the case where request.PathInfo() should be "/*"
+
+jetty-7.0.0.M2 - 18 May 2009
+ + JETTY-937 Work around Sun JVM bugs
+ + JETTY-941 Linux chkconfig hint
+ + JETTY-959 CGI servlet doesn't kill the CGI in case the client disconnects
+ + JETTY-980 Fixed ResourceHandler ? handling, and bad URI creation in listings
+ + JETTY-996 Make start-stop-daemon optional
+ + 273767 Update to use geronimo annotations spec 1.1.1
+ + JETTY-1003 java.lang.IllegalArgumentException: timeout can't be negative
+ + JETTY-1004 CERT VU#402580 Canonical path handling includes ? in path segment
+ + JETTY-1013 MySql Error with JDBCUserRealm
+ + JETTY-1014 Enable start-stop-daemon by default on jetty.sh
+   (START_STOP_DAEMON=1)
+ + JETTY-1015 Reduce BayeuxClient and HttpClient lock contention
+ + JETTY-1020 ZipException in org.mortbay.jetty.webapp.TagLibConfiguration
+   prevents all contexts from being loaded
+ + 275396 Added ScopedHandler to set servlet scope before security handler
+
+jetty-6.1.18 - 16 May 2009
+ + JETTY-937 Improved work around sun JVM selector bugs
+ + JETTY-1004 CERT VU#402580 Canonical path handling includes ? in path segment
+ + JETTY-1008 ContinuationBayeux destroy is called
+ + JETTY-1013 MySql Error with JDBCUserRealm
+ + JETTY-1014 Enable start-stop-daemon by default on jetty.sh
+   (START_STOP_DAEMON=1)
+ + JETTY-1015 Reduce BayeuxClient and HttpClient lock contention
+ + JETTY-1017 HttpDestination has too coarse locking
+ + JETTY-1018 Denial of Service Filter
+ + JETTY-1020 ZipException in org.mortbay.jetty.webapp.TagLibConfiguration
+   prevents all contexts from being loaded
+ + JETTY-1022 Removed several 1.5isms
+
+jetty-5.1.15 - 18 May 2009
+ + JETTY-418 synchronized load class
+ + JETTY-1004 CERT VU402580 Canonical path handling includes ? in path segment
+ + Fixes for CERT438616-CERT237888-CERT21284
+
+jetty-6.1.17 - 30 April 2009
+ + JETTY-936 Make optional dispatching to welcome files as servlets
+ + JETTY-937 Work around sun JVM selector bugs
+ + JETTY-941 Linux chkconfig hint
+ + JETTY-957 Reduce hardcoded versions
+ + JETTY-980 Security / Directory Listing XSS present
+ + JETTY-982 Make test-jaas-webapp run with jetty:run
+ + JETTY-983 Default Servlet sets accept-ranges for cached/gzipped content
+ + JETTY-988 X-Forwarded-Host has precedence over X-Forwarded-Server
+ + JETTY-989 GzipFilter handles addHeader
+ + JETTY-990 Async HttpClient connect
+ + JETTY-992 URIUtil.encodePath encodes markup characters
+ + JETTY-996 Make start-stop-daemon optional
+ + JETTY-997 Remove jpackage-utils dependency on rpm install
+ + JETTY-985 Allow listeners to implement both interfaces
+ + JETTY-1000 Avoided needless 1.5 dependency
+ + JETTY-1002 cometd-api to 1.0.beta8
+ + JETTY-1003 java.lang.IllegalArgumentException: timeout can't be negative
+ + JETTY-1004 CERT VU#402580 Canonical path handling includes ? in path segment
+ + JETTY-1006 Resume meta connect on all XD messages
+
+jetty-7.0.0.M1 - 22 April 2009
+ + 271258 FORM Authentication dispatch handling avoids caching
+ + Initial support for LoginService.logout
+ + Removed HTTPConnection specifics from connection dispatching
+ + JETTY-695 Handler dump
+ + Reworked authentication for deferred authentication
+ + Reworked JMX for new layout
+ + JETTY-983 DefaultServlet generates accept-ranges for cached/gzip content
+ + 273011 JETTY-980 JETTY-992 Security / Directory Listing XSS present
+ + 271536 Add support to IO for quietly closing Readers / Writers
+ + 273101 Fix DefaultServletTest XSS test case
+ + 273153 Test for Nested references in DispatchServlet
+
+jetty-6.1.16 - 01 April 2009
+ + JETTY-702 Create "jetty-tasks.xml" for the Ant plugin
+ + JETTY-899 Standardize location for configuration files which go into etc
+ + JETTY-936 Allow dispatch to welcome files that are servlets
+ + JETTY-944 Lazy messages don't prevent long polls waiting
+ + JETTY-946 Redeploys with maven jetty plugin of webapps with overlays don't
+   work
+ + JETTY-947 Exception stops terracotta session scavenger
+ + JETTY-948 ConcurrentModificationException in TerracottaSessionManager
+   scavenger
+ + JETTY-949 Move cometd source to cometd.org project
+ + JETTY-953 SSL keystore file input stream is not being closed directly
+ + JETTY-956 SslSelectChannelConnector - password should be the default value
+   of keyPassword if not specified
+ + JETTY-959 CGI servlet doesn't kill the CGI in case the client disconnects
+ + JETTY-964 Typo in Jetty 6.1.15 Manifest - Bundle-RequiredExcutionEnvironment
+ + JETTY-972 Move cometd code back from cometd.org project (temporarily)
+ + JETTY-973 Deliver same message to a collection of cometd Clients
+
+jetty-7.0.0.M0 - 27 March 2009
+ + JETTY-496 Support inetd/xinetd through use of System.inheritedChannel()
+ + JETTY-540 Merged 3.0 Public Review changes
+ + JETTY-567 Delay in initial TLS Handshake With FireFox 3 beta5 and
+   SslSelectChannelConnector
+ + JETTY-600 Automated tests of WADI integration + upgrade to WADI 2.0
+ + JETTY-691 System.getProperty() calls ... wrap them in doPrivileged
+ + JETTY-713 Expose additional AbstractConnector methods via MBean
+ + JETTY-731 Completed DeliverListener for cometd
+ + JETTY-748 RandomAccessFileBuffer for hadoop optimization
+ + JETTY-749 Improved ArrayQueue
+ + JETTY-765 ensure stop mojo works for all execution phases
+ + JETTY-774 Improved caching of mime types with charsets
+ + JETTY-775 AbstractSessionTest remove timing related test
+ + JETTY-778 handle granular windows timer in lifecycle test
+ + JETTY-779 Fixed line feed in request log
+ + JETTY-781 Add "mvn jetty:deploy-war" for deploying a pre-assembled war
+ + JETTY-782 Implement interval advice for BayeuxClient
+ + JETTY-783 Update jetty self-signed certificate
+ + JETTY-784 TerracottaSessionManager leaks sessions scavenged in other nodes
+ + JETTY-786 Allow DataSourceUserRealm to create tables
+ + JETTY-787 Handle MSIE7 mixed encoding
+ + JETTY-788 Fix jotm for scoped jndi naming
+ + JETTY-790 WaitingContinuations can change mutex if not pending
+ + JETTY-792 TerracottaSessionManager does not unlock new session with
+   requested id
+ + JETTY-793 Fixed DataCache millisecond rounding
+ + JETTY-794 WADI integration tests fail intermittently.
+ + JETTY-795 NullPointerException in SocketConnector.java
+ + JETTY-801 Bring back 2 arg EnvEntry constructor
+ + JETTY-802 Modify the default error pages to make association with Jetty
+   clearer
+ + JETTY-804 HttpClient timeout does not always work
+ + JETTY-805 Fix jetty-jaas.xml for new UserRealm package
+ + JETTY-806 Timeout related Deadlocks in HTTP Client
+ + JETTY-807 HttpTester to handle charsets
+ + JETTY-808 cometd client demo run.sh
+ + JETTY-809 Need a way to customize WEB-INF/lib file extensions that are added
+   to the classpath
+ + JETTY-811 Allow configuration of system properties for the maven plugin
+   using a file
+ + JETTY-813 Simplify NCSARequestLog.java
+ + JETTY-814 Add org.eclipse.jetty.client.Address.toString()
+ + JETTY-816 Implement reconnect on java bayeux client
+ + JETTY-817 Aborted SSL connections may cause jetty to hang with full cpu
+ + JETTY-818 Support javax.servlet.request.ssl_session_id
+ + JETTY-821 Allow lazy loading of persistent sessions
+ + JETTY-822 Commit when autocommit=true causes error with mysql
+ + JETTY-823 Extend start.config profiles
+ + JETTY-824 Access to inbound byte statistics
+ + JETTY-825 URL decoding of spaces (+) fails for encoding not utf8
+ + JETTY-830 Add ability to reserve connections on http client
+ + JETTY-831 Add ability to stop java bayeux client
+ + JETTY-832 More UrlDecoded handling in relation to JETTY-825
+ + JETTY-834 Configure DTD does not allow <Map> children
+ + JETTY-837 Response headers set via filter are ignored for static resources
+ + JETTY-840 add default mime types to *.htc and *.pps
+ + JETTY-841 Duplicate messages when sending private message to yourself with
+   cometd chat demo
+ + JETTY-842 NPE in jetty client when no path component
+ + JETTY-843 META-INF/MANIFEST.MF is not present in unpacked webapp
+ + JETTY-844 Replace reflection with direct invocation in Slf4jLog
+ + JETTY-848 Temporary folder not fully cleanup after stop (via Sweeper)
+ + JETTY-854 JNDI scope does not work with applications in a .war
+ + JETTY-859 MultiPartFilter ignores the query string parameters
+ + JETTY-861 switched buffer pools to ThreadLocal implementation
+ + JETTY-862 EncodedHttpURI ignores given encoding in constructor
+ + JETTY-866 jetty-client test case fix
+ + JETTY-869 NCSARequestLog locale config
+ + JETTY-870 NullPointerException in Response when performing redirect to wrong
+   relative URL
+ + JETTY-871 jetty-client expires() NPE race condition fixed
+ + JETTY-876 Added new BlockingArrayQueue and new QueuedThreadPool
+ + JETTY-894 Add android .apk to mime types
+ + JETTY-897 Remove swing dependency in GzipFilter
+ + JETTY-898 Allow jetty debs to start with custom java args provided by users
+ + JETTY-899 Standardize location and build process for configuration files
+   which go into etc
+ + JETTY-890 merge jaspi branch to trunk
+ + JETTY-909 Update useragents cache
+ + JETTY-917 Change for JETTY-811 breaks systemProperties config parameter in
+   maven-jetty-plugin
+ + JETTY-922 Fixed NPE on getRemoteHost when socket closed
+ + JETTY-923 Client supports attributes
+ + JETTY-926 default location for generatedClasses of jspc plugin is incorrect
+ + JETTY-939 NPE in AbstractConfiguration.callPreDestroyCallbacks
+ + JETTY-938 Deadlock in the TerracottaSessionManager
+ + JETTY-946 Redeploys with maven jetty plugin of webapps with overlays don't
+   work
+ + JETTY-950 Fix double-printing of request URI in request log
+ + JETTY-953 SSL keystore file input stream is not being closed directly
+ + JETTY-956 SslSelectChannelConnector - password should be the default value
+   of keyPassword if not specified
+ + moved to org.eclipse packages
+ + simplified HandlerContainer API
+
+jetty-6.1.15 - 04 March 2009
+ + JETTY-931 Fix issue with jetty-rewrite.xml
+ + JETTY-934 fixed stop/start of Bayeux Client
+ + JETTY-938 Deadlock in the TerracottaSessionManager
+ + JETTY-939 NPE in AbstractConfiguration.callPreDestroyCallbacks
+ + JETTY-923 BayeuxClient uses message pools to reduce memory footprint
+ + JETTY-924 Improved BayeuxClient disconnect handling
+ + JETTY-925 Lazy bayeux messages
+ + JETTY-926 default location for generatedClasses of jspc plugin is incorrect
+
+jetty-6.1.15 - 02 March 2009
+ + JETTY-923 BayeuxClient uses message pools to reduce memory footprint
+ + JETTY-924 Improved BayeuxClient disconnect handling
+ + JETTY-925 Lazy bayeux messages
+ + JETTY-926 default location for generatedClasses of jspc plugin is incorrect
+
+jetty-6.1.15.rc4 - 19 February 2009
+ + JETTY-496 Support inetd/xinetd through use of System.inheritedChannel()
+ + JETTY-713 Expose additional AbstractConnector methods via MBean
+ + JETTY-749 Improved ack extension
+ + JETTY-811 Allow configuration of system properties for the maven plugin
+   using a file
+ + JETTY-840 add default mime types to *.htc and *.pps
+ + JETTY-848 Temporary folder not fully cleanup after stop (via Sweeper)
+ + JETTY-872 Handshake handler calls wrong extension callback
+ + JETTY-879 Support extra properties in jQuery comet implementation
+ + JETTY-802 Modify the default error pages to make association with Jetty
+   clearer
+ + JETTY-869 NCSARequestLog locale config
+ + JETTY-870 NullPointerException in Response when performing redirect to wrong
+   relative URL
+ + JETTY-878 Removed printStackTrace from WaitingContinuation
+ + JETTY-882 ChannelBayeuxListener called too many times
+ + JETTY-884 Use hashcode for threadpool ID
+ + JETTY-815 Add comet support to jQuery javascript library
+ + JETTY-887 Split configuration and handshaking in jquery comet
+ + JETTY-888 Fix abort in case of multiple outstanding connections
+ + JETTY-894 Add android .apk to mime types
+ + JETTY-898 Allow jetty debs to start with custom java args provided by users
+ + JETTY-909 Update useragents cache
+
+jetty-6.1.15.rc3 - 28 January 2009
+ + JETTY-691 System.getProperty() calls ... wrap them in doPrivileged
+ + JETTY-844 Replace reflection with direct invocation in Slf4jLog
+ + JETTY-861 switched buffer pools to ThreadLocal implementation
+ + JETTY-866 jetty-client test case fix
+
+jetty-6.1.15.rc2 - 23 January 2009
+ + adjustment to jetty-client assembly packaging
+ + JETTY-567 Delay in initial TLS Handshake With FireFox 3 beta5 and
+   SslSelectChannelConnector
+
+jetty-6.1.15.pre0 - 20 January 2009
+ + JETTY-600 Automated tests of WADI integration + upgrade to WADI 2.0
+ + JETTY-749 Reliable message delivery
+ + JETTY-794 WADI integration tests fail intermittently.
+ + JETTY-781 Add "mvn jetty:deploy-war" for deploying a pre-assembled war
+ + JETTY-795 NullPointerException in SocketConnector.java
+ + JETTY-798 Jboss session manager incompatible with LifeCycle.Listener
+ + JETTY-801 Bring back 2 arg EnvEntry constructor
+ + JETTY-802 Modify the default error pages to make association with Jetty very
+   clear
+ + JETTY-804 HttpClient timeout does not always work
+ + JETTY-806 Timeout related Deadlocks in HTTP Client
+ + JETTY-807 HttpTester to handle charsets
+ + JETTY-808 cometd client demo run.sh
+ + JETTY-809 Need a way to customize WEB-INF/lib file extensions that are added
+   to the classpath
+ + JETTY-814 Add org.eclipse.jetty.client.Address.toString()
+ + JETTY-816 Implement reconnect on java bayeux client
+ + JETTY-817 Aborted SSL connections may cause jetty to hang with full cpu
+ + JETTY-819 Jetty Plus no more jre 1.4
+ + JETTY-821 Allow lazy loading of persistent sessions
+ + JETTY-824 Access to inbound byte statistics
+ + JETTY-825 URL decoding of spaces (+) fails for encoding not utf8
+ + JETTY-827 Externalize servlet api
+ + JETTY-830 Add ability to reserve connections on http client
+ + JETTY-831 Add ability to stop java bayeux client
+ + JETTY-832 More UrlDecoded handling in relation to JETTY-825
+ + JETTY-833 Update debian and rpm packages for new jsp-2.1-glassfish jars and
+   servlet-api jar
+ + JETTY-834 Configure DTD does not allow <Map> children
+ + JETTY-837 Response headers set via filter are ignored for static resources
+ + JETTY-841 Duplicate messages when sending private message to yourself with
+   cometd chat demo
+ + JETTY-842 NPE in jetty client when no path component
+ + JETTY-843 META-INF/MANIFEST.MF is not present in unpacked webapp
+ + JETTY-852 Ensure handshake and connect retried on failure for jquery-cometd
+ + JETTY-854 JNDI scope does not work with applications in a .war
+ + JETTY-855 jetty-client uber assembly support
+ + JETTY-858 ContentExchange provides bytes
+ + JETTY-859 MultiPartFilter ignores the query string parameters
+ + JETTY-862 EncodedHttpURI ignores given encoding in constructor
+
+jetty-6.1.14 - 14 November 2008
+ + JETTY-630 jetty6-plus rpm is missing the jetty6-plus jar
+ + JETTY-748 Reduced flushing of large content
+ + JETTY-765 ensure stop mojo works for all execution phases
+ + JETTY-777 include util5 on the jetty debs
+ + JETTY-778 handle granular windows timer in lifecycle test
+ + JETTY-779 Fixed line feed in request log
+ + JETTY-782 Implement interval advice for BayeuxClient
+ + JETTY-783 Update jetty self-signed certificate
+ + JETTY-784 TerracottaSessionManager leaks sessions scavenged in other nodes
+ + JETTY-787 Handle MSIE7 mixed encoding
+ + JETTY-788 Fix jotm for new scoped jndi
+ + JETTY-790 WaitingContinuations can change mutex if not pending
+ + JETTY-791 Ensure jdk1.4 compatibility for jetty-6
+ + JETTY-792 TerracottaSessionManager does not unlock new session with
+   requested id
+ + JETTY-793 Fixed DataCache millisecond rounding
+
+jetty-6.1.12 - 04 November 2008
+ + JETTY-731 Completed DeliverListener for cometd
+ + JETTY-772 Increased default threadpool size to 250
+ + JETTY-774 Cached text/json content type
+ + JETTY-775 fix port of openspaces to jetty-6
+
+jetty-7.0.0.pre5 - 30 October 2008
+ + JETTY-766 Fix npe
+ + JETTY-767 Fixed SSL Client no progress handshake bug
+ + JETTY-768 Remove EnvEntry overloaded constructors
+ + JETTY-769 jquery example error
+ + JETTY-771 Ensure NamingEntryUtil is jdk1.4 compliant
+ + JETTY-772 Increased default threadpool size to 250
+
+jetty-6.1.12.rc5 - 30 October 2008
+ + JETTY-703 maxStopTimeMs added to QueuedThreadPool
+ + JETTY-762 improved QueuedThreadPool idle death handling
+ + JETTY-763 Fixed AJP13 constructor
+ + JETTY-766 Ensure SystemProperties set early on jetty-maven-plugin
+ + JETTY-767 Fixed SSL Client no progress handshake bug
+ + JETTY-768 Remove EnvEntry overloaded constructors
+ + JETTY-771 Ensure NamingEntryUtil jdk1.4 compliant
+
+jetty-7.0.0.pre4 - 28 October 2008
+ + JETTY-241 Support for web application overlays in rapid application
+   development (jetty:run)
+ + JETTY-319 improved passing of exception when webapp unavailable
+ + JETTY-331 SecureRandom hangs on systems with low entropy (connectors slow to
+   start)
+ + JETTY-591 No server classes for jetty-web.xml
+ + JETTY-604 AbstractSession.setSessionURL
+ + JETTY-670 $JETTY_HOME/bin/jetty.sh not worked in Solaris, because of
+   /usr/bin/which has no error-code
+ + JETTY-676 ResourceHandler doesn't support HTTP HEAD requests
+ + JETTY-677 GWT serialization issue
+ + JETTY-680 Can't configure the ResourceCollection with maven
+ + JETTY-681 JETTY-692 MultiPartFilter is slow for file uploads
+ + JETTY-682 Added listeners and queue methods to cometd
+ + JETTY-686 LifeCycle.Listener
+ + JETTY-687 Issue with servlet-mapping in dynamic servlet invoker
+ + JETTY-688 Cookie causes NumberFormatException
+ + JETTY-689 processing of non-servlet related annotations
+ + JETTY-690 Updated XBean dependencies to XBean version 3.4.3 and Spring
+   2.0.5.
+ + JETTY-696 jetty.sh restart not working
+ + JETTY-698 org.eclipse.resource.JarResource.extract does not close
+   JarInputStream jin
+ + JETTY-699 Optimized cometd sending of 1 message to many many clients
+ + JETTY-700 unit test for unread request data
+ + JETTY-703 maxStopTimeMs added to QueuedThreadPool
+ + JETTY-708 allow 3 scopes for jndi resources: jvm, server or webapp
+ + JETTY-709 Jetty plugin's WebAppConfig configured properties gets overridden
+   by AbstractJettyRunMojo even when already set
+ + JETTY-710 Worked around poor implementation of File.toURL()
+ + JETTY-711 DataSourceUserRealm implementation
+ + JETTY-712 HttpClient does not handle request complete after response
+   complete
+ + JETTY-715 AJP Key size as Integer
+ + JETTY-716 Fixed NPE on empty cometd message
+ + JETTY-718 during ssl unwrap, return true if some bytes were read, even if
+   underflow
+ + JETTY-720 fix HttpExchange.waitForStatus
+ + JETTY-721 Support wildcard in VirtualHosts configuration
+ + JETTY-723 jetty.sh does not check if TMP already is set
+ + JETTY-724 better handle EBCDIC default JVM encoding
+ + JETTY-728 Improve Terracotta integration and performances
+ + JETTY-730 Set SAX parse features to defaults
+ + JETTY-731 DeliverListener for cometd
+ + JETTY-732 Case Sensitive Basic Authentication Response Header
+   Implementations
+ + JETTY-733 Expose ssl connectors with xbean
+ + JETTY-735 Wrong default jndi name on DataSourceUserRealm
+ + JETTY-736 Client Specific cometd advice
+ + JETTY-737 refactored jetty.jar into jetty, xml, security, ssl, webapp and
+   deploy jars
+ + JETTY-738 If jetty.sh finds a pid file is does not check to see if a process
+   with that pid is still running
+ + JETTY-739 Race in QueuedThreadPool
+ + JETTY-741 HttpClient connects slowly due to reverse address lookup by
+   InetAddress.getHostName()
+ + JETTY-742 Private messages in cometd chat demo
+ + JETTY-747 Handle HttpClient exceptions better
+ + JETTY-755 Optimized HttpParser and buffers for few busy connections
+ + JETTY-757 Unhide JAAS classes
+ + JETTY-758 Update JSP to glassfish tag SJSAS-9_1_1-B51-18_Sept_2008
+ + JETTY-759 Fixed JSON small negative real numbers
+ + JETTY-760 Handle wildcard VirtualHost and normalize hostname in
+   ContextHandlerCollection
+ + JETTY-762 improved QueuedThreadPool idle death handling
+ + JETTY-763 Fixed AJP13 constructor
+ + JETTY-766 Ensure SystemProperties set early on jetty-maven-plugin
+
+jetty-6.1.12.rc4 - 21 October 2008
+ + JETTY-319 improved passing of exception when webapp unavailable
+ + JETTY-729 Backport Terracotta integration to Jetty6.1 branch
+ + JETTY-744 Backport of JETTY-741: HttpClient connects slowly due to reverse
+   address lookup by InetAddress.getHostName()
+ + JETTY-747 Handle exceptions better in HttpClient
+ + JETTY-755 Optimized HttpParser and buffers for few busy connections
+ + JETTY-758 Update JSP 2.1 to glassfish tag SJSAS-9_1_1-B51-18_Sept_2008
+ + JETTY-759 Fixed JSON small negative real numbers
+ + JETTY-760 Handle wildcard VirtualHost and normalize hostname in
+   ContextHandlerCollection
+
+jetty-6.1.12.rc3 - 10 October 2008
+ + JETTY-241 Support for web application overlays in rapid application
+   development (jetty:run)
+ + JETTY-686 LifeCycle.Listener
+ + JETTY-715 AJP key size
+ + JETTY-716 NPE for empty cometd message
+ + JETTY-718 during ssl unwrap, return true if some bytes were read, even if
+   underflow
+ + JETTY-720 fix HttpExchange.waitForStatus
+ + JETTY-721 Support wildcard in VirtualHosts configuration
+ + JETTY-722 jndi related threadlocal not cleared after deploying webapp
+ + JETTY-723 jetty.sh does not check if TMP already is set
+ + JETTY-725 port JETTY-708 (jndi scoping) to jetty-6
+ + JETTY-730 set SAX parser features to defaults
+ + JETTY-731 DeliverListener for cometd
+ + JETTY-732 Case Sensitive Basic Authentication Response Header
+   Implementations
+ + JETTY-736 Client Specific cometd advice
+ + JETTY-738 If jetty.sh finds a pid file is does not check to see if a process
+   with that pid is still running
+ + JETTY-739 Race in QueuedThreadPool
+ + JETTY-742 Private messages in cometd chat demo
+
+jetty-6.1.12rc2 - 12 September 2008
+ + JETTY-282 Support manually-triggered reloading
+ + JETTY-331 SecureRandom hangs on systems with low entropy (connectors slow to
+   startup)
+ + JETTY-591 No server classes for jetty-web.xml
+ + JETTY-670 $JETTY_HOME/bin/jetty.sh not worked in Solaris, because of
+   /usr/bin/which has no error-code
+ + JETTY-671 Configure DTD does not allow <Property> children
+ + JETTY-672 Utf8StringBuffer doesn't properly handle null characters (char
+   with byte value 0)
+ + JETTY-676 ResourceHandler doesn't support HTTP HEAD requests
+ + JETTY-677 GWT serialization issue
+ + JETTY-680 Can't configure the ResourceCollection with maven
+ + JETTY-681 JETTY-692 MultiPartFilter is slow for file uploads
+ + JETTY-682 Added listeners and queue methods to cometd
+ + JETTY-683 ResourceCollection works for jsp files but does not work for
+   static resources under DefaultServlet
+ + JETTY-687 Issue with servlet-mapping in dynamic servlet invoker
+ + JETTY-688 Cookie causes NumberFormatException
+ + JETTY-696 ./jetty.sh restart not working
+ + JETTY-698 org.eclipse.resource.JarResource.extract does not close
+   JarInputStream jin
+ + JETTY-699 Optimize cometd sending of 1 message to many many clients
+ + JETTY-709 Jetty plugin's WebAppConfig configured properties gets overridden
+   by AbstractJettyRunMojo even when already set
+ + JETTY-710 Worked around poor implementation of File.toURL()
+ + JETTY-712 HttpClient does not handle request complete after response
+   complete
+
+jetty-7.0.0pre3 - 06 August 2008
+ + Upgrade jsp 2.1 to SJSAS-9_1_02-B04-11_Apr_2008
+ + JETTY-30 Externalize servlet-api to own project
+ + JETTY-182 Support setting explicit system classpath for jasper
+   Jsr199JavaCompiler
+ + JETTY-319 Get unavailable exception and added startWithUnavailable option
+ + JETTY-381 JETTY-622 Multiple Web Application Source Directory
+ + JETTY-442 Accessors for mimeType on ResourceHandler
+ + JETTY-502 forward of an include should hide include attributes
+ + JETTY-562 RewriteHandler support for virtual hosts
+ + JETTY-563 JETTY-482 OpenRemoteServiceServlet for GWT1.5M2+
+ + JETTY-564 Consider optionally importing org.apache.jasper.servlet
+ + JETTY-571 SelectChannelConnector throws Exception on close on Windows
+ + JETTY-608 Suspend/Resume/Complete request listeners
+ + JETTY-621 Improved LazyList javadoc
+ + JETTY-626 Null protect reading the dtd resource from classloader
+ + JETTY-628 Rewrite rule for rewriting scheme
+ + JETTY-629 Don't hold timeout lock during expiry call.
+ + JETTY-632 OSGi tags for Jetty client
+ + JETTY-633 Default form encoding 8859_1 rather than utf-8
+ + JETTY-635 Correctly merge request parameters when doing forward
+ + JETTY-636 Separate lifeycle of jsp build
+ + JETTY-637 empty date headers throw IllegalArgumentException
+ + JETTY-641 JDBC Realm purge cache problem
+ + JETTY-642 NPE in LdapLoginModule
+ + JETTY-644 LdapLoginModule uses proper filters when searching
+ + JETTY-645 Do not provide jetty-util to the webapps
+ + JETTY-646 Should set Cache-Control header when sending errors to avoid
+   caching
+ + JETTY-647 suspended POSTs with binary data do too many resumes
+ + JETTY-650 Parse "*" URI for HTTP OPTIONS request
+ + JETTY-651 Release resources during destroy
+ + JETTY-653 Upgrade jta api specs to more recent version
+ + JETTY-654 Allow Cometd Bayeux object to be JMX manageable
+ + JETTY-655 Support parsing application/x-www-form-urlencoded parameters via
+   http PUT
+ + JETTY-656 HttpClient defaults to async mode
+ + JETTY-659 ContentExchange and missing headers in HttpClient
+ + JETTY-663 AbstractDatabaseLoginModule handle not found UserInfo and userName
+ + JETTY-665 Support merging class directories
+ + JETTY-666 scanTargetPatterns override the values already being set by
+   scanTarget
+ + JETTY-667 HttpClient handles chunked content
+ + JETTY-669 Http methods other than GET and POST should not have error page
+   content
+ + JETTY-671 Configure DTD does not allow <Property> children
+ + JETTY-672 Utf8StringBuffer doesn't properly handle null characters (char
+   with byte value 0)
+ + JETTY-675 ServletContext.getRealPath("") returns null instead of returning
+   the root dir of the webapp
+
+jetty-6.1.12rc1 - 01 August 2008
+ + Upgrade jsp 2.1 to SJSAS-9_1_02-B04-11_Apr_2008
+ + JETTY-319 Get unavailable exception and added startWithUnavailable option
+ + JETTY-381 JETTY-622 Multiple Web Application Source Directory
+ + JETTY-442 Accessors for mimeType on ResourceHandler
+ + JETTY-502 forward of an include should hide include attributes
+ + JETTY-562 RewriteHandler support for virtual hosts
+ + JETTY-563 GWT OpenRemoteServiceServlet GWT1.5M2+
+ + JETTY-564 Consider optionally importing org.apache.jasper.servlet
+ + JETTY-571 SelectChannelConnector throws Exception on close on Windows
+ + JETTY-596 Proxy authorization support in HttpClient
+ + JETTY-599 handle buffers consistently handle invalid index for poke
+ + JETTY-603 Handle IPv6 in HttpURI
+ + JETTY-605 Added optional threadpool to BayeuxService
+ + JETTY-606 better writeTo impl for BIO
+ + JETTY-607 Add GigaSpaces session clustering
+ + JETTY-610 jetty.class.path not being interpreted
+ + JETTY-613 website module now generates site-component for jetty-site
+ + JETTY-614 scanner allocated hashmap on every scan
+ + JETTY-623 ServletContext.getServerInfo() non compliant
+ + JETTY-626 Null protect reading the dtd resource from classloader
+ + JETTY-628 Rewrite rule for rewriting scheme
+ + JETTY-629 Don't hold timeout lock during expiry call.
+ + JETTY-632 OSGi tags for Jetty client
+ + JETTY-633 Default form encoding 8859_1 rather than utf-8
+ + JETTY-635 Correctly merge request parameters when doing forward
+ + JETTY-637 empty date headers throw IllegalArgumentException
+ + JETTY-641 JDBC Realm purge cache problem
+ + JETTY-642 NPE in LdapLoginModule
+ + JETTY-644 LdapLoginModule uses proper filters when searching
+ + JETTY-646 Should set Cache-Control header when sending errors to avoid
+   caching
+ + JETTY-647 suspended POSTs with binary data do too many resumes
+ + JETTY-650 Parse "*" URI for HTTP OPTIONS request
+ + JETTY-651 Release resources during destroy
+ + JETTY-654 Allow Cometd Bayeux object to be JMX manageable
+ + JETTY-655 Support parsing application/x-www-form-urlencoded parameters via
+   http PUT
+ + JETTY-656 HttpClient defaults to async mode
+ + JETTY-657 Backport jetty-7 sslengine
+ + JETTY-658 backport latest HttpClient from jetty-7 to jetty-6
+ + JETTY-659 ContentExchange and missing headers in HttpClient
+ + JETTY-660 Backported QoSFilter
+ + JETTY-663 AbstractDatabaseLoginModule handle not found UserInfo and userName
+ + JETTY-665 Support merging class directories
+ + JETTY-666 scanTargetPatterns override the values already being set by
+   scanTarget
+ + JETTY-667 HttpClient handles chunked content
+ + JETTY-669 Http methods other than GET and POST should not have error page
+   content
+
+jetty-7.0.0pre2 - 30 June 2008
+ + JETTY-336 413 error for header buffer full
+ + JETTY-425 race in stopping SelectManager
+ + JETTY-568 Avoid freeing DirectBuffers. New locking NIO ResourceCache.
+ + JETTY-569 Stats for suspending requests
+ + JETTY-576 servlet dtds and xsds not being loaded locally
+ + JETTY-572 Unique cometd client ID
+ + JETTY-578 OSGI Bundle-RequiredExcutionEnvironment set to J2SE-1.5
+ + JETTY-579 OSGI resolved management and servlet.resources import error
+ + JETTY-580 Fixed SSL shutdown
+ + JETTY-581 ContextPath constructor
+ + JETTY-582 final ISO_8859_1
+ + JETTY-584 handle null contextPath
+ + JETTY-587 persist sessions to database
+ + JETTY-588 handle Retry in ServletException
+ + JETTY-589 Added Statistics Servlet
+ + JETTY-590 Digest auth domain for root context
+ + JETTY-592 expired timeout callback without synchronization
+ + JETTY-595 SessionHandler only deals with base request session
+ + JETTY-596 proxy support in HttpClient
+ + JETTY-598 Added more reliable cometd message flush option
+ + JETTY-599 handle buffers consistently handle invalid index for poke
+ + JETTY-603 Handle IPv6 in HttpURI
+ + JETTY-605 Added optional threadpool to BayeuxService
+ + JETTY-606 better writeTo impl for BIO
+ + JETTY-607 Add GigaSpaces session clustering
+ + JETTY-609 jetty-client improvements for http conversations
+ + JETTY-610 jetty.class.path not being interpreted
+ + JETTY-611 make general purpose jar scanning mechanism
+ + JETTY-612 scan for web.xml fragments
+ + JETTY-613 various distribution related changes
+ + JETTY-614 scanner allocates hashmap on every iteration
+ + JETTY-615 Replaced CDDL servlet.jar with Apache-2.0 licensed version
+ + JETTY-623 ServletContext.getServerInfo() non compliant
+
+jetty-6.1.11 - 06 June 2008
+ + JETTY-336 413 error for full header buffer
+ + JETTY-425 race in stopping SelectManager
+ + JETTY-580 Fixed SSL shutdown
+ + JETTY-581 ContextPath constructor
+ + JETTY-582 final ISO_8859_1
+ + JETTY-584 handle null contextPath
+ + JETTY-588 handle Retry in ServletException
+ + JETTY-590 Digest auth domain for root context
+ + JETTY-592 expired timeout callback without synchronization
+ + JETTY-595 SessionHandler only deals with base request session
+ + JETTY-596 Proxy support in HttpClient
+ + JETTY-598 Added more reliable cometd message flush option
+
+jetty-6.1.10 - 20 May 2008
+ + Use QueuedThreadPool as default
+ + JETTY-440 allow file name patterns for jsp compilation for jspc plugin
+ + JETTY-529 CNFE when deserializing Array from session resolved
+ + JETTY-537 JSON handles Locales
+ + JETTY-547 Shutdown SocketEndpoint output before close
+ + JETTY-550 Reading 0 bytes corrupts ServletInputStream
+ + JETTY-551 Upgraded to Wadi 2.0-M10
+ + JETTY-556 Encode all URI fragments
+ + JETTY-557 Allow ServletContext.setAttribute before start
+ + JETTY-558 optional handling of X-Forwarded-For/Host/Server
+ + JETTY-566 allow for non-blocking behavior in jetty maven plugin
+ + JETTY-572 unique cometd client ID
+ + JETTY-579 osgi fixes with management and servlet resources
+
+jetty-7.0.0pre1 - 03 May 2008
+ + Allow annotations example to be built regularly, copy to contexts-available
+ + Make annotations example consistent with servlet 3.0
+ + Refactor JNDI impl to simplify
+ + Improved suspend examples
+ + address osgi bundling issue relating to build resources
+ + JETTY-529 CNFE when deserializing Array from session resolved
+ + JETTY-558 optional handling of X-Forwarded-For/Host/Server
+ + JETTY-559 ignore unsupported shutdownOutput
+ + JETTY-566 allow for non-blocking behavior in jetty maven plugin
+ + JETTY-440 allow file name patterns for jsp compilation for jspc plugin
+
+jetty-7.0.0pre0 - 21 April 2008
+ + Jetty-6.1.8 Changes
+ + Refactor of Continuation towards servlet 3.0 proposal
+ + JETTY-282 Support manually-triggered reloading by maven plugin
+ + QueuedThreadPool default
+ + RetryRequest exception now extends ThreadDeath
+ + Added option to dispatch to suspended requests.
+ + Delay 100 continues until getInputStream
+ + HttpClient supports pipelined request
+ + BayeuxClient use a single connection for polling
+ + Make javax.servlet.jsp optional osgi import for jetty module
+ + Ensure Jotm tx mgr can be found in jetty-env.xml
+ + Renamed modules management and naming to jmx and jndi.
+ + JETTY-341 100-Continues sent only after getInputStream called.
+ + JETTY-386 backout fix and replaced with
+   ContextHandler.setCompactPath(boolean)
+ + JETTY-399 update OpenRemoteServiceServlet to gwt 1.4
+ + JETTY-467 allow URL rewriting to be disabled.
+ + JETTY-468 unique holder names for addServletWithMapping
+ + JETTY-471 LDAP JAAS Realm
+ + JETTY-474 Fixed case sensitivity issue with HttpFields
+ + JETTY-475 AJP connector in RPMs
+ + JETTY-486 Improved jetty.sh script
+ + JETTY-487 Handle empty chunked request
+ + JETTY-494 Client side session replication
+ + JETTY-519 HttpClient does not recycle closed connection.
+ + JETTY-522 Add build profile for macos for setuid
+ + JETTY-523 Default servlet uses ServletContext.getResource
+ + JETTY-524 Don't synchronize session event listener calls
+ + JETTY-525 Fixed decoding for long strings
+ + JETTY-526 Fixed MMBean fields on JMX MBeans
+ + JETTY-528 Factor our cookie parsing to CookieCutter
+ + JETTY-530 Improved JMX MBeanContainer lifecycle
+ + JETTY-531 Optional expires on MovedContextHandler
+ + JETTY-532 MBean properties for QueuedThreadPool
+ + JETTY-535 Fixed Bayeux server side client memory leak
+ + JETTY-537 JSON handles Locales
+ + JETTY-538 test harness fix for windows
+ + JETTY-540 Servlet-3.0 & java5 support (work in progress)
+ + JETTY-543 Atomic batch get and put of files.
+ + JETTY-545 Rewrite handler
+ + JETTY-546 Webapp runner. All in one jar to run a webapps
+ + JETTY-547 Shutdown SocketEndpoint output before close
+ + JETTY-550 Reading 0 bytes corrupts ServletInputStream
+ + JETTY-551 Wadi 2.0-M10
+ + JETTY-553 Fixed customize override
+ + JETTY-556 Encode all URI fragments
+ + JETTY-557 Allow ServletContext.setAttribute before start
+ + JETTY-560 Allow decoupling of jndi names in web.xml
+
+jetty-6.1.9 - 26 March 2008
+ + Make javax.servlet.jsp optional osgi import for jetty module
+ + Ensure Jotm tx mgr can be found in jetty-env.xml
+ + JETTY-399 update OpenRemoteServiceServlet to gwt 1.4
+ + JETTY-471 LDAP JAAS Realm
+ + JETTY-475 AJP connector in RPMs
+ + JETTY-482 update to JETTY-399
+ + JETTY-519 HttpClient does not recycle closed connection.
+ + JETTY-522 Add build profile for macos for setuid
+ + JETTY-525 Fixed decoding for long strings
+ + JETTY-526 Fixed MMBean fields on JMX MBeans
+ + JETTY-532 MBean properties for QueuedThreadPool
+ + JETTY-535 Fixed Bayeux server side client memory leak
+ + JETTY-538 test harness fix for windows
+ + JETTY-541 Cometd per client timeouts
+
+jetty-6.1.8 - 28 February 2008
+ + Added QueuedThreadPool
+ + Optimized QuotedStringTokenizer.quote()
+ + further Optimizations and improvements of Cometd
+ + Optimizations and improvements of Cometd, more pooled objects
+ + Improved Cometd timeout handling
+ + Added BayeuxService
+ + Cookie support in BayeuxClient
+ + Improved Bayeux API
+ + add removeHandler(Handler) method to HandlerContainer interface
+ + Added JSON.Convertor and non static JSON instances
+ + Long cache for JSON
+ + Fixed JSON negative numbers
+ + JSON unquotes /
+ + Add "mvn jetty:stop"
+ + allow sessions to be periodically persisted to disk
+ + grizzly fixed for posts
+ + Remove duplicate commons-logging jars and include sslengine in jboss sar
+ + Allow code ranges on ErrorPageErrorHandler
+ + AJP handles bad mod_jk methods
+ + JETTY-350 log ssl errors on SslSocketConnector
+ + JETTY-417 JETTY_LOGS environment variable not queried by jetty.sh
+ + JETTY-433 ContextDeployer constructor fails unnecessarily when using a
+   security manager if jetty.home not set
+ + JETTY-434 ContextDeployer scanning of sub-directories should be optional
+ + JETTY-481 Handle empty Bayeux response
+ + JETTY-489 Improve doco on the jetty.port property for plugin
+ + JETTY-490 Fixed JSONEnumConvertor
+ + JETTY-491 opendocument mime types
+ + JETTY-492 Null pointer in HashSSORealm
+ + JETTY-493 JSON handles BigDecimals
+ + JETTY-498 Improved cookie parsing
+ + JETTY-507 Fixed encoding from JETTY-388 and test case
+ + JETTY-508 Extensible cometd handlers
+ + JETTY-509 Fixed JSONP transport for changing callback names
+ + JETTY-511 jetty.sh mishandled JETTY_HOME when launched from a relative path
+ + JETTY-512 add slf4j as optional to manifest
+ + JETTY-513 Terracotta session replication does not work when the initial page
+   on each server does not set any attributes
+ + JETTY-515 Timer is missing scavenging Task in HashSessionManager
+
+jetty-6.1.7 - 22 December 2007
+ + Added BayeuxService
+ + Added JSON.Convertor and non static JSON instances
+ + Add "mvn jetty:stop"
+ + allow sessions to be periodically persisted to disk
+ + Cookie support in BayeuxClient
+ + grizzly fixed for posts
+ + jetty-6.1 branch created from 6.1.6 and r593 of jetty-contrib trunk
+ + Optimizations and improvements of Cometd, more pooled objects
+ + Update java5 patch
+ + JETTY-386 CERT-553235 backout fix and replaced with
+   ContextHandler.setCompactPath(boolean)
+ + JETTY-467 allow URL rewriting to be disabled.
+ + JETTY-468 unique holder names for addServletWithMapping
+ + JETTY-474 Fixed case sensitivity issue with HttpFields
+ + JETTY-486 Improved jetty.sh script
+ + JETTY-487 Handle empty chunked request
+
+jetty-6.1.6 - 18 November 2007
+ + rudimentary debian packaging
+ + updated grizzly connector to 1.6.1
+ + JETTY-455 Optional cometd id
+ + JETTY-459 Unable to deploy from Eclipse into the root context
+ + JETTY-461 fixed cometd unknown channel
+ + JETTY-464 typo in ErrorHandler
+ + JETTY-465 System.exit() in constructor exception for MultiPartOutputStream
+
+jetty-6.1.6rc1 - 05 November 2007
+ + Upgrade jsp 2.1 to SJSAS-9_1-B58G-FCS-08_Sept_2007
+ + Housekeeping on poms
+ + CERT VU#38616 handle single quotes in cookie names.
+ + Improved JSON parsing from Readers
+ + Moved some impl classes from jsp-api-2.1 to jsp-2.1
+ + Added configuration file for capturing stderr and stdout
+ + Updated for dojo 1.0(rc) cometd
+ + Give bayeux timer name
+ + Give Terracotta session scavenger a name
+ + Jetty Eclipse Plugin 1.0.1: force copy of context file on redeploy
+ + JETTY-388 Handle utf-16 and other multibyte non-utf-8 form content.
+ + JETTY-409 String params that denote files changed to File
+ + JETTY-438 handle trailing . in vhosts
+ + JETTY-439 Fixed 100 continues clash with Connection:close
+ + JETTY-451 Concurrent modification of session during invalidate
+ + JETTY-443 windows bug causes Acceptor thread to die
+ + JETTY-445 removed test code
+ + JETTY-448 added setReuseAddress on AbstractConnector
+ + JETTY-450 Bad request for response sent to server
+ + JETTY-452 CERT VU#237888 Dump Servlet - prevent cross site scripting
+ + JETTY-453 updated Wadi to 2.0-M7
+ + JETTY-454 handle exceptions with themselves as root cause
+ + JETTY-456 allow null keystore for osX
+ + JETTY-457 AJP certificate chains
+
+jetty-6.1.6rc0 - 03 October 2007
+ + Added jetty.lib system property to start.config
+ + AJP13 Fix on chunked post
+ + Fix cached header optimization for extra characters
+ + SetUID option to support setgid
+ + Make mx4j used only if runtime uses jdk<1.5
+ + Moved Grizzly to contrib
+ + Give deployment file Scanner threads a unique name
+ + Fix Host header for async client
+ + Fix typo in async client onResponsetHeader method name
+ + Tweak OSGi manifests to remove unneeded imports
+ + Allow scan interval to be set after Scanner started
+ + Add jetty.host system property
+ + Allow properties files on the XmlConfiguration command line.
+ + Prevent infinite loop on stopping with temp dir
+ + Ensure session is completed only when leaving context.
+ + Update terracotta to 2.4.1 and exclude ssl classes
+ + Update jasper2.1 to tag SJSAS-9_1-B58C-FCS-22_Aug_2007
+ + Removal of unneeded dependencies from management, maven-plugin, naming &
+   plus poms
+ + Adding setUsername,setGroupname to setuid and mavenizing native build
+ + UTF-8 for bayeux client
+ + CVE-2007-5615 Added protection for response splitting with bad headers.
+ + Cached user agents strings in the /org/mortbay/jetty/useragents resource
+ + Make default time format for RequestLog match NCSA default
+ + Use terracotta repo for build; make jetty a terracotta module
+ + Fix patch for java5 to include cometd module
+ + Added ConcatServlet to combine javascript and css
+ + Add ability to persist sessions with HashSessionManager
+ + Avoid FULL exception in window between blockForOutput and remote close
+ + Added JPackage RPM support
+ + Added JSON.Convertable
+ + Updated README, test index.html file and jetty-plus.xml file
+ + JETTY-259 SystemRoot set for windows CGI
+ + JETTY-311 avoid json keywords
+ + JETTY-376 allow anything but CRLF in reason string
+ + JETTY-398 Allow same WADI Dispatcher to be used across multiple web-app
+   contexts
+ + JETTY-400 consume CGI stderr
+ + JETTY-402 keep HashUserRealm in sync with file
+ + JETTY-403 Allow long content length for range requests
+ + JETTY-404 WebAppDeployer sometimes deploys duplicate webapp
+ + JETTY-405 Default date formate for reqest log
+ + JETTY-407 AJP handles unknown content length
+ + JETTY-413 Make rolloveroutputstream timer daemon
+ + JETTY-422 Allow <Property> values to be null in config files
+ + JETTY-423 Ensure javax.servlet.forward parameters are latched on first
+   forward
+ + JETTY-425 Handle duplicate stop calls better
+ + JETTY-430 improved cometd logging
+ + JETTY-431 HttpClient soTimeout
+
+jetty-6.1.5 - 19 July 2007
+ + Upgrade to Jasper 2.1 tag SJSAS-9_1-B50G-BETA3-27_June_2007
+ + Fixed GzipFilter for dispatchers
+ + Fixed reset of reason
+ + JETTY-392 updated LikeJettyXml example
+
+jetty-6.1.5rc0 - 15 July 0200
+ + update terracotta session clustering to terracotta 2.4
+ + SetUID option to only open connectors before setUID.
+ + Protect SslSelectChannelConnector from exceptions during close
+ + Improved Request log configuration options
+ + Added GzipFilter and UserAgentFilter
+ + make OSGi manifests for jetty jars
+ + update terracotta configs for tc 2.4 stable1
+ + remove call to open connectors in jetty.xml
+ + update links on website
+ + make jetty plus example webapps use ContextDeployer
+ + Dispatch SslEngine expiry (non atomic)
+ + Make SLF4JLog impl public, add mbean descriptors
+ + SPR-3682 - dont hide forward attr in include.
+ + Upgrade to Jasper 2.1 tag SJSAS-9_1-B50G-BETA3-27_June_2007
+ + JETTY-253 Improved graceful shutdown
+ + JETTY-373 Stop all dependent lifecycles
+ + JETTY-374 HttpTesters handles large requests/responses
+ + JETTY-375 IllegalStateException when committed.
+ + JETTY-376 allow spaces in reason string
+ + JETTY-377 allow sessions to be wrapped with
+   AbstractSesssionManager.SessionIf
+ + JETTY-378 handle JVMs with non ISO/UTF default encodings
+ + JETTY-380 handle pipelines of more than 4 requests!
+ + JETTY-385 EncodeURL for new sessions from dispatch
+ + JETTY-386 Allow // in file resources
+
+jetty-6.1.4 - 15 June 2007
+ + fixed early open() call in NIO connectors
+ + JETTY-370 ensure maxIdleTime<=0 means connections never expire
+ + JETTY-371 Fixed chunked HEAD response
+ + JETTY-372 make test for cookie caching more rigorous
+
+jetty-6.1.4rc1 - 10 June 2007
+ + Work around IBM JVM socket close issue
+ + moved documentation for jetty and jspc maven plugins to wiki
+ + async client improvements
+ + fixed handling of large streamed files
+ + Fixed synchronization conflict SslSelectChannel and SelectChannel
+ + Optional static content cache
+ + JETTY-310 better exception when no filter file for cometd servlet
+ + JETTY-323 handle htaccess without a user realm
+ + JETTY-346 add wildcard support to extra scan targets for maven plugin
+ + JETTY-355 extensible SslSelectChannelConnector
+ + JETTY-357 cleaned up ssl buffering
+ + JETTY-360 allow connectors, userRealms to be added from a <jettyConfig> for
+   maven plugin
+ + JETTY-361 prevent url encoding of dir listings for non-link text
+ + JETTY-362 More object locks
+ + JETTY-365 make needClientAuth work on SslSelectChannelConnector
+ + JETTY-366 JETTY-368 Improved bayeux disconnect
+
+jetty-6.1.4rc0 - 01 June 2007
+ + Reorganized import of contrib modules
+ + Unified JMX configuration
+ + Updated slf4j version to 1.3.1
+ + Updated junit to 3.8.2
+ + Allow XmlConfiguration properties to be configured
+ + Add (commented out) jspc precompile to test-webapp
+ + Add slf4j-api for upgraded version
+ + Change scope of fields for Session
+ + Add ability to run cometd webapps to maven plugin
+ + Delay ssl handshake until after dispatch in sslSocketConnector
+ + Set so_timeout during ssl handshake as an option on SslSocketConnector
+ + Optional send Date header. Server.setSendDateHeader(boolean)
+ + update etc/jetty-ssl.xml with new handshake timeout setting
+ + fixed JSP close handling
+ + improved date header handling
+ + fixed waiting continuation reset
+ + JETTY-257 fixed comet cross domain
+ + JETTY-309 fix applied to sslEngine
+ + JETTY-317 rollback inclusion of cometd jar for maven plugin
+ + JETTY-318 Prevent meta channels being created
+ + JETTY-330 Allow dependencies with scope provided for jspc plugin
+ + JETTY-335 SslEngine overflow fix
+ + JETTY-337 deprecated get/setCipherSuites and added
+   get/setExcludeCipherSuites
+ + JETTY-338 protect isMoreInBuffer from destroy
+ + JETTY-339 MultiPartFiler deletes temp files on IOException
+ + JETTY-340 FormAuthentication works with null response
+ + JETTY-344 gready fill in ByteArrayBuffer.readFrom
+ + JETTY-345 fixed lost content with blocked NIO.
+ + JETTY-347 Fixed type util init
+ + JETTY-352 Object locks
+
+jetty-6.1.3 - 04 May 2007
+ + Handle CRLF for content in header optimization
+ + JETTY-309 don't clear writable status until dispatch
+ + JETTY-315 suppressed warning
+ + JETTY-322 AJP13 cping and keep alive
+
+jetty-6.1.2 - 01 May 2007
+ + Improved unavailabile handling
+ + sendError resets output state
+ + Fixed session invalidation error in WadiSessionManager
+ + Updated Wadi to version 2.0-M3
+ + Added static member definition in WadiSessionManager
+ + JETTY-322 fix ajp cpong response and close handling
+ + JETTY-324 fix ant plugin
+ + JETTY-328 updated jboss
+
+jetty-6.1.2rc5 - 24 April 2007
+ + set default keystore for SslSocketConnector
+ + removed some compile warnings
+ + Allow jsp-file to be / or /*
+ + JETTY-305 delayed connection destroy
+ + JETTY-309 handle close in multivalue connection fields.
+ + JETTY-314 fix for possible NPE in Request.isRequestedSessionIdValid
+
+jetty-6.1.2rc4 - 19 April 2007
+ + JETTY-294 Fixed authentication reset
+ + JETTY-299 handle win32 paths for object naming
+ + JETTY-300 removed synchronized on dispatch
+ + JETTY-302 correctly parse quoted content encodings
+ + JETTY-303 fixed dual reset of generator
+ + JETTY-304 Fixed authentication reset
+
+jetty-6.1.2rc3 - 16 April 2007
+ + Improved performance and exclusions for TLD scanning
+ + MBean properties assume writeable unless marked RO
+ + refactor of SessionManager and SessionIdManager for clustering
+ + Improvements to allow simple setting of Cache-Control headers
+ + AJP redirects https requests correctly
+ + Fixed writes of unencoded char arrays.
+ + JETTY-283 Parse 206 and 304 responses in client
+ + JETTY-285 enable jndi for mvn jetty:run-war and jetty:run-exploded
+ + JETTY-289 fixed javax.net.ssl.SSLException on binary file upload
+ + JETTY-292 Fixed error page handler error pages
+ + JETTY-293 fixed NPE on fast init
+ + JETTY-294 Response.reset() resets headers as well as content
+ + JETTY-295 Optional support of authenticated welcome files
+ + JETTY-296 Close direct content inputstreams
+ + JETTY-297 Recreate tmp dir on stop/start
+ + JETTY-298 Names in JMX ObjectNames for context, servlets and filters
+
+jetty-6.1.2rc2 - 27 March 2007
+ + Enable the SharedStoreContextualiser for the WadiSessionManager(Database
+   store for clustering)
+ + AJP13 CPING request and CPONG response implemented
+ + AJP13 Shutdown Request from peer implemented
+ + AJP13 remoteUser, contextPath, servletPath requests implemented
+ + Change some JNDI logging to debug level instead of info
+ + Update jasper to glassfish tag SJSAS-9_1-B39-RC-14_Mar_2007
+ + Optimized multi threaded init on startup servlets
+ + Removed unneeded specialized TagLibConfiguration class from maven plugin
+ + Refactor Scanner to increase code reuse with maven/ant plugins
+ + Added RestFilter for PUT and DELETE from Aleksi Kallio
+ + Make annotations work for maven plugin
+ + JETTY-125 maven plugin: ensure test dependencies on classpath for
+   <useTestClasspath>
+ + JETTY-246 path encode cookies rather than quote
+ + JETTY-254 prevent close of jar entry by bad JVMs
+ + JETTY-256 fixed isResumed and work around JVM bug
+ + JETTY-258 duplicate log message in ServletHandler
+ + JETTY-260 Close connector before stop
+ + JETTY-262 Allow acceptor thread priority to be adjusted
+ + JETTY-263 Added implementation for authorizationType Packets
+ + JETTY-265 Only quote cookie values if needed
+ + JETTY-266 Fix deadlock with shutdown
+ + JETTY-271 ResourceHandler uses resource for MimeType mapping
+ + JETTY-272 Activate and Passivate events for sessions
+ + JETTY-274 Improve flushing at end of request for blocking
+ + JETTY-276 Partial fix for reset/close race
+ + JETTY-277 Improved ContextHandlerCollection
+ + JETTY-278 Session invalidation delay until no requests
+ + JETTY-280 Fixed deadlock with two flushing threads
+ + JETTY-284 Fixed stop connector race
+ + JETTY-286 isIntegral and isConfidential methods overridden in
+   SslSelectChannelConnector
+
+jetty-6.1.2rc1 - 08 March 2007
+ + TagLibConfiguration uses resource input stream
+ + Improved handling of early close in AJP
+ + add ajp connector jar to jetty-jboss sar
+ + Improved Context setters for wadi support
+ + fix Dump servlet to handle primitive array types
+ + handle comma separated values for the Connection: header
+ + Added option to allow null pathInfo within context
+ + BoundedThreadPool queues rather than blocks excess jobs.
+ + Support null pathInfo option for webservices deployed to jetty/jboss
+ + Workaround to call SecurityAssocation.clear() for jboss webservices calls to
+   ejbs
+ + Ensure jetty/jboss uses servlet-spec classloading order
+ + call preDestroy() after servlet/filter destroy()
+ + Fix constructor for Constraint to detect wildcard role
+ + Added support for lowResourcesIdleTime to SelectChannelConnector
+ + JETTY-157 make CGI handle binary data
+ + JETTY-175 JDBCUserRealm use getInt instead of getObject
+ + JETTY-188 Use timer for session scavaging
+ + JETTY-235 default realm name
+ + JETTY-242 fix race condition with scavenging sessions when stopping
+ + JETTY-243 FULL
+ + JETTY-244 Fixed UTF-8 buffer overflow
+ + JETTY-245 Client API improvements
+ + JETTY-246 spaces in cookies
+ + JETTY-248 setContentLength after content written
+ + JETTY-250 protect attribute enumerations from modification
+ + JETTY-252 Fixed stats handling of close connection
+ + JETTY-254 prevent close of jar file by bad JVMs
+
+jetty-6.1.2rc0 - 15 February 2007
+ + JETTY-223 Fix disassociate of UserPrincipal on dispatches
+ + JETTY-226 Fixed SSLEngine close issue
+ + JETTY-232 Fixed use of override web.xml
+ + JETTY-236 Buffer leak
+ + JETTY-237 AJPParser Buffer Data Handling
+ + JETTY-238 prevent form truncation
+ + Patches from sybase for ClientCertAuthenticator
+ + Coma separated cookies
+ + Cometd timeout clients
+
+jetty-6.1.2pre1 - 05 February 2007
+ + JETTY-224 run build up to process-test before invoking jetty:run
+ + Added error handling for incorrect keystore/truststore password in
+   SslSelectChannelConnector
+ + fixed bug with virtual host handling in ContextHandlerCollection
+ + added win32service to standard build
+ + refactored cometd to be continuation independent
+ + allow ResourceHandler to use resource base from an enclosing ContextHandler
+
+jetty-6.1.2pre0 - 01 February 2007
+ + Fixed 1.4 method in jetty plus
+ + Fixed generation of errors during jsp compilation for jsp-2.1
+ + Added cometd jsonp transport from aabeling
+ + Added terracotta cluster support for cometd
+ + JETTY-213 request.isUserInRole(String) fixed
+ + JETTY-215 exclude more transitive dependencies from tomcat jars for jsp-2.0
+ + JETTY-216 handle AJP packet fragmentation
+ + JETTY-218 handle AJP ssl key size and integer
+ + JETTY-219 fixed trailing encoded chars in cookies
+ + JETTY-220 fixed AJP content
+ + JETTY-222 fix problem parsing faces-config.xml
+ + add support for Annotations in servlet, filter and listener sources
+ + improved writer buffering
+ + moved JSON parser to util to support reuse
+ + handle virtual hosts in ContextHandlerCollection
+ + enable SslSelectChannelConnector to modify the SslEngine's client
+   authentication settings
+
+jetty-6.1.1 - 15 January 2007
+
+jetty-6.1.1rc1 - 12 January 2007
+ + Use timers for Rollover logs and scanner
+ + JETTY-210 Build jsp-api-2.0 for java 1.4
+
+jetty-6.1.1rc0 - 10 January 2007
+ + Fixed unpacking WAR
+ + extras/win32service download only if no JavaServiceWrapper exist
+ + MultiPartFilter deleteFiles option
+ + CGI servlet fails without exception
+ + JETTY-209 Added ServletTester.createSocketConnector
+ + JETTY-210 Build servlet-api-2.5 for java 1.4
+ + JETTY-211 fixed jboss build
+ + ensure response headers on AjaxFilter messsages turn off caching
+ + start webapps on deployment with jboss, use isDistributed() method from
+   WebAppContext
+ + simplified chat demo
+
+jetty-6.1.0 - 09 January 2007
+ + Fixed unpacking WAR
+
+jetty-6.1.0 - 05 January 2007
+ + Improved config of java5 threadpool
+ + Protect context deployer from Errors
+ + Added WebAppContext.setCopyWebDir to avoid JVM jar caching issues.
+ + GERONIMO-2677 refactor of session id handling for clustering
+ + ServletTester sets content length
+ + Added extras/win32service
+ + JETTY-206 fixed AJP getServerPort and getRemotePort
+
+jetty-6.1.0rc3 - 02 January 2007
+ + JETTY-195 fixed ajp ssl_cert handling
+ + JETTY-197 fixed getRemoteHost
+ + JETTY-203 initialize ServletHandler if no Context instance
+ + JETTY-204 setuid fix
+ + setLocale does not use default content type
+ + Use standard releases of servlet and jsp APIs.
+ + implement resource injection and lifecycle callbacks declared in web.xml
+ + extras/servlet-tester
+
+jetty-6.1.0rc2 - 20 December 2006
+ + AJP13Parser, throw IllegalStateException on unimplemented AJP13 Requests
+ + ContextHandlerCollection is noop with no handlers
+ + ensure servlets initialized if only using ServletHandler
+ + fixed Jetty-197 AJP13 getRemoteHost()
+ + Refactored AbstractSessionManager for ehcache
+ + ensure classpath passed to jspc contains file paths not urls
+ + JETTY-194 doubles slashes are significant in URIs
+ + JETTY-167 cometd refactor
+ + remove code to remove SecurityHandler if no constraints present
+ + JETTY-201 make run-as work for both web container and ejb container in jboss
+ + ensure com.sun.el.Messages.properties included in jsp-2.1 jar
+
+jetty-6.1.0rc1 - 14 December 2006
+ + simplified idle timeout handling
+ + JETTY-193 MailSessionReference without authentication
+ + JETTY-199 newClassPathResource
+ + ensure unique name for ServletHolder instances
+ + added cache session manager(pre-alpha)
+
+jetty-6.1.0rc0 - 08 December 2006
+ + JETTY-181 Allow injection of a java:comp Context
+ + JETTY-182 Optionally set JSP classpath initparameter
+ + Dispatcher does not protect javax.servlet attributes
+ + DefaultHandler links virtual hosts.
+ + Fixed cachesize on invalidate
+ + Optimization of writers
+ + ServletHandler allows non REQUEST exceptions to propogate
+ + TCK fixes from Sybase:
+ + Handle request content encodings
+ + forward query attribute fix
+ + session attribute listener
+ + Servlet role ref
+ + flush if content-length written
+ + 403 for BASIC authorization failure
+ + null for unknown named dispatches
+ + JETTY-184 cometd connect non blocking
+ + Support for RFC2518 102-processing response
+ + JETTY-123 fix improved
+ + Added org.mortbay.thread.concurrent.ThreadPool
+ + Added extras/gwt
+ + Fixed idle timeout
+ + JETTY-189 ProxyConnection
+ + Added spring ejb3 demo example
+ + update jasper to glassfish SJSAS-9_1-B27-EA-07_Dec_2006
+ + JETTY-185 tmp filename generation
+
+jetty-6.1.0pre3 - 22 November 2006
+ + fixed NIO endpoint flush. Avoid duplicate sends
+ + CVE-2006-6969 Upgraded session ID generation to use SecureRandom
+ + updated glassfish jasper to tag SJSAS-9_1-B25-EA-08_Nov_2006
+ + Support TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ + JETTY-180 XBean support for context deploy
+ + JETTY-154 Cookies are double quotes only
+ + Expose isResumed on Continuations
+ + Refactored AJP generator
+
+jetty-6.0.2 - 22 November 2006
+ + Moved all modules updates from 6.1pre2 to 6.0
+ + Added concept of bufferred endpoint
+ + Added conversion Object -> ObjectName for the result of method calls made on
+   MBeans
+ + Added DataFilter configuration to cometd
+ + added examples/test-jaas-webapp
+ + Added extraClassPath to WebAppContext
+ + Added hierarchical destroy of mbeans
+ + Added ID constructor to AbstractSessionManager.Session
+ + added isStopped() in LifeCycle and AbstractLifeCycle
+ + Added override descriptor for deployment of RO webapps
+ + add <Property> replacement in jetty xml config files
+ + alternate optimizations of writer (use -Dbuffer.writers=true)
+ + Allow session cookie to be refreshed
+ + Apply queryEncoding to getQueryString
+ + CGI example in test webapp
+ + change examples/test-jndi-webapp so it can be regularly built
+ + Default soLinger is -1 (disabled)
+ + ensure "" returned for ServletContext.getContextPath() for root context
+ + ensure sessions nulled out on request recycle; ensure session null after
+   invalidate
+ + ensure setContextPath() works when invoked from jetty-web.xml
+ + fixed NIO endpoint flush. Avoid duplicate sends
+ + Fixed NPE in bio.SocketEndPoint.getRemoteAddr()
+ + Fixed resource cache flushing
+ + Fixed tld parsing for maven plugin
+ + HttpGenerator can generate requests
+ + Improved *-mbean.properties files and specialized some MBean
+ + JETTY-118 ignore extra content after close.
+ + JETTY-119 cleanedup Security optimizatoin
+ + JETTY-123 handle windows UNC paths
+ + JETTY-126 handle content > Integer.MAX_VALUE
+ + JETTY-129 ServletContextListeners called after servlets are initialized
+ + JETTY-151 Idle timeout only applies to blocking operations
+ + JETTY-154 Cookies are double quotes only
+ + JETTY-171 Fixed filter mapping
+ + JETTY-172 use getName() instead of toString
+ + JETTY-173 restore servletpath after dispatch
+ + Major refactor of SelectChannel EndPoint for client selector
+ + make .tag files work in packed wars
+ + Plugin shutdown context before stopping it.
+ + Refactored session lifecycle and additional tests
+ + release resource lookup in Default servlet
+ + (re)make JAAS classes available to webapp classloader
+ + Reverted UnixCrypt to use coersions (that effected results)
+ + Session IDs can change worker ID
+ + Simplified ResourceCache and Default servlet
+ + SocketConnector closes all connections in doStop
+ + Upgraded session ID generation to use SecureRandom
+ + updated glassfish jasper to tag SJSAS-9_1-B25-EA-08_Nov_2006
+ + Support TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+
+jetty-5.1.14 - 09 August 2007
+ + patched with correct version
+ + JETTY-155 force close with content length.
+ + JETTY-369 failed state in Container
+
+jetty-5.1.13
+ + Sourceforge 1648335: problem setting version for AJP13
+
+jetty-5.1.12 - 22 November 2006
+ + Added support for TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ + Upgraded session ID generation to use SecureRandom
+ + Quote single quotes in cookies
+ + AJP protected against bad requests from mod_jk
+ + JETTY-154 Cookies ignore single quotes
+
+jetty-4.2.27 - 22 November 2006
+ + Upgraded session ID generation to use SecureRandom
+ + AJP protected against bad requests from mod_jk
+
+jetty-6.1.0pre2 - 20 November 2006
+ + Added extraClassPath to WebAppContext
+ + Fixed resource cache flushing
+ + Clean up jboss module licensing
+
+jetty-6.1.0pre1 - 19 November 2006
+ + Use ContextDeployer as main deployer in jetty.xml
+ + Added extras/jboss
+ + Major refactor of SelectChannel EndPoint for client selector
+ + Fixed NPE in bio.SocketEndPoint.getRemoteAddr()
+ + Reverted UnixCrypt to use coersions (that effected results)
+ + JETTY-151 Idle timeout only applies to blocking operations
+ + alternate optimizations of writer (use -Dbuffer.writers=true)
+ + JETTY-171 Fixed filter mapping
+ + JETTY-172 use getName() instead of toString
+ + JETTY-173 restore servletpath after dispatch
+ + release resource lookup in Default servlet
+ + Simplified ResourceCache and Default servlet
+ + Added override descriptor for deployment of RO webapps
+ + Added hierarchical destroy of mbeans
+
+jetty-6.1.0pre0 - 21 October 2006
+ + add <Property> replacement in jetty xml config files
+ + make .tag files work in packed wars
+ + add hot deployment capability
+ + ensure setContextPath() works when invoked from jetty-web.xml
+ + ensure sessions nulled out on request recycle; ensure session null after
+   invalidate
+ + ensure "" returned for ServletContext.getContextPath() for root context
+ + Fixed tld parsing for maven plugin
+ + Improved *-mbean.properties files and specialized some MBean
+ + Added conversion Object -> ObjectName for the result of method calls made on
+   MBeans
+ + JETTY-129 ServletContextListeners called after servlets are initialized
+ + change examples/test-jndi-webapp so it can be regularly built
+ + added isStopped() in LifeCycle and AbstractLifeCycle
+ + fixed isUserInRole checking for JAASUserRealm
+ + fixed ClassCastException in JAASUserRealm.setRoleClassNames(String[])
+ + add a maven-jetty-jspc-plugin to do jspc precompilation
+ + added examples/test-jaas-webapp
+ + (re)make JAAS classes available to webapp classloader
+ + CGI example in test webapp
+ + Plugin shutdown context before stopping it.
+ + Added concept of bufferred endpoint
+ + Factored ErrorPageErrorHandler out of WebAppContext
+ + Refactored ErrorHandler to avoid statics
+ + Transforming classloader does not transform resources.
+ + SocketConnector closes all connections in doStop
+ + Improved charset handling in URLs
+ + minor optimization of bytes to UTF8 strings
+ + JETTY-112 ContextHandler checks if started
+ + JETTY-113 support optional query char encoding on requests
+ + JETTY-114 removed utf8 characters from code
+ + JETTY-115 Fixed addHeader
+ + added cometd chat demo
+ + JETTY-119 cleanedup Security optimizatoin
+ + Refactored session lifecycle and additional tests
+ + JETTY-121 init not called on externally constructed servlets
+ + JETTY-124 always initialize filter caches
+ + JETTY-126 handle content > Integer.MAX_VALUE
+ + JETTY-123 handle windows UNC paths
+ + JETYY-120 SelectChannelConnector closes all connections on stop
+ + Added ID constructor to AbstractSessionManager.Session
+ + Allow session cookie to be refreshed
+ + Added DataFilter configuration to cometd
+ + Added extras/setuid to support start as root
+ + Apply queryEncoding to getQueryString
+ + JETTY-118 ignore extra content after close.
+ + HttpGenerator can generate requests
+ + Ported HtAccessHandler
+ + Start of a client API
+ + Session IDs can change worker ID
+ + Default soLinger is -1 (disabled)
+ + AJP Connector
+
+jetty-5.1.11 - 08 October 2006
+ + fixed ByteBufferOutputStream capacity calculation
+ + Fixed AJP handling of certificate length (1494939)
+ + Fixed AJP chunk header (1507377)
+ + Fixed order of destruction event calls
+ + Fix to HttpOutputStream from M.Traverso
+ + Default servlet only uses setContentLength on wrapped responses
+
+jetty-4.2.26 - 08 October 2006
+ + Backport of AJP fixes
+
+jetty-6.0.1 - 24 September 2006
+ + fixed isUserInRole checking for JAASUserRealm
+ + fixed ClassCastException in JAASUserRealm.setRoleClassNames(String[])
+ + Improved charset handling in URLs
+ + Factored ErrorPageErrorHandler out of WebAppContext
+ + Refactored ErrorHandler to avoid statics
+ + JETTY-112 ContextHandler checks if started
+ + JETTY-114 removed utf8 characters from code
+ + JETTY-115 Fixed addHeader
+ + JETTY-121 init not called on externally constructed servlets
+ + minor optimization of bytes to UTF8 strings
+ + JETTY-113 support optional query char encoding on requests
+ + JETTY-124 always initialize filter caches
+ + JETYY-120 SelectChannelConnector closes all connections on stop
+
+jetty-6.0.0 - 10 September 2006
+ + SocketConnector closes all connections in doStop
+ + Conveniance builder methods for listeners and filters
+ + Transforming classloader does not transform resources.
+ + Plugin shutdown context before stopping it.
+
+jetty-6.0.0rc4 - 05 September 2006
+ + bind jetty-env.xml entries to java:comp/env
+ + JETTY-107 Poor cast in SessionDump demo.
+ + Set charset on error pages
+
+jetty-6.0.0rc3 - 01 September 2006
+ + pulled 6.0.0 branch
+ + JETTY-103
+ + Move MailSessionReference to org.mortbay.naming.factories
+ + Less verbose handling of BadResources from bad URLs
+ + Avoid double error handling of Bad requests
+ + don't warn for content length on head requests
+ + JETTY-104 (raised glassfish ISSUE-1044) hide JSP forced path attribute
+ + JETTY-68 Complete request after sendRedirect
+ + Transferred the sslengine patch from the patches directory to extras
+
+jetty-6.0.0rc2 - 25 August 2006
+ + use mvn -Dslf4j=false jetty:run to disable use of slf4j logging with
+   jdk1.4/jsp2.0
+ + added org.apache.commons.logging package to system classes that can't be
+   overridden by a webapp classloader
+ + mvn -Djetty.port=x jetty:run uses port number given for the default
+   connector
+ + Fixed NPE when no resource cache
+ + Refactored WebXmlConfiguration to allow custom web.xml resource
+ + Moved more utility packagtes to the util jar
+ + Direct buffer useage is optional
+ + Destroy HttpConnection to improve buffer pooling
+ + Timestamp in StdErrLog
+
+jetty-6.0.0rc1 - 16 August 2006
+ + Support for binding References and Referenceables and javax.mail.Sessions in
+   JNDI
+ + Added TransformingWebAppClassLoader for spring 2.0 byte code modification
+   support
+ + JETTY-90
+ + Fixed FD leak for bad TCP acks. JETTY-63
+ + JETTY-87
+ + Change path mapping so that a path spec of /foo/* does not match /foo.bar :
+   JETTY-88
+ + add <requestLog> config param to jetty plugin
+ + JETTY-85 JETTY-86 (TrustManager and SecureRandom are now configurable;
+   better handling of null/default values)
+ + parse jsp-property-group in web.xml for additional JSP servlet mappings
+ + protected setContentType from being set during include
+ + JETTY-91
+ + added modules/spring with XmlBeanFactory configuration
+ + removed support for lowResources from SelectChannelConnector
+ + added start of cometd implementation (JSON only)
+ + added start of grizzly connector
+ + removed org.mortbay. from context system classes configuration
+ + -DSTOP.PORT must be specified.
+ + moved optional modules to extras
+ + fixed bug that caused Response.setStatus to ignore the provided message
+ + refactored resource cache
+ + Allow direct filling of buffers for uncached static content.
+ + Added simple ResourceHandler and FileServer example
+
+jetty-6.0.0rc0 - 07 July 2006
+ + change prefix from "jetty6" to just "jetty" for plugin: eg is now mvn
+   jetty:run
+ + allow <key> or <name> in <systemProperty> for plugin
+ + simplified jetty.xml with new constructor injections
+ + added setters and getters on SessionManager API for session related config:
+   cookie name, url parameter name, domain, max age and path.
+ + add ability to have a lib/ext dir from which to recursively add all jars and
+   zips to the classpath
+ + patch to allow Jetty to use JSP2.1 from Glassfish instead of Jasper from
+   Tomcat
+ + fixed classesDirectory param for maven plugin to be configurable
+ + ensure explicitly set tmp directory called "work" is not deleted on exit
+ + ensure war is only unpacked if war is newer than "work" directory
+ + change name of generated tmp directory to be
+   "Jetty_"+host+"_"+port+"_"+contextpath+"_"+virtualhost
+ + Cleaned up idle expiry.
+ + Ssl algorithm taken from system property
+ + Added 8 random letters&digits to Jetty-generated tmp work dir name to ensure
+   uniqueness
+ + Simplify runtime resolution of JSP library for plugin
+ + Ensure mvn clean cleans the build
+ + Do not wrap EofException with EofException
+ + reverse order for destroy event listeners
+ + added StatisticsHandler and statistics on Connector.
+ + Simplified Servlet Context API
+ + Added maximum limit to filter chain cache.
+ + refactor HttpChannelEndPoint in preparation for SslEngine
+ + ContextHandlerCollection addContext and setContextClass
+ + Discard excess bytes in header buffer if connection is closing
+ + Updated javax code from
+   http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/java/javax@417727
+ + Threadpool does not need to be a LifeCycle
+ + support graceful shutdown
+ + Added WebAppContextClassLoader.newInstance to better support exensible
+   loaders.
+ + immutable getParameterMap()
+ + support <load-on-startup> for SingleThreadModel
+ + changed ServletContext.getResourcePaths()  to not return paths containing
+   double slashes
+ + fixed HttpGenerator convertion of non UTF-8: JETTY-82
+ + added html module from jetty 5 - but deprecated until maintainer found
+
+jetty-6.0.0beta17 - 01 June 2006
+ + Added config to disable file memory mapped buffers for windows
+ + Added Request.isHandled()
+ + Refactored Synchronization of SelectChannelConnector
+ + Recovered repository from Codehaus crash
+ + ContextHandler.setConnectors replace setHosts
+ + Connector lowResourceMaxIdleTime  implemented.
+ + Default servlet checks for aliases resources
+ + Added clover reports and enough tests to get >50% coverage
+ + Fixed IE SSL issue.
+ + Implemented runAs on servlets
+ + Flush will flush all bytes rather than just some.
+ + Protected WEB-INF and META-INF
+ + don't reset headers during forward
+ + BoundedThreadPool.doStop waits for threads to complete
+
+jetty-6.0.0beta16 - 12 May 2006
+ + remove a couple of System.err.printlns
+ + replace backwards compativle API in UrlEncoded
+
+jetty-6.0.0beta15 - 11 May 2006
+ + Added Server attribute org.mortbay.jetty.Request.maxFormContentSize
+ + Renamed NotFoundHandler to DefaultHandler
+ + Added automatic scan of all WEB-INF/jetty-*.xml files for plugin
+ + Added <scanTargets> parameter to allow other locations to scan for plugin
+ + Major refactor to simplify Server and handler hierarchy
+ + setSendServerVersion method added to Server to control sending of Server:
+   http header
+ + removed SelectBlockingChannelConnector (unmaintained)
+ + Improved HttpException
+ + Moved more resources to resources
+ + Added ThrottlingFilter and fixed race in Continuations
+ + Added taglib resources to 2.1 jsp api jar
+ + Reset of timer task clears expiry
+ + improved MBeanContainer object removal
+ + ContextHandler.setContextPath can be called after start.
+ + Fixed handling of params after forward
+ + Added --version to start.jar
+ + Added embedded examples
+ + Simplified DefaultServlet static content buffering
+ + readded BoundedThreadPool shrinking (and then fixed resulting deadlock)
+ + improved MBean names
+ + improved support for java5 jconsole
+ + Session scavenger threads from threadpool
+ + Thread names include URI if debug set
+ + don't accept partial authority in request line.
+ + enforce 204 and 304 have no content
+
+jetty-6.0.0beta14 - 09 April 2006
+ + ignore dirs and files that don't exist in plugin scanner
+ + added support for stopping jetty using "java -jar start.jar --stop"
+ + added configurability for webdefault.xml in maven plugin
+ + adding InvokerServlet
+ + added ProxyServlet
+ + stop JDBCUserRealm coercing all credentials to String
+ + Change tmp dir of plugin to work to be in line with jetty convention
+ + Modify plugin to select JSP impl at runtime
+ + Use start.config to select which JSP impl at runtime based on jdk version
+ + Added JSP 2.1 APIs from apache
+ + Added Jasper 2.1 as jesper (jasper without JCL)
+ + Started readding logging to jesper using jdk logging
+ + fixed priority of port from url over host header
+ + implemented request.isUserInRole
+ + securityHandler removed if not used.
+ + moved test webapps to examples directory
+ + improved contentType handling and test harness
+ + fixed forward bug (treated as include)
+ + fixed HttpField iterator
+ + added jetty-util.jar module
+ + added reset to Continuation
+
+jetty-6.0.0beta12 - 16 March 2006
+ + Fixed maven plugin JNDI for redeploys
+ + Fixed tld discovery for plugin (search dependencies)
+ + Fixed JettyPlus for root contexts
+ + Fixed error handling in error page
+ + Added JSP2.0 demos to test webapp
+ + Upgraded jasper to 5.5.15
+ + Added provider support to SslListener
+ + Log ERROR for runtimeExceptions
+
+jetty-6.0.0beta11 - 14 March 2006
+ + added JAAS
+ + added webapp-specific JNDI entries
+ + added missing Configurations for maven plugin
+ + fixed FORM authentication
+ + moved dtd and xsd to standard javax location
+ + added patch to use joda-time
+ + refactored session ID management
+ + refactored configuration files and start()
+ + fixed ; decoding in URIs
+ + Added HttpURI and improved UTF-8 parsing.
+ + refactored writers and improved UTF-8 generation.
+
+jetty-6.0.0beta10 - 25 February 2006
+ + Added support for java:comp/env
+ + Added support for pluggable transaction manager
+ + Forward masks include attributes and vice versa
+ + Fixed default servlet handling of includes
+ + Additional accessors for request logging
+ + added getLocalPort() to connector
+ + Fixed content-type for range requests
+ + Fix for sf1435795 30sec delay from c taylor
+ + Fix for myfaces and include with close
+ + Fix sf1431936 don't chunk the chunk
+ + Fix http://jira.codehaus.org/browse/JETTY-6. hi byte reader
+ + Updates javax to MR2 release
+
+jetty-6.0.0beta9 - 09 February 2006
+ + PathMap for direct context mapping.
+ + Refactored chat demo and upgraded prototype.js
+ + Continuation cleanup
+ + Fixed unraw decoding of query string
+ + Fixed dispatch of wrapped requests.
+ + Fixed double flush of short content.
+ + Added request log.
+ + Added CGI servlet.
+ + Force a tempdir to be set.
+ + Force jasper scratch dir.
+ + fixed setLocale bug sf1426940
+ + Added TLD tag listener handling.
+
+jetty-6.0.0beta8 - 24 January 2006
+ + fixed dispatch of new session problem. sf:1407090
+ + reinstated rfc2616 test harness
+ + Handle pipeline requests without hangs
+ + Removed queue from thread pool.
+ + improved caching of content types
+ + fixed bug in overloaded write method on HttpConnection (reported against
+   Tapestry4.0)
+ + hid org.apache.commons.logging and org.slf4j packages from webapp
+ + maven-jetty6-plugin stopped transitive inclusion of log4j and
+   commons-logging from commons-el for jasper
+ + patch to remove spurious ; in HttpFields
+ + improve buffer return mechanism.
+ + conveniance addHandler removeHandler methods
+ + maven-jetty6-plugin: ensure compile is done before invoking jetty
+ + maven-jetty6-plugin: support all types of artifact dependencies
+
+jetty-6.0.0Beta7
+ + Fixed infinite loop with chunk handling
+ + Faster header name lookup
+ + removed singleton Container
+ + reduced info verbosity
+ + null dispatch attributes not in names
+ + maven-jetty6-plugin added tmpDirectory property
+ + maven-jetty6-plugin stopped throwing an error if there is no target/classes
+   directory
+
+jetty-6.0.0Beta6
+ + Fixed issue with blocking reads
+ + Fixed issue with unknown headers
+ + optimizations
+
+jetty-6.0.0Beta5
+ + Moved to SVN
+ + Fixed writer char[] creations
+ + Added management module for mbeans
+
+jetty-6.0.0Beta4
+ + System property support in plugin
+ + CVE-2006-2758 Fixed JSP visibility security issue.
+ + Improved jetty-web.xml access to org.mortbay classes.
+ + Jasper 5.5.12
+
+jetty-6.0.0Beta3
+ + Fixed error in block read
+ + Named dispatch.
+ + Fixed classloader issue with server classes
+
+jetty-6.0.0Beta2
+ + merged util jar back into jetty jar
+ + Simpler continuation API
+ + loosely coupled with JSP servlet
+ + loosely coupled with SLF4J
+ + Improved reuse of HttpField values and cookies.
+ + Improved buffer return
+
+jetty-6.0.0Beta1
+ + Servlet 2.5 API
+ + SSL connector
+ + maven2 plugin
+ + shutdown hook
+ + refactored start/stop
+ + Implemented all listeners
+ + Error pages
+ + Virtual hosts
+ + Multiple select sets
+
+jetty-6.0.0Beta0
+ + Maven 2 build
+ + Dispatcher parameters
+ + UTF-8 encoding for URLs
+ + Fixed blocking read
+
+jetty-6.0.0APLPA3
+ + Added demo for Continuations
+ + Jasper and associated libraries.
+
+jetty-6.0.0ALPHA2
+ + Continuations - way cool way to suspend a request and retry later.
+ + Dispatchers
+ + Security
+
+jetty-6.0.0ALPHA1
+ + Filters
+ + web.xml handling
+
+jetty-6.0.0ALPHA0
+ + Totally rearchitected and rebuilt, so 10 years of cruft could be removed!
+ + Improved "dependancy injection" and "inversion of control" design of
+   components
+ + Improved "interceptor" design of handlers
+ + Smart split buffer design allows large buffers to only be allocated to
+   active connections. The resulting memory savings allow very large buffers to
+   be used, which increases the chance of efficient asynchronous flushing and
+   of avoiding chunking.
+ + Optional use of NIO Buffering so that efficient direct buffers and memory
+   mapped files can be used.
+ + Optional use of NIO non-blocking scheduling so that threads are not
+   allocated per connection.
+ + Optional use of NIO gather writes, so that for example a HTTP header and a
+   memory mapped
+ + file may be sent as sent is a single operation.
+ + Missing Security
+ + Missing Request Dispatchers
+ + Missing web.xml based configuration
+ + Missing war support
+
+jetty-5.1.11RC0 - 05 April 2006
+ + stop JDBCUserRealm forcing all credentials to be String
+ + force close with shutdownOutput for win32
+ + NPE protection if desirable client certificates
+ + Added provider support to SslListener
+ + logging improvements for servlet and runtime exceptions
+ + Fixed AJP handling of ;jsessionid.
+ + improved contentType param handling
+
+jetty-5.1.10 - 05 January 2006
+ + Fixed path aliasing with // on windows.
+ + Fix for AJP13 with multiple headers
+ + Fix for AJP13 with encoded path
+ + Remove null dispatch attributes from getAttributeNames
+ + Put POST content default back to iso_8859_1. GET is UTF-8 still
+
+jetty-4.2.25 - 04 January 2006
+ + Fixed aliasing of // for win32
+
+jetty-5.1.9 - 07 December 2005
+ + Fixed wantClientAuth(false) overriding netClientAuth(true)
+
+jetty-6.0.0betaX
+ + See http://jetty.mortbay.org/jetty6 for 6.0 releases
+
+jetty-5.1.8 - 07 December 2005
+ + Fixed space in URL issued created in 5.1.6
+
+jetty-5.1.7 - 07 December 2005
+
+jetty-5.1.7rc0 - 06 December 2005
+ + improved server stats
+ + char encoding for MultiPartRequest
+ + fixed merging of POST params in dispatch query string.
+ + protect from NPE in dispatcher getValues
+ + Updated to 2.6.2 xerces
+ + JSP file servlet mappings copy JspServlet init params.
+ + Prefix servlet context logs with org.mortbay.jetty.context
+ + better support for URI character encodings
+ + use commons logging jar instead of api jar.
+
+jetty-5.1.6 - 18 November 2005
+ + CVE-2006-2758 Fixed JSP visibility security issue.
+ + Improved jetty-web.xml access to org.mortbay classes.
+
+jetty-5.1.5 - 10 November 2005
+ + Improved shutdown hook
+ + Improved URL Decoding
+ + Improved mapping of JSP files.
+
+jetty-5.1.5rc2 - 07 October 2005
+ + Reverted dispatcher params to RI rather than spec behaviour.
+ + ProxyHandler can handle chained proxies
+ + unsynchronized ContextLoader
+ + ReFixed merge of Dispatcher params
+ + public ServerMBean constructor
+ + UTF-8 encoding for URLs
+ + Response.setLocale will set locale even if getWriter called.
+
+jetty-5.1.5rc1 - 23 August 2005
+ + upgraded to commons logging 1.0.4
+ + Release commons logging factories when stopping context.
+ + Fixed illegal state with chunks and 100 continue - Tony Seebregts
+ + Fixed PKCS12Import input string method
+ + Fixed merge of Dispatcher parameters
+ + Encoded full path in ResourceHandler directory listing
+ + handle extra params after charset in header
+ + Fixed 100-continues with chunking and early commit
+
+jetty-5.1.5rc0 - 16 August 2005
+ + Fixed component remove memory leak for stop/start cycles
+ + Facade over commons LogFactory so that discovery may be avoided.
+ + Applied ciphersuite patch from tonyj
+ + Authenticators use servlet sendError
+ + CGI sets SCRIPT_FILENAME
+ + HttpTunnel timeout
+ + NPE protection for double stop in ThreadedServer
+ + Expect continues only sent if input is read.
+
+jetty-5.1.4 - 05 June 2005
+ + Fixed FTP close issue.
+ + setup MX4J with JDK1.5 in start.config
+ + set classloader during webapp doStop
+ + NPE protection in ThreadedServer
+ + ModelMBean handles null signatures
+ + Change JAAS impl to be more flexible on finding roles
+
+jetty-5.1.4rc0 - 19 April 2005
+ + ServletHttpContext correctly calls super.doStop.
+ + HttpServer delegates component handling to Container.
+ + Allow ServletHandler in normal HttpContext again.
+ + Stop start.jar putting current directory on classpath.
+ + More protection from null classloaders.
+ + Turn off web.xml validation for JBoss.
+
+jetty-5.1.3 - 07 April 2005
+ + Some minor code janitorial services
+
+jetty-4.2.24 - 07 April 2005
+
+jetty-5.1.3rc4 - 31 March 2005
+ + Moved servlet request wrapping to enterContextScope for geronimo security
+ + refixed / mapping for filters
+ + Allow XmlConfiguration to start with no object.
+ + updated to mx4j 3.0.1
+ + rework InitialContextFactory to use static 'default' namespace
+ + make java:comp/env immutable for webapps as per J2EE spec
+
+jetty-5.1.3rc3 - 20 March 2005
+ + removed accidental enablement of DEBUG for JettyPlus jndi in
+   log4j.properties
+ + fixed "No getter or setter found" mbean errors
+
+jetty-5.1.3rc2 - 16 March 2005
+ + Updated JSR154Filter for ERROR dispatch
+ + Fixed context to _context refactory error
+
+jetty-5.1.3rc1 - 13 March 2005
+ + Fixed typo in context-param handling.
+ + update to demo site look and feel.
+ + Fixed principal naming in FormAuthenticator
+ + JettyPlus updated to JOTM 2.0.5, XAPool 1.4.2
+
+jetty-4.2.24rc1
+ + Fixed principal naming in FormAuthenticator
+
+jetty-5.1.3rc0 - 08 March 2005
+ + Flush filter chain caches on servlet/filter change
+ + Fixed rollover filename format bug
+ + Fixed JSR154 error dispatch with explicit pass of type.
+ + Allow system and server classes to be configured for context loader.
+ + IOException if EOF read during chunk.
+ + Fixed HTAccess crypt salt handling.
+ + Added simple xpath support to XmlParser
+ + Added TagLibConfiguration to search for listeners in TLDs.
+ + Added SslListener for 1.4 JSSE API.
+ + Fixed moderate load preventing ThreadPool shrinking.
+ + Added logCookie and logLatency support to NCSARequestLog
+ + Added new JAAS callback to allow extra login form fields in authentication
+
+jetty-4.2.24rc0 - 08 March 2005
+ + Back ported Jetty 5 ThreadedServer and ThreadPool
+ + Added logCookie and logLatency support to NCSARequestLog
+
+jetty-5.1.2 - 18 January 2005
+ + Added id and ref support to XmlConfiguration
+ + Cleaned up AbstractSessionManager synchronization.
+ + Fixed potential concurrent login problem with JAAS
+ + Apply patch #1103953
+
+jetty-4.2.23 - 16 January 2005
+ + Cleaned up AbstractSessionManager synchronization.
+ + Fixed potential concurrent login problem with JAAS
+
+jetty-5.1.2pre0 - 22 December 2004
+ + Fixed case of Cookie parameters
+ + Support Secure and HttpOnly in session cookies
+ + Modified useRequestedID handling to only use IDs from other contexts
+ + Added global invalidation to AbstractSessionManager
+ + UnavailableException handling from handle
+ + Fixed suffix filters
+
+jetty-4.2.23RC0 - 17 December 2004
+ + LineInput handles readers with small internal buffer
+ + Added LogStream to capture stderr and stdout to logging
+ + Support Secure and HttpOnly in session cookies
+ + Build unsealed jars
+
+jetty-5.1.1 - 01 December 2004
+
+jetty-5.1.1RC1
+ + Some minor findbugs code cleanups
+ + Made more WebApplicationHandle configuration methods public.
+ + Fixed ordering of filters with multiple interleaved mappings.
+ + Allow double // within URIs
+ + Applied patch for MD5 hashed credentials for MD5
+
+jetty-5.1.1RC0 - 17 November 2004
+ + fix for adding recognized EventListeners
+ + fix commons logging imports to IbmJsseListener
+ + added new contributed shell start/stop script
+ + excluded ErrorPageHandler from standard build in extra/jdk1.2 build
+
+jetty-5.1.0 - 14 November 2004
+
+jetty-5.1.RC1 - 24 October 2004
+ + Allow JSSE listener to be just confidential or just integral.
+ + Fixed NPE for null contenttype
+ + improved clean targets
+ + when committed setHeader is a noop rather than IllegalStateException
+ + Partially flush writers on every write so content length can be detected.
+ + Build unsealed jars
+ + default / mapping does not apply to Filters
+ + many minor cleanups suggested from figbug utility
+ + Allow multiple accepting threads
+
+jetty-5.1.RC0 - 11 October 2004
+ + Fixed many minor issues from J2EE 1.4 TCK testing See sf.net bugs 1031520 -
+   1032205
+ + Refactored, simplified and optimized HttpOutputStream
+ + LineInput handles readers with small internal buffer
+ + Added LogStream to capture stderr and stdout to logging
+ + Added filter chain cache
+ + Added JSR77 servlet statistic support
+ + Refactored webapp context configurations
+ + Added LifeCycle events and generic container.
+ + Upgraded to ant-1.6 for jasper
+ + Fixed HTAccessHandler
+ + JBoss 4.0.0 support
+
+jetty-5.0.0 - 10 September 2004
+
+jetty-5.0.RC4 - 05 September 2004
+ + Fixed configuration of URL alias checking
+ + JettyJBoss: Use realm-name from web.xml if present, otherwise use
+   security-domain from jboss-web.xml
+
+jetty-5.0.RC3 - 28 August 2004
+ + DIGEST auth handles qop, stale and maxNonceAge.
+ + Less verbose warning for non validating xml parser.
+ + fixed jaas logout for jetty-jboss
+ + fixed deployment of ejb-link elements in web.xml with jboss
+ + Update to jasper 5.0.27
+ + Added parameters for acceptQueueSize and lowResources level.
+ + Changed default URI encoding to UTF-8
+ + Fixes to work with java 1.5
+ + JettyPlus upgrade to XAPool 1.3.3. and HSQLDB 1.7.2
+ + JettyPlus addition of pluggable DataSources
+ + Always say close for HTTP/1.0 non keep alive.
+
+jetty-4.2.22
+ + fixed jaas logout for jetty-jboss integration
+ + fixed deployment of ejb-link elements in web.xml for jboss
+ + Added parameters for acceptQueueSize and lowResources level.
+
+jetty-5.0.RC2 - 02 July 2004
+ + Fixed DIGEST challenge delimiters
+ + HTAccess calls UnixCrypt correctly
+ + integrated jetty-jboss with jboss-3.2.4
+ + Error dispatchers are always GET requests.
+ + OPTIONS works for all URLs on default servlet
+ + add JMX support for JettyPlus
+ + add listing of java:comp/env for webapp with JMX
+ + make choice of override of JNDI ENC entries: config.xml or web.xml
+ + Default servlet may use only pathInfo for resource
+ + Fixed session leak in j2ee
+ + Fixed no-role security constraint combination.
+ + Fix to use runas roles during servlet init and destroy
+ + Fixed JAAS logout
+ + HttpContext sendError for authentication errors
+
+jetty-4.2.21 - 02 July 2004
+ + integrated jetty-jboss with jboss-3.2.4
+ + add JMX support for JettyPlus
+ + add listing of java:comp/env for webapp with JMX
+ + make choice of override of JNDI ENC entries: config.xml or web.xml
+ + Fixed JAAS logout
+
+jetty-5.0.RC1 - 24 May 2004
+ + Changed to apache 2.0 license
+ + added extra/etc/start-plus.config to set up main.class for jettyplus
+ + maxFormContentLength may be unlimited with <0 value
+ + Fixed HTTP tunnel timeout setting.
+ + Improved handling of exception from servlet init.
+ + FORM auth redirects to context on a re-auth
+ + Handle multiple virutal hosts from JBoss 3.2.4RC2
+
+jetty-4.2.20 - 22 May 2004
+ + maxFormContentLength may be unlimited with <0 value
+ + Fixed HTTP tunnel timeout setting.
+ + Improved handling of exception from servlet init.
+ + FORM auth redirects to context on a re-auth
+
+jetty-5.0.0RC0 - 07 April 2004
+ + Updated JettyPlus to JOTM 1.4.3 (carol-1.5.2, xapool-1.3.1)
+ + ServletContext attributes wrap HttpContext attributes.
+ + Factored out XML based config from WebApplicationContext
+ + Improved RequestLog performance
+ + Fixed j2se 1.3 problem with HttpFields
+ + Default servlet respectes servlet path
+ + Fixed setCharacterEncoding for parameters.
+ + Fixed DOS problem
+ + Worked around bad jboss URL handler in XMLParser
+ + Forced close of connections over stop/start
+ + ProxiedFor field support added to NCSARequestLog
+ + Fixed Default servlet for non empty servlet paths
+ + Updated mx4j to V2
+ + Updated jasper to 5.0.19
+ + Changed dist naming convention to lowercase
+
+jetty-4.2.20RC0 - 07 April 2004
+ + Worked around bad jboss URL handler in XMLParser
+ + Forced close of connections over stop/start
+ + HttpFields protected headers
+ + ProxiedFor field support added to NCSARequestLog
+ + Fixed Default servlet for non empty servlet paths
+ + Changed dist naming convention to lowercase
+
+jetty-4.2.19 - 19 March 2004
+ + Fixed DOS attack problem
+
+jetty-5.0.beta2 - 12 February 2004
+ + Added skeleton JMX MBean for jetty plus
+ + Fixed HEAD with empty chunk bug.
+ + Fixed jetty.home/work handling
+ + Fixed setDate thread safety
+ + Fixed SessionManager init
+ + Improved low thread handling
+ + FileResource better handles non sun JVM
+ + Monitor closes socket before exit
+ + Updated to Japser 5.0.16
+ + RequestDispatcher uses request encoding for query params
+ + Fixed busy loop in threadpool run
+ + Reorganized ServletHolder init
+ + Added log4j context repository to jettyplus
+ + NPE guard for no-listener junit deployment
+ + Added experimental NIO listeners again.
+ + fixed filter dispatch configuration.
+ + fixed lazy authentication with FORMs
+
+jetty-4.2.18 - 01 March 2004
+ + Added log4j context repository to jettyplus
+ + NPE guard for no-listener junit deployment
+ + Improved log performance
+ + Fixed j2se 1.3 problem with HttpFields
+ + Suppress some more IOExceptions
+ + Default servlet respectes servlet path
+
+jetty-4.2.17 - 01 February 2004
+ + Fixed busy loop in threadpool run
+ + Reorganized ServletHolder init
+
+jetty-4.2.16 - 30 January 2004
+ + Fixed setDate multi-cpu race
+ + Improved low thread handling
+ + FileResource better handles non sun JVM
+ + Fixed HttpTunnel for JDK 1.2
+ + Monitor closes socket before exit
+ + RequestDispatcher uses request encoding for query params
+ + Update jasper to 4.1.29
+
+jetty-5.0.beta1 - 24 December 2003
+ + SecurityConstraints not reset by stop() on custom context
+ + Fixed UnixCrypt handling in HTAccessHandler
+ + Added patch for JBoss realm single sign on
+ + Reorganized FAQ
+ + Env variables for CGI
+ + Removed support for old JBoss clustering
+
+jetty-4.2.15 - 24 December 2003
+ + SecurityConstraints not reset by stop() on custom context
+ + Fixed UnixCrypt handling in HTAccessHandler
+ + Added patch for JBoss realm single sign on
+ + Environment variables for CGI
+ + Removed support for old JBoss clustering
+
+jetty-5.0.beta0 - 22 November 2003
+ + Removed support for HTTP trailers
+ + PathMap uses own Map.Entry impl for IBM JVMs
+ + Use ${jetty.home}/work or WEB-INF/work for temp directories if present
+ + Protect ThreadPool.run() from interrupted exceptions
+ + Added org.mortbay.http.ErrorHandler for error pages.
+ + Fixed init race in HttpFields cache
+ + Allow per listener handlers
+ + Added MsieSslHandler to handle browsers that don't grok persistent SSL (msie
+   5)
+ + Respect content length when decoding form content.
+ + JBoss integration uses writer rather than stream for XML config handling
+ + Expire pages that contain set-cookie as per RFC2109 recommendation
+ + Updated jasper to 5.0.14beta
+ + Removed the CMR/CMP distributed session implementation
+
+jetty-4.2.15rc0 - 22 November 2003
+ + PathMap uses own Map.Entry impl for IBM JVMs
+ + Race in HttpFields cache
+ + Use ${jetty.home}/work or WEB-INF/work for temp directories if present
+ + Protect ThreadPool.run() from interrupted exceptions
+ + Added org.mortbay.http.ErrorHandler for error pages.
+ + JsseListener checks UserAgent for browsers that can't grok persistent SSL
+   (msie5)
+ + Removed the CMR/CMP distributed session implementation
+
+jetty-4.2.14 - 04 November 2003
+ + respect content length when decoding form content.
+ + JBoss integration uses writer rather than stream for XML config handling
+ + Fixed NPE in SSO
+ + Expire pages that contain set-cookie as per RFC2109 recommendation
+
+jetty-5.0.alpha3 - 19 October 2003
+ + Reworked Dispatcher to better support cross context sessions.
+ + Use File.toURI().toURL() when jdk 1.2 alternative is available.
+ + Priority added to ThreadPool
+ + replaced win32 service with http://wrapper.tanukisoftware.org
+ + FileClassPath derived from walk of classloader hierarchy.
+ + Implemented security constraint combinations
+ + Set TransactionManager on JettyPlus datasources and pools
+ + Fixed null pointer if no sevices configured for JettyPlus
+ + Updated jasper and examples to 5.0.12
+ + Lazy authentication if no auth constraint.
+ + Restore servlet handler after dispatch
+ + Allow customization of HttpConnections
+ + Failed requests excluded from duration stats
+
+jetty-4.2.14RC1 - 19 October 2003
+ + Reworked Dispatcher to better support cross context sessions.
+ + Added UserRealm.logout and arrange for form auth
+ + Allow customization of HttpConnections
+ + Failed requests excluded from
+
+jetty-4.2.14RC0 - 07 October 2003
+ + Correctly setup context classloader in cross context dispatch.
+ + Put a semi busy loop into proxy tunnels for IE problems
+ + Fixed handling of error pages for IO and Servlet exceptions
+ + updated extra/j2ee to jboss 3.2.1+
+ + Use File.toURI().toURL() when jdk 1.2 alternative is available.
+ + cookie timestamps are in GMT
+ + Priority on ThreadedServer
+ + replaced win32 service with http://wrapper.tanukisoftware.org
+ + Build fileclasspath from a walk of the classloaders
+ + Set TransactionManager on JettyPlus datasources and pools
+ + Fixed null pointer if no sevices configured for JettyPlus
+ + Fixed comments with embedded double dashes on jettyplus.xml file
+
+jetty-5.0.alpha2 - 19 September 2003
+ + Use commons logging.
+ + Use log4j if extra is present.
+ + Improved JMX start.
+ + Update jakarta examples
+ + Correctly setup context classloader in cross context dispatch.
+ + Turn off validation without non-xerces errors
+ + minor doco updates.
+ + moved mailing lists to sourceforge.
+ + Put a semi busy loop into proxy tunnels for IE problems
+ + MultipartRequest supports multi value headers.
+ + XML entity resolution uses URLs not Resources
+ + Implemented ServletRequestListeners as optional filter.
+ + Moved error page mechanism to be webapp only.
+ + Fixed error page handling of IO and Servlet exceptions.
+
+jetty-5.0.alpha1 - 12 August 2003
+ + Switched to mx4j
+ + Improve combinations of Security Constraints
+ + Implemented locale encoding mapping.
+ + Synced with 4.2.12
+ + Updated to Jasper 5.0.7
+ + Server javadoc from war
+
+jetty-5.0.alpha0 - 16 July 2003
+ + Compiled against 2.4 servlet spec.
+ + Implemented remote/local addr/port methods
+ + Updated authentication so that a normal Principal is used.
+ + updated to jasper 5.0.3
+ + Implemented setCharaterEncoding
+ + Implemented filter-mapping <dispatcher> element
+ + Implemented Dispatcher forward attributes.
+
+jetty-4.2.12 - 12 August 2003
+ + Restore max inactive interval for session manager
+ + Removed protection of org.mortbay.http attributes
+ + Fixed parameter ordering for a forward request.
+ + Fixed up HTAccessHandler
+ + Improved error messages from ProxyHandler
+ + Added missing S to some OPTIONS strings
+ + Added open method to threaded server.
+ + FORMAuthenticator does 403 with empty error page.
+ + Fixed MIME types for chemicals
+ + Padding for IE in RootNotFoundHandler
+
+jetty-4.2.11 - 12 July 2003
+ + Fixed race in servlet initialization code.
+ + Cookie params all in lower case.
+ + Simplified AJP13 connection handling.
+ + Prevent AJP13 from reordering query.
+ + Support separate Monitor class for start
+ + Branched for Jetty 5 development.
+
+jetty-4.2.10 - 07 July 2003
+ + Updates to JettyPlus documentation
+ + Updates to Jetty tutorial for start.jar, jmx etc
+
+jetty-4.2.10pre2 - 04 July 2003
+ + Improvement to JettyPlus config of datasources and connection pools
+ + Addition of mail service for JettyPlus
+ + Move to Service-based architecture for JettyPlus features
+ + Re-implementation of JNDI
+ + Many improvements in JettyPlus java:comp handling
+ + Allow multiple security-role-ref elements per servlet.
+ + Handle Proxy-Connection better
+ + Cleaned up alias handling.
+ + Confidential redirection includes query
+ + handle multiple security role references
+ + Fixed cookie handling for old cookies and safari
+ + Restricted ports in ProxyHandler.
+ + URI always encodes %
+ + Session statistics
+ + XmlConfiguration can get/set fields.
+
+jetty-4.2.10pre1 - 02 June 2003
+ + Fixed JSP code visibility problem introduced in Jetty-4.2.10pre0
+ + Added stop.jar
+ + Added SSO implementation for FORM authentication.
+ + WebApplicationContext does not reassign defaults descriptor value.
+ + Fixed AJP13 protocol so that request/response header enums are correct.
+ + Fixed form auth success redirect after retry, introduced in 4.2.9rc1
+ + Trace support is now optional (in AbstractHttpHandler).
+ + Deprecated forced chunking.
+ + Form authentication remembers URL over 403
+ + ProxyHandler has improved test for request content
+ + Removed support of org.mortbay.http.User role.
+ + Fixed problem with shared session for inter context dispatching.
+
+jetty-4.2.10pre0 - 05 May 2003
+ + Moved Log4JLogSink into JettyPlus
+ + Added ability to override jetty startup class by using -Djetty.server on
+   runline
+ + Incorporate JettyPlus jotm etc into build.
+ + Massive reorg of the CVS tree.
+ + Incorporate jetty extra and plus into build
+ + Integrate with JAAS
+ + Apply the append flag of RolloverFileOutputStream constructor.
+ + RolloverFileOutputStream manages Rollover thread.
+ + New look and feel for www site.
+ + Fixed table refs in JDBCUserRealm.
+ + Allow params in form auth URLs
+ + Updated to jasper jars from tomcat 4.1.24
+ + Allow query params in error page URL.
+ + ProxyHandler checks black and white lists for Connect.
+ + Merge multivalued parameters in dispatcher.
+ + Fixed CRLF bug in MultiPartRequest
+ + Warn if max form content size is reached.
+ + getAuthType returns CLIENT_CERT instead of CLIENT-CERT.
+ + getAuthType maps the HttpServletRequest final strings.
+ + FORM Authentication is serializable for session distribution.
+
+jetty-4.2.9 - 19 March 2003
+ + Conditional headers check after /dir to /dir/ redirection.
+
+jetty-4.2.9rc2 - 16 March 2003
+ + Fixed build.xml for source release
+ + Made rfc2068 PUT/POST Continues support optional.
+ + Defaults descriptor has context classloader set.
+ + Allow dispatch to j_security_check
+ + Added X-Forwarded-For header in ProxyHandler
+ + Updated included jmx jars
+
+jetty-4.2.9rc1 - 06 March 2003
+ + Work around URLClassloader not handling leading /
+ + Dump servlet can load resources for testing now.
+ + Added trust manager support to SunJsseListener.
+ + Added support for client certs to AJP13.
+ + Cleaned up includes
+ + Removed checking for single valued headers.
+ + Optional 2.4 behaviour for sessionDestroyed notification.
+ + Stop proxy url from doing user interaction.
+ + Turn request log buffering off by default.
+ + Reduced default context cache sizes (Total 1MB file 100KB).
+ + ProxyHandler has black and white host list.
+ + Added requestlog to HttpContext.
+ + Allow delegated creation of WebApplication derivations.
+ + Check Data contraints before Auth constraints
+
+jetty-4.2.8_01 - 18 February 2003
+ + Patched first release of 4.2.8 with correct version number
+ + Fixed CGI servlet to handle multiple headers.
+ + Added a SetResponseHeadersHandler, can set P3P headers etc.
+ + ProxyHandler can handle multiple cookies.
+ + Fixed AdminServlet to handle changed getServletPath better.
+ + Default servlet can have own resourceBase.
+ + Rolled back SocketChannelListener to 4.2.5 version
+ + Added option to resolve remote hostnames.  Defaults to off.
+ + Added MBeans for Servlets and Filters
+ + Moved ProxyHandler to the src1.4 tree
+
+jetty-4.2.7 - 04 February 2003
+ + Upgraded to JSSE 1.0.3_01 to fix security problem.
+ + Fixed proxy tunnel for non persistent connections.
+ + Relative sendRedirect handles trailing / correctly.
+ + Changed PathMap to conform to / getServletPath handling.
+
+jetty-4.2.6 - 24 January 2003
+ + Improved synchronization on AbstractSessionManager.
+ + Allow AJP13 buffers to be resized.
+ + Fixed LineInput problem with expanded buffers.
+ + ClientCertAuthentication updates request.
+ + Fixed rel sendRedirects for root context.
+ + Added HttpContext.setHosts to restrict context by real interface.
+ + Added MBeans for session managers
+ + Improved SocketChannelListener contributed.
+ + Added version to HttpServerMBean.
+
+jetty-4.2.5 - 14 January 2003
+ + Fixed pathParam bug for ;jsessionid
+ + Don't process conditional headers and ranges for includes
+ + Added Log4jSink in the contrib directory.
+ + Fixed requestedSessionId null bug.
+
+jetty-4.2.4 - 04 January 2003
+ + Fixed stop/start handling of servlet context
+ + Reuse empty LogSink slots.
+ + HTAccessHandler checks realm as well as htpassword.
+ + Clear context listeners after stop.
+ + Clear context attributes after stop.
+ + Use requestedSessionId as default session ID.
+ + Added MBeans for handlers
+ + Upgraded jasper to 4.1.18
+
+jetty-4.2.4rc0 - 12 December 2002
+ + Simplified ThreadedServer
+ + Use ThreadLocals for ByteArrayPool to avoid synchronization.
+ + Use Version to reset HttpFields
+ + Cheap clear for HttpFields
+ + Fixed setBufferSize NPE.
+ + Cleaned up some unused listener throws.
+ + Handle chunked form data.
+ + Allow empty host header.
+ + Avoid optional 100 continues.
+ + Limit form content size.
+ + Handle = in param values.
+ + Added HttpContext.flushCache
+ + Configurable root context.
+ + RootNotFoundHandler to help when no context found.
+ + Update jasper to 4.1.16beta
+ + Fixed dir listing from jars.
+ + Dir listings in UTF8
+ + Character encoding handling for GET requests.
+ + Removed container transfer encoding handling.
+ + Improved setBufferSize handling
+ + Code logs objects rather than strings.
+ + Better access to session manager.
+ + Fixed isSecure and getScheme for SSL over AJP13
+ + Improved ProxyHandler to the point is works well for non SSL.
+ + Implemented RFC2817 CONNECT in ProxyHandler
+ + Added gzip content encoding support to Default and ResourceHandler
+
+jetty-4.2.3 - 02 December 2002
+ + Removed aggressive threadpool shrinkage to avoid deadlock on SMP machines.
+ + Fixed some typos
+ + Added links to Jetty Powered page
+ + Clean up of ThreadedServer.stop()
+ + Updated bat scripts
+ + Added PKCS12Import class to import PKCS12 key directly
+ + removed old HttpContext.setDirAllowed()
+ + added main() to org.mortbay.http.Version
+ + Check form authentication config for leading /
+ + Cleaner servlet stop to avoid extra synchronization on handle
+ + org.mortbay.http.HttpContext.FileClassPathAttribute
+
+jetty-4.2.2 - 20 November 2002
+ + Fixed sendRedirect for non http URLS
+ + Fixed URI query recycling for persistent connections
+ + Fixed handling of empty headers
+ + Added EOFException to reduce log verbosity on closed connections.
+ + Avoided bad buffer status after closed connection.
+
+jetty-4.2.1 - 18 November 2002
+ + Fixed bad optimization in UrlEncoding
+ + Re-enabled UrlEncoding test harnesses
+
+jetty-4.2.0 - 16 November 2002
+ + Fixed AJP13 buffer size.
+ + Fixed remove listener bug.
+ + Fixed include of Invoker servlet.
+ + Restrict 304 responses to seconds time resolution.
+ + Use IE date formatting for speed.
+ + Removed jasper source and just include jars from 4.1.12
+ + Worked around JVM1.3 bug for JSPs
+ + Lowercase jsessionid for URLs only.
+ + Made NCSARequestLog easier to extend.
+ + Added definitions for RFC2518 WebDav response codes.
+ + Removed remaining non portable getBytes() calls
+ + Added upload demo to dump servlet.
+ + Many more optimizations.
+
+jetty-4.1.4 - 16 November 2002
+ + Fixed ContextLoader parent delegation bug
+ + Fixed remove SocketListener bug.
+ + Fixed Invoker servlet for RD.include
+ + Use IE date formatting for last-modified efficiency
+ + Last modified handling uses second resolution.
+ + Made NCSARequestLog simpler to extend.
+
+jetty-4.2.0rc1 - 02 November 2002
+ + Support default mime mapping defined by *
+ + Recycling of HttpFields class.
+ + Renamed Filter application methods.
+ + Fixed firstWrite after commit.
+ + Fixed ContextLoader parent delegation bug.
+ + Fixed problem setting the size of chunked buffers.
+ + Removed unused Servlet and Servlet-Engine headers.
+ + Fixed servletpath on invoker for named servlets.
+ + Fixed directory resource bug in JarFileResource.
+ + Improved handling of 2 byte encoded characters within forms.
+
+jetty-4.2.0rc0 - 24 October 2002
+ + Greg's birthday release!
+ + Added embedded iso8859 writer to HttpOutputStream.
+ + Removed duplicate classes from jar
+ + Fixed RolloverFileOutputStream without date.
+ + Fixed SessionManager initialization
+ + Added authenticator to admin.xml
+ + Fixed Session timeout NPE.
+
+jetty-4.1.3 - 24 October 2002
+ + Fixed RolloverFileOutputStream without date.
+ + Fixed SessionManager initialization
+ + Added authenticator to admin.xml
+ + Fixed Session timeout NPE.
+
+jetty-4.0.6 - 24 October 2002
+ + Clear interrupted status in ThreadPool
+ + Fixed forward query string handling
+ + fixed forward attribute handling for jsp-file servlets
+ + Fixed setCharacterEncoding to work with getReader
+ + Fixed handling of relative sendRedirect after forward.
+ + Fixed virtual hosts temp directories.
+
+jetty-4.2.0beta0 - 13 October 2002
+ + New ThreadPool implementation.
+ + New Buffering implementation.
+ + New AJP13 implementation.
+ + Removed Dispatcher dependancy on ServletHttpContext
+ + getNamedDispatcher(null) returns containers default servlet.
+ + unquote charset in content type
+ + Stop/Start filters in declaration order.
+ + Use "standard" names for default,jsp & invoker servlets.
+ + Fixed caching of directories to avoid shared buffers.
+ + Fixed bad log dir detection
+ + Fix Session invalidation bug
+ + Build without jmx
+ + 404 instead of 403 for WEB-INF requests
+ + FORM authentication sets 403 error page
+ + Allow %3B encoded ; in URLs
+ + Allow anonymous realm
+ + Update jasper to 4.1.12 tag
+
+jetty-4.1.2 - 13 October 2002
+ + Some AJP13 optimizations.
+ + getNamedDispatcher(null) returns containers default servlet.
+ + unquote charset in content type
+ + Stop/Start filters in declaration order.
+ + Use "standard" names for default,jsp & invoker servlets.
+ + Fixed caching of directories to avoid shared buffers.
+ + Fixed bad log dir detection
+ + Fix Session invalidation bug
+ + Build without jmx
+ + 404 instead of 403 for WEB-INF requests
+ + FORM authentication sets 403 error page
+ + Allow %3B encoded ; in URLs
+ + Allow anonymous realm
+ + Update jasper to 4.1.12 tag
+
+jetty-4.1.1 - 30 September 2002
+ + Fixed client scripting vulnerability with jasper2.
+ + Merged LimitedNCSARequestLog into NCSARequestLog
+ + Fixed space in resource name handling for jdk1.4
+ + Moved launcher/src to src/org/mortbay/start
+ + Fixed infinite recursion in JDBCUserRealm
+ + Avoid setting sotimeout for optimization.
+ + String comparison of If-Modified-Since headers.
+ + Touch files when expanding jars
+ + Deprecated maxReadTime.
+ + Cache directory listings.
+
+jetty-4.1.0 - 22 September 2002
+ + Fixed CGI+windows security hole.
+ + Fixed AJP13 handling of mod_jk loadbalancing.
+ + Stop servlets in opposite order to start.
+ + NCSARequest log buffered default
+ + WEB-INF/classes before WEB-INF/lib
+ + Sorted directory listings.
+ + Handle unremovable tempdir.
+ + Context Initparams to control session cookie domain, path and age.
+ + ClientCertAuthenticator protected from null subjectDN
+ + Added LimitedNCSARequestLog
+ + Use javac -target 1.2 for normal classes
+
+jetty-4.1.0RC6 - 14 September 2002
+ + Don't URL encode FileURLS.
+ + Improved HashUserRealm doco
+ + FormAuthenticator uses normal redirections now.
+ + Encode URLs of Authentication redirections.
+ + Added logon.jsp for no cookie form authentication.
+ + Extended Session API to pass request for jvmRoute handling
+ + Fixed problem with AJP 304 responses.
+ + Improved look and feel of demo
+ + Cleaned up old debug.
+ + Added redirect to welcome file option.
+
+jetty-4.1.0RC5 - 08 September 2002
+ + AJP13Listener caught up with HttpConnection changes.
+ + Added commandPrefix init param to CGI
+ + More cleanup in ThreadPool for idle death.
+ + Improved errors for misconfigured realms.
+ + Implemented security-role-ref for isUserInRole.
+
+jetty-4.1.0RC4 - 30 August 2002
+ + Included IbmJsseListener in the contrib directory.
+ + Updated jasper2 to 4.1.10 tag.
+ + Reverted to 302 for all redirections as all clients do not understand 303
+ + Created statsLock sync objects to avoid deadlock when stopping.
+
+jetty-4.1.0RC3 - 28 August 2002
+ + Fixed security problem for suffix matching with trailing "/"
+ + addWebApplications encodes paths to allow for spaces in file names.
+ + Improved handling of PUT,DELETE & MOVE.
+ + Improved handling of path encoding in Resources for bad JVMs
+ + Added buffering to request log
+ + Created and integrated the Jetty Launcher
+ + Made Resource canonicalize it's base path for directories
+ + Allow WebApplicationHandler to be used with other handlers.
+ + Added defaults descriptor to addWebApplications.
+ + Allow FORM auth pages to be within security constraint.
+
+jetty-4.1.0RC2 - 20 August 2002
+ + Conveninace setClassLoaderJava2Compliant method.
+ + Clear interrupted status in ThreadPool
+ + Fixed HttpFields cache overflow
+ + Improved ByteArrayPool to handle multiple sizes.
+ + Added HttpListener.bufferReserve
+ + Use system line separator for log files.
+ + Updated to Jasper2 (4_1_9 tag)
+ + Build ant, src and zip versions with the release
+
+jetty-4.1.0RC1 - 11 August 2002
+ + Fixed forward query string handling
+ + Fixed setCharacterEncoding to work with getReader
+ + Fixed getContext to use canonical contextPathSpec
+ + Improved the return codes for PUT
+ + Made HttpServer serializable
+ + Updated international URI doco
+ + Updated jasper to CVS snapshot 200208011920
+ + Fixed forward to jsp-file servlet
+ + Fixed handling of relative sendRedirect after forward.
+
+jetty-4.1.0RC0 - 31 July 2002
+ + Fixed getRealPath for packed war files.
+ + Changed URI default charset back to ISO_8859_1
+ + Restructured Password into Password and Credentials
+ + Added DigestAuthenticator
+ + Added link to a Jetty page in Korean.
+ + Added ExpiryHandler which can set a default Expires header.
+
+jetty-4.0.5 - 31 July 2002
+ + Fixed getRealPath for packed war files.
+ + Reversed order of ServletContextListener.contextDestroyed calls
+ + Fixed getRequestURI for RD.forward to return new URI.
+
+jetty-4.1.B1 - 19 July 2002
+ + Updated mini.http.jar target
+ + CGI Servlet, pass all HTTP headers through.
+ + CGI Servlet, catch and report program invocation failure status.
+ + CGI Servlet, fixed suffix mapping problem.
+ + CGI Servlet, set working directory for exec
+ + Support HTTP/0.9 requests again
+ + Reversed order of ServletContextListener.contextDestroyed calls
+ + Moved dynamic servlet handling to Invoker servlet.
+ + Moved webapp resource handling to Default servlet.
+ + Sessions create attribute map lazily.
+ + Added PUT,DELETE,MOVE support to webapps.
+ + Added 2.4 Filter dispatching support.
+
+jetty-3.1.9 - 15 July 2002
+ + Allow doHead requests to be forwarded.
+ + Fixed race in ThreadPool for minThreads <= CPUs
+
+jetty-4.1.B0 - 13 July 2002
+ + Added work around of JDK1.4 bug with NIO listener
+ + Moved 3rd party jars to $JETTY_HOME/ext
+ + Fixed ThreadPool bug when minThreads <= CPUs
+ + close rather than disable stream after forward
+ + Allow filter init to access servlet context methods.
+ + Keep notFoundContext out of context mapping lists.
+ + mod_jk FAQ
+ + Fixed close problem with load balancer.
+ + Stopped RD.includes closing response.
+ + RD.forward changes getRequestURI.
+ + NCSARequestLog can log to stderr
+
+jetty-4.1.D2 - 24 June 2002
+ + Support trusted external authenticators.
+ + Moved jmx classes from JettyExtra to here.
+ + Set contextloader during webapplicationcontext.start
+ + Added AJP13 listener for apache integration.
+ + Fixed ChunkableOutputStream close propagation
+ + Better recycling of HttpRequests.
+ + Protect session.getAttributeNames from concurrent modifications.
+ + Allow comma separated cookies and headers
+ + Back out Don't chunk 30x empty responses.
+ + Conditional header tested against welcome file not directory.
+ + Improved ThreadedServer stopping on bad networks
+ + Use ThreadLocals to avoid unwrapping in Dispatcher.
+
+jetty-4.0.4 - 23 June 2002
+ + Back out change: Don't chunk 30x empty responses.
+ + Conditional header tested against welcome file not directory.
+ + Improved ThreadedServer stopping on bad networks
+
+jetty-4.0.3 - 20 June 2002
+ + WebapplicationContext.start sets context loader
+ + Fixed close propagation of on-chunked output streams
+ + Force security disassociation.
+ + Better recycling of HttpRequests.
+ + Protect session.getAttributeNames from concurrent modifications.
+ + Allow session manager to be initialized when set.
+ + Fixed japanese locale
+ + Allow comma separated cookies and headers
+
+jetty-4.1.D1 - 08 June 2002
+ + Recycle servlet requests and responses
+ + Added simple buffer pool.
+ + Reworked output buffering to keep constant sized buffers.
+ + Don't chunk 30x empty responses.
+ + Fixed "" contextPaths in Dispatcher.
+ + Removed race for the starting of session scavaging
+ + Fixed /foo/../bar// bug in canonical path.
+ + Merged ResourceBase and SecurityBase into HttpContext
+
+jetty-4.0.2 - 06 June 2002
+ + Fixed web.dtd references.
+ + Fixed handler/context start order.
+ + Added OptimizeIt plug
+ + Fixed /foo/../bar// bug in canonical path.
+ + Don't chunk 30x empty responses.
+ + Fixed "" contextPaths in Dispatcher.
+ + Removed race for the starting of session scavaging
+
+jetty-3.1.8 - 06 June 2002
+ + Made SecurityConstraint.addRole() require authentication.
+ + Fixed singled threaded dynamic servlets
+ + Fixed no slash context redirection.
+ + Fixed /foo/../bar// bug in canonical path.
+
+jetty-4.1.D0 - 05 June 2002
+ + The 4.1 Series started looking for even more performance within the 2.3
+   specification.
+ + Removed the HttpMessage facade mechanism
+ + BRAND NEW WebApplicationHandler & WebApplicationContext
+ + Added TypeUtil to reduce Integer creation.
+ + General clean up of the API for for MBean getters/setters.
+ + Experimental CLIENT-CERT Authenticator
+ + Restructured ResourceHandler into ResourceBase
+ + Fixed web.dtd references.
+ + Fixed handler/context start order.
+ + Added OptimizeIt plug.
+
+jetty-4.0.1 - 22 May 2002
+ + Fixed contextclassloader on ServletContextEvents.
+ + Support graceful stopping of context and server.
+ + Fixed "null" return from getRealPath
+ + OutputStreamLogSink config improvements
+ + Updated jasper to 16 May snapshot
+
+jetty-4.0.1RC2 - 14 May 2002
+ + Better error for jre1.3 with 1.4 classes
+ + Cleaned up RD query string regeneration.
+ + 3DES Keylength was being reported as 0. Now reports 168 bits.
+ + Implemented the run-as servlet tag.
+ + Added confidential and integral redirections to HttpListener
+ + Fixed ServletResponse.reset() to resetBuffer.
+
+jetty-4.0.1RC1 - 29 April 2002
+ + Improved flushing of chunked responses
+ + Better handling if no realm configured.
+ + Expand ByteBuffer full limit with capacity.
+ + Fixed double filtering of welcome files.
+ + Fixed FORM authentication auth of login page bug.
+ + Fixed setTempDirectory creation bug
+ + Avoid flushes during RequestDispatcher.includes
+
+jetty-4.0.1RC0 - 18 April 2002
+ + Updated Jasper to CVS snapshot from Apr 18 18:50:59 BST 2002
+ + Pass pathParams via welcome file forward for jsessionid
+ + Extended facade interfaces to HttpResponse.sendError
+ + Moved basic auth handling to HttpRequest
+ + AbstractSessionManager sets contextClassLoader for scavanging
+ + Set thread context classloader for webapp load-on-startup inits
+ + Added extract arg to addWebApplications
+ + Fixed delayed response bug: Stopped HttpConnection consuming input from
+   timedout connection.
+ + DTD allows static "Get" and "Set" methods to be invoked.
+
+jetty-4.0.0 - 22 March 2002
+ + Updated tutorial configure version
+ + Added IPAddressHandler for IP restrictions
+ + Updated contributors.
+ + Minor documentation updates.
+ + Jetty.sh cygwin support
+
+jetty-4.0.RC3 - 20 March 2002
+ + Fixed ZZZ offset format to +/-HHMM
+ + Updated history
+ + JDBCUserRealm instantiates JDBC driver
+ + ContextInitialized notified before load-on-startup servlets.
+ + Suppress WriterOutputStream warning.
+ + Changed html attribute order for mozilla quirk.
+
+jetty-4.0.RC2 - 12 March 2002
+ + Fixed security constraint problem with //
+ + Fixed version for String XmlConfigurations
+ + Fixed empty referrer in NCSA log.
+ + Dont try to extract directories
+ + Added experimental nio SocketChannelListener
+ + Added skeleton load balancer
+ + Fixed column name in JDBCUserRealm
+ + Remove last of the Class.forName calls.
+ + Removed redundant sessionID check.
+ + Security FAQ
+ + Disabled the Password EXEC mechanism by default
+
+jetty-3.1.7 - 12 March 2002
+ + Fixed security problem with constraints being bypassed with // in URLs
+
+jetty-4.0.RC1 - 06 March 2002
+ + Added ContentEncodingHandler for compression.
+ + Fixed filter vs forward bug.
+ + Improved efficiency of quality list handling
+ + Simplified filter API to chunkable streams
+ + XmlParser is validating by default. use o.m.x.XmlParser.NotValidating
+   property to change.
+ + contextDestroyed event sent before destruction.
+ + Minor changes to make HttpServer work on J2ME CVM
+ + Warn if jdk 1.4 classes used on JVM <1.4
+ + WebApplication will use ContextLoader even without WEB-INF directory.
+ + FileResource depends less on FilePermissions.
+ + Call response.flushBuffer after service to flush wrappers.
+ + Empty suffix for temp directory.
+ + Contributors list as an image to prevent SPAM!
+ + Fixed recursive DEBUG loop in Logging.
+ + Updated jetty.sh to always respect arguments.
+
+jetty-3.1.6 - 28 February 2002
+ + Implemented 2.3 clarifications to security constraint semantics PLEASE
+   REVIEW YOUR SECURITY CONSTRAINTS (see README).
+ + Empty suffix for temp directory.
+ + Fixed HttpFields remove bug
+ + Set Listeners default scheme
+ + LineInput can handle any sized marks
+ + HttpResponse.sendError makes a better attempt at finding an error page.
+ + Dispatcher.forward dispatches directly to ServletHolder to avoid premature
+   exception handling.
+
+jetty-4.0.B2 - 25 February 2002
+ + Minor Jasper updates
+ + Improve handling of unknown URL protocols.
+ + Improved default jetty.xml
+ + Adjust servlet facades for welcome redirection
+ + User / mapping rather than /* for servlet requests to static content
+ + Accept jetty-web.xml or web-jetty.xml in WEB-INF
+ + Added optional JDK 1.4 src tree
+ + o.m.u.Frame uses JDK1.4 stack frame handling
+ + Added LoggerLogSink to direct Jetty Logs to JDK1.4 Log.
+ + Start ServletHandler as part of the FilterHandler start.
+ + Simplified addWebApplication
+ + Added String constructor to XmlConfiguration.
+ + Added org.mortbay.http.JDBCUserRealm
+ + Init classloader for JspServlet
+ + Slightly more agressive eating unused input from non persistent connection.
+
+jetty-4.0.B1 - 13 February 2002
+ + WriterOutputStream so JSPs can include static resources.
+ + Suppress error only for IOExceptions not derivitives.
+ + HttpConnection always eats unused bodies
+ + Merged HttpMessage and Message
+ + LineInput waits for LF after CF if seen CRLF before.
+ + Added setClassLoader and moved getFileClassPath to HttpContext
+ + Updated examples webapp from tomcat
+ + getRequestURI returns encoded path
+ + Servlet request destined for static content returns paths as default servlet
+
+jetty-4.0.B0 - 04 February 2002
+ + Implemented 2.3 security constraint semantics PLEASE REVIEW YOUR SECURITY
+   CONSTRAINTS (see README).
+ + Stop and remove NotFound context for HttpServer
+ + HttpContext destroy
+ + Release process builds JettyExtra
+ + Welcome files may be relative
+ + Fixed HttpFields remove bug
+ + Added Array element to XMLConfiguration
+ + Allow listener schemes to be set.
+ + Added index links to tutorial
+ + Renamed getHttpServers and added setAnonymous
+ + Updated crimson to 1.1.3
+ + Added hack for compat tests in watchdog for old tomcat stuff
+ + Added AbstractSessionManager
+ + Support Random Session IDs in HashSessionManager.
+ + Common handling of TRACE
+ + Updated tutorial and FAQ
+ + Reduce object count and add hash width to StringMap
+ + Factor out RolloverFileOutputStream from OutputStreamLogSink
+ + Remove request logSink and replace with RequestLog using
+   RolloverFileOutputStream
+ + Handle special characters in resource file names better.
+ + Welcome file dispatch sets requestURI.
+ + Removed triggers from Code.
+
+jetty-4.0.D4 - 14 January 2002
+ + Prevent output after forward
+ + Handle ServletRequestWrappers for Generic Servlets
+ + Improved handling of UnavailableException
+ + Extract WAR files to standard temp directory
+ + URI uses UTF8 for % encodings.
+ + Added BlueRibbon campaign.
+ + RequestDispatcher uses cached resources for include
+ + Improved HttpResponsse.sendError error page matching.
+ + Fixed noaccess auth demo.
+ + FORM auth caches UserPrincipal
+ + Added isAuthenticated to UserPrincipal
+
+jetty-4.0.D3 - 31 December 2001
+ + Fixed cached filter wrapping.
+ + Fixed getLocale again
+ + Patch jasper to 20011229101000
+ + Removed limits on mark in LineInput.
+ + Corrected name to HTTP_REFERER in CGI Servlet.
+ + Fixed UrlEncoding for % + combination.
+ + Generalized temp file handling
+ + Fixed ContextLoader lib handling.
+ + DateCache handles misses better.
+ + HttpFields uses DateCache more.
+ + Moved admin port to 8081 to avoid JBuilder
+ + Made Frame members private and fixed test harness
+ + cookies with maxAge==0 expire on 1 jan 1970
+ + setCookie always has equals
+
+jetty-3.1.5 - 11 December 2001
+ + setCookie always has equals for cookie value
+ + cookies with maxage==0 expired 1 jan 1970
+ + Fixed formatting of redirectURLs for NS4.08
+ + Fixed ChunableInputStream.resetStream bug.
+ + Ignore IO errors when trying to persist connections.
+ + Allow POSTs to static resources.
+ + stopJob/killStop in ThreadPool to improve stopping ThreadedServer on some
+   platforms.
+ + Branched at Jetty_3_1
+
+jetty-4.0.D2 - 02 December 2001
+ + Removed most of the old doco, which needs to be rewritten and added again.
+ + Restructured for demo and test hierarchies
+ + Fixed formatting of redirect URLs.
+ + Removed ForwardHandler.
+ + Removed Demo.java (until updated).
+ + Made the root context a webapplication.
+ + Moved demo docroot/servlets to demo directory
+ + added addWebApplications auto discovery
+ + Disabled last forwarding by setPath()
+ + Removed Request set methods (will be replaced)
+ + New event model to decouple from beans container.
+ + Better handling of charset in form encoding.
+ + Allow POSTs to static resources.
+ + Fixed ChunableInputStream.resetStream bug.
+ + Ignore IO errors when trying to persist connections.
+ + stopJob/killStop in ThreadPool to improve stopping ThreadedServer on some
+   platforms.
+
+jetty-4.0.D1 - 14 November 2001
+ + Fixed ServletHandler with no servlets
+ + Fixed bug with request dispatcher parameters
+ + New ContextLoader implementation.
+ + New Dispatcher implementation
+ + Added Context and Session Event Handling
+ + Added FilterHolder
+ + Added FilterHandler
+ + Changed HandlerContext to HttpContext
+ + Simplified ServletHandler
+ + Removed destroy methods
+ + Simplified MultiMap
+
+jetty-4.0.D0 - 06 November 2001
+ + Branched from Jetty_3_1 == Jetty_3_1_4
+ + 2.3 Servlet API
+ + 1.2 JSP API
+ + Jasper from tomcat4
+ + Start SessionManager abstraction.
+ + Added examples webapp from tomcat4
+ + Branched at Jetty_3_1
+
+jetty-3.1.4 - 06 November 2001
+ + Added RequestLogFormat to allow extensible request logs.
+ + Support the ZZZ timezone offset format in DateCache
+ + HTAccessHandler made stricter on misconfiguration
+ + Generate session unbind events on a context.stop()
+ + Default PathMap separator changed to ":,"
+ + PathMap now ignores paths after ; or ? characters.
+ + Remove old stuff from contrib that had been moved to extra
+ + getRealPath accepts \ URI separator on platforms using \ file separator.
+
+jetty-3.1.3 - 26 October 2001
+ + Fix security problem with trailing special characters. Trailing %00 enabled
+   JSP source to be viewed or other servlets to be bypassed.
+ + Fixed several problems with external role authentication. Role
+   authentication in JBoss was not working correctly and there were possible
+   object leaks. The fix required an API change to UserPrinciple and UserRealm.
+ + Allow a per context UserRealm instance.
+ + Upgraded JSSE to 1.0.2
+ + Improved FORM auth handling of role failure.
+ + Improved Jasper debug output.
+ + Improved ThreadedServer timeout defaults
+ + Fixed binary files in CVS
+ + Fixed Virtual hosts to case insensitive.
+ + PathMap spec separator changed from ',' to ':'. May be set with
+   org.mortbay.http.PathMap.separators system property.
+ + Correct dispatch to error pages with javax attributes set.
+
+jetty-3.1.2 - 13 October 2001
+ + Fixed double entry on PathMap.getMatches
+ + Fixed servlet handling of non session url params.
+ + Fixed attr handling in XmlParser.toString
+ + Fixed request log date formatting
+ + Fixed NotFoundHandler handling of unknown methods
+ + Fixed FORM Authentication username.
+ + Fixed authentication role handling in FORM auth.
+ + FORM authentication passes query params.
+ + Added short delay to shutdown hook for JVM bug.
+ + Added ServletHandler.sessionCount()
+ + Added run target to ant
+ + Changed 304 responses for Opera browser.
+ + Changed JSESSIONID to jsessionid
+ + Log OK state after thread low warnings.
+ + Changed unsatisfiable range warnings to debug.
+ + Further improvements in handling of shutdown.
+
+jetty-3.1.1 - 27 September 2001
+ + Fixed jar manifest format - patched 28 Sep 2001
+ + Removed JDK 1.3 dependancy
+ + Fixed ServletRequest.getLocale().
+ + Removed incorrect warning for WEB-INF/lib jar files.
+ + Handle requestdispatcher during init.
+ + Use lowercase tags in html package to be XHTML-like.
+ + Correctly ignore auth-constraint descriptions.
+ + Reduced verbosity of bad URL errors from IIS virus attacks
+
+jetty-3.1.0 - 21 September 2001
+ + Added long overdue Tutorial documentation.
+ + Improved some other documentation.
+ + Fix ResourceHandler cache invalidate.
+ + Fix ServletResponse.setLocale()
+ + Fix reuse of Resource
+ + Fix Jetty.bat for spaces.
+ + Fix .. handling in URI
+ + Fix REFFERER in CGI
+ + Fix FORM authentication on exact patterns
+ + Fix flush on stop bug in logs.
+ + Fix param reading on CGI servlet
+ + New simplified jetty.bat
+ + Improved closing of listeners.
+ + Optimized List creation
+ + Removed win32 service.exe
+ + Added HandlerContext.registerHost
+
+jetty-3.1.rc9 - 02 September 2001
+ + Added bin/orgPackage.sh script to change package names.
+ + Changed to org.mortbay domain names.
+ + Form auth login and error pages relative to context path.
+ + Fixed handling of rel form authentication URLs
+ + Added support for Nonblocking listener.
+ + Added lowResourcePersistTimeMs for more graceful degradation when we run out
+   of threads.
+ + Patched Jasper to 3.2.3.
+ + Added handlerContext.setClassPaths
+ + Fixed bug with non cookie sessions.
+ + Format cookies in HttpFields.
+
+jetty-3.1.rc8 - 22 August 2001
+ + Support WEB-INF/web-jetty.xml configuration extension for webapps
+ + Allow per context log files.
+ + Updated sponsors page
+ + Added HttpServer statistics
+ + Don't add notfound context.
+ + Many major and minor optimizations:
+ + ISO8859 conversion
+ + Buffer allocation
+ + URI pathAdd
+ + StringMap
+ + URI canonicalPath
+ + OutputStreamLogSink replaces WriterLogSink
+ + Separation of URL params in HttpHandler API.
+ + Fixed handling of default mime types
+ + Allow contextpaths without leading /
+ + Removed race from dynamic servlet initialization.
+
+jetty-3.1.rc7 - 09 August 2001
+ + Fix bug in sendRedirect for HTTP/1.1
+ + Added doco for Linux port redirection.
+ + Don't persist connections if low on threads.
+ + Added shutdown hooks to Jetty.Server to trap Ctl-C
+ + Fixed bug with session ID generation.
+ + Added FORM authentication.
+ + Remove old context path specs
+ + Added UML diagrams to Jetty architecture documentation.
+ + Use Enumerations to reduce conversions for servlet API.
+ + Optimized HttpField handling to reduce object creatiyon.
+ + ServletRequest SSL attributes in line with 2.2 and 2.3 specs.
+ + Dump Servlet displays cert chains
+ + Fixed redirect handling by the CGI Servlet.
+ + Fixed request.getPort for redirections from 80
+ + Added utility methods to ServletHandler for wrapping req/res pairs.
+ + Added method handling to HTAccessHandler.
+ + ServletResponse.sendRedirect puts URLs into absolute format.
+
+jetty-3.1.rc6 - 10 July 2001
+ + Avoid script vulnerability in error pages.
+ + Close persistent HTTP/1.0 connections on missing Content-Length
+ + Use exec for jetty.sh run
+ + Improved SSL debugging information.
+ + KeyPairTool can now load cert chains.
+ + KeyPairTool is more robust to provider setup.
+ + Fixed bug in B64Code. Optimised B64Code.
+ + Added Client authentication to the JsseListener
+ + Fixed a problem with Netscape and the acrobat plugin.
+ + Improved debug output for IOExceptions.
+ + Updated to JSSE-1.0.2, giving full strength crypto.
+ + Win32 Service uses Jetty.Server instead of HttpServer.
+ + Added getResource to HandleContext.
+ + WebApps initialize resourceBase before start.
+ + Fixed XmlParser to handle xerces1.3 OK
+ + Added Get element to the XmlConfiguration class.
+ + Added Static calls to the XmlConfiguration class.
+ + Added debug and logging config example to demo.xml
+ + Moved mime types and encodings to property bundles.
+ + RequestDispatch.forward() uses normal HandlerContext.handle() path if
+   possible.
+ + Cleaned up destroy handling of listeners and contexts.
+ + Removed getConfiguration from LifeCycleThread to avoid JMX clash.
+ + Cleaned up Win32 Service server creation.
+ + Moved gimp image files to Jetty3Extra
+
+jetty-3.1.rc5 - 01 May 2001
+ + Added build target for mini.jetty.jar - see README.
+ + Major restructing of packages to separate servlet dependancies. c.m.XML  -
+   moved XML dependant classes from c.m.Util c.m.HTTP - No servlet or XML
+   dependant classes: c.m.Jetty.Servlet - moved from c.m.HTTP.Handler.Servlet
+   c.m.Servlet - received some servlet dependant classes from HTTP.
+ + Added UnixCrypt support to c.m.U.Password
+ + Added HTaccessHandler to authenitcate against apache .htaccess files.
+ + Added query param handling to ForwardHandler
+ + Added ServletHandler().setUsingCookies().
+ + Optimized canonical path calculations.
+ + Warn and close connections if content-length is incorrectly set.
+ + Request log contains bytes actually returned.
+ + Fixed handling of empty responses at header commit.
+ + Fixed ResourceHandler handling of ;JSESSIONID
+ + Fixed forwarding to null pathInfo requests.
+ + Fixed handling of multiple cookies.
+ + Fixed EOF handling in MultiPartRequest.
+ + Fixed sync of ThreadPool idleSet.
+ + Fixed jetty.bat classpath problems.
+
+jetty-3.0.6 - 26 April 2001
+ + Fixed handling of empty responses at header commit.
+ + Fixed ResourceHandler handling of ;JSESSIONID
+ + Fixed forwarding to null pathInfo requests.
+ + Fixed EOF handlding in MultiPartRequest.
+ + Fixed sync of ThreadPool idleSet.
+ + Load-on-startup the JspServlet so that precompiled servlets work.
+
+jetty-3.1.rc4 - 14 April 2001
+ + Include full versions of JAXP and Crimson
+ + Added idle thread getter to ThreadPool.
+ + Load-on-startup the JspServlet so that precompiled servlets work.
+ + Removed stray debug println from the Frame class.
+
+jetty-3.0.5 - 14 April 2001
+ + Branched from 3.1 trunk to fix major errors
+ + Fixed LineInput bug EOF
+ + Improved flush ordering for forwarded requests.
+ + Turned off range handling by default until bugs resolved
+ + Don't chunk if content length is known.
+ + fixed getLocales handling of quality params
+ + Created better random session ID
+ + Resource handler strips URL params like JSESSION.
+ + Fixed session invalidation unbind notification to conform with spec
+ + Load-on-startup the JspServlet so that precompiled servlets work.
+
+jetty-3.1.rc3 - 09 April 2001
+ + Implemented multi-part ranges so that acrobat is happy.
+ + Simplified multipart response class.
+ + Improved flush ordering for forwarded requests.
+ + Improved ThreadPool stop handling
+ + Frame handles more JIT stacks.
+ + Cleaned up handling of exceptions thrown by servlets.
+ + Handle zero length POSTs
+ + Start session scavenger if needed.
+ + Added ContentHandler Observer to XmlParser.
+ + Allow webapp XmlParser to be observed for ejb-ref tags etc.
+ + Created better random session ID
+
+jetty-3.1.rc2 - 30 March 2001
+ + Lifecycle.start() may throw Exception
+ + Added MultiException to throw multiple nested exceptions.
+ + Improved logging of nested exceptions.
+ + Only one instance of default MIME map.
+ + Use reference JAXP1.1 for XML parsing.y
+ + Version 1.1 of configuration dtd supports New objects.
+ + Improved handling of Primitive classes in XmlConfig
+ + Renamed getConnection to getHttpConnection
+ + fixed getLocales handling of quality params
+ + fixed getParameter(name) handling for multiple values.
+ + added options to turn off ranges and chunking to support acrobat requests.
+
+jetty-3.1.rc1 - 18 March 2001
+ + Moved JMX and SASL handling to Jetty3Extra release
+ + Fixed problem with ServletContext.getContext(uri)
+ + Added Jetty documentation pages from JettyWiki
+ + Cleaned up build.xml script
+ + Minimal handling of Servlet.log before initialization.
+ + Various SSL cleanups
+ + Resource handler strips URL params like JSESSION.
+
+jetty-3.1.rc0 - 23 February 2001
+ + Added JMX management framework.
+ + Use Thread context classloader as default context loader parent.
+ + Fixed init order for unnamed servlets.
+ + Fixed session invalidation unbind notification to conform with spec
+ + Improved handling of primitives in utilities.
+ + Socket made available via HttpConnection.
+ + Improved InetAddrPort and ThreadedServer to reduce DNS lookups.
+ + Dynamic servlets may be restricted to Context classloader.
+ + Reoganized packages to allowed sealed Jars
+ + Changed getter and setter methods that did not conform to beans API.
+
+jetty-3.0.4 - 23 February 2001
+ + Fixed LineInput bug with split CRLF.
+
+jetty-3.0.3 - 03 February 2001
+ + Fixed pipelined request buffer bug.
+ + Handle empty form content without exception.
+ + Allow Log to be disabled before initialization.
+ + Included new Jetty Logo
+ + Implemented web.xml servlet mapping to a JSP
+ + Fixed handling of directories without trailing /
+
+jetty-3.0.2 - 13 January 2001
+ + Replaced ResourceHandler FIFO cache with LRU cache.
+ + Greatly improved buffering in ChunkableOutputStream
+ + Padded error bodies for IE bug.
+ + Improved HTML.Block efficiency
+ + Improved jetty.bat
+ + Improved jetty.sh
+ + Handle unknown status reasons in HttpResponse
+ + Ignore included response updates rather than IllegalStateException
+ + Removed classloading stats which were causing circular class loading
+   problems.
+ + Allow '+' in path portion of a URL.
+ + Try ISO8859_1 encoding if can't find ISO-8859-1
+ + Restructured demo site pages.
+ + Context specific security permissions.
+ + Added etc/jetty.policy as example policy file.
+
+jetty-3.0.1 - 20 December 2000
+ + Fixed value unbind notification for session invalidation.
+ + Removed double null check possibility from ServletHolder
+
+jetty-3.0.0 - 17 December 2000
+ + Improved jetty.sh logging
+ + Improved dtd resolution in XML parser.
+ + Fixed taglib parsing
+ + Fixed rel path handling in default configurations.
+ + Optional extract war files.
+ + Fixed WriterLogSink init bug
+ + Use inner class to avoid double null check sync problems
+ + Fixed rollover bug in WriterLogSink
+
+jetty-3.0.0.rc8 - 13 December 2000
+ + Optional alias checking added to FileResource.  Turned on by default on all
+   platforms without the "/" file separator.
+ + Mapped *.jsp,*.jsP,*.jSp,*.jSP,*.Jsp,*.JsP,*.JSp,*.JSP
+ + Tidied handling of ".", ".." and "//" in resource paths
+ + Protected META-INF as well as WEB-INF in web applications.
+ + Jetty.Server catches init exceptions per server
+ + getSecurityHandler creates handler at position 0.
+ + SysV unix init script
+ + Improved exit admin handling
+ + Change PathMap handling of /* to give precedence over suffix mapping.
+ + Forward to welcome pages rather than redirect.
+ + Removed special characters from source.
+ + Default log options changed if in debug mode.
+ + Removed some unused variables.
+ + Added ForwardHandler
+ + Removed security constraint on demo admin server.
+ + Patched jasper to tomcat 3.2.1
+
+jetty-3.0.0.rc7 - 02 December 2000
+ + Fixed security problem with lowercase WEB-INF uris on windows.
+ + Extended security constraints (see README and WebApp Demo).
+ + Set thread context classloader during handler start/stop calls.
+ + Don't set MIME-Version in response.
+ + Allow dynamic servlets to be served from /
+ + Handle multiple inits of same servlet class.
+ + Auto add a NotFoundHandler if needed.
+ + Added NotFoundServlet
+ + Added range handling to ResourceHandler.
+ + CGI servlet handles not found better.
+ + WEB-INF protected by NotFoundServlet rather than security constraint.
+ + PUT, MOVE disabled in WebApplication unless defaults file is passed.
+ + Conditionals apply to puts, dels and moves in ResourceHandler.
+ + URIs accept all characters < 0xff.
+ + Set the AcceptRanges header.
+ + Depreciated RollOverLogSink and moved functionality to an improved
+   WriterLogSink.
+ + Changed log options to less verbose defaults.
+ + ThreadedServer.forceStop() now makes a connection to itself to handle
+   non-premptive close.
+ + Double null lock checks use ThreadPool.__nullLockChecks.
+ + Split Debug servlet out of Admin Servlet.
+ + Added Com.mortbay.HTTP.Handler.Servlet.Context.LogSink attribute to Servlet
+   Context. If set, it is used in preference to the system log.
+
+jetty-3.0.0.rc6 - 20 November 2000
+ + RequestDispatcher.forward() only resets buffer, not headers.
+ + Added ServletWriter that can be disabled.
+ + Resource gets systemresources from it's own classloader.
+ + don't include classes in release.
+ + Allow load-on-startup with no content.
+ + Fixed RollOverFileLogSink bug with extra log files.
+ + Improved Log defaults
+ + Don't start HttpServer log sink on add.
+ + Admin servlet uses unique links for IE.
+ + Added Win32 service support
+ + Reduced risk of double null check sync problem.
+ + Don't set connection:close for normal HTTP/1.0 responses.
+ + RequestDispatcher new queries params replace old.
+ + Servlet init order may be negative.
+ + Corrected a few of the many spelling mistakes.
+ + Javadoc improvements.
+ + Webapps serve dynamics servlets by default.
+ + Warn for missing WEB-INF or web.xml
+ + Sessions try version 1 cookies in set-cookie2 header.
+ + Session cookies are given context path
+ + Put extra server and servlet info in header.
+ + Version details in header can be suppressed with System property
+   java.com.mortbay.HTTP.Version.paranoid
+ + Prevent reloading dynamic servlets at different paths.
+ + Implemented resource aliases in HandlerContext - used by Servlet Context
+ + Map tablib configuration to resource aliases.
+ + Implemented customizable error pages.
+ + Simple stats in ContextLoader.
+ + Allow HttpMessage state to be manipulated.
+ + Allow multiple set cookies.
+
+jetty-3.0.0.rc5 - 12 November 2000
+ + Default writer encoding set by mime type if not explicitly set.
+ + Relax webapp rules, accept no web.xml or no WEB-INF
+ + Pass flush through ServletOut
+ + Avoid jprobe race warnings in DateCache
+ + Allow null cookie values
+ + Servlet exceptions cause 503 unavailable rather than 500 server error
+ + RequestDispatcher can dispatch static resources.
+ + Merged DynamicHandler into ServletHandler.
+ + Added debug form to Admin servlet.
+ + Implemented servlet load ordering.
+ + Moved JSP classpath hack to ServletHolder
+ + Removed Makefile build system.
+ + Many javadoc cleanups.
+
+jetty-2.4.9 - 12 November 2000
+ + HttpListener ignore InterruptedIOExceptions
+ + HttpListener default max idle time = 20s
+ + HtmlFilter handles non default encodings
+ + Writing HttpRequests encodes path
+ + HttpRequest.write uses ISO8859_1 encoding.
+
+jetty-3.0.0.rc4 - 06 November 2000
+ + Provide default JettyIndex.properties
+ + Fixed mis-synchronization in ThreadPool.stop()
+ + Fixed mime type mapping bug introduced in RC3
+ + Ignore more IOExceptions (still visible with debug).
+
+jetty-3.0.0.rc3 - 05 November 2000
+ + Changed ThreadPool.stop for IBM 1.3 JVM
+ + Added bin/jetty.sh run script.
+ + upgraded build.xml to ant v1.2
+ + Set MaxReadTimeMs in all examples
+ + Further clean up of the connection close actions
+ + Moved unused classes from com.mortbay.Util to com.mortbay.Tools in new
+   distribution package.
+ + Handle mime suffixes containing dots.
+ + Added gz tgz tar.gz .z mime mappings.
+ + Fixed default mimemap initialization bug
+ + Optimized persistent connections by recycling objects
+ + Added HandlerContext.setHttpServerAccess for trusted contexts.
+ + Set the thread context class loader in HandlerContext.handle
+ + Prevent servlet setAttribute calls to protected context attributes.
+ + Removed redundant context attributes.
+ + Implemented mime mapping in webapplications.
+ + Strip ./ from relative resources.
+ + Added context class path dynamic servlet demo
+
+jetty-3.0.0.rc2 - 29 October 2000
+ + Replaced ISO-8859-1 literals with StringUtil static
+ + Pass file based classpath to JspServlet (see README).
+ + Prevented multiple init of ServletHolder
+ + ErlEncoding treats params without values as empty rather than null.
+ + Accept public DTD for XmlConfiguration (old style still supported).
+ + Cleaned up non persistent connection close.
+ + Accept HTTP/1. as HTTP/1.0 (for netscape bug).
+ + Fixed thread name problem in ThreadPool
+
+jetty-3.0.0.rc1 - 22 October 2000
+ + Added simple admin servlet.
+ + Added CGI to demo
+ + Added HashUserRealm and cleaned up security constraints
+ + Added Multipart request and response classes from Jetty2
+ + Moved and simplified ServletLoader to ContextLoader.
+ + Initialize JSP with classloader.
+ + All attributes in javax. java. and com.mortbay. name spaces to be set.
+ + Partial handling of 0.9 requests.
+ + removed Thread.destroy() calls.
+ + Cleaned up exception handling.
+
+jetty-2.4.8 - 23 October 2000
+ + Fixed bug with 304 replies with bodies.
+ + Improved win32 make files.
+ + Fixed closing socket problem
+
+jetty-3.0.B05 - 18 October 2000
+ + Improved null returns to get almost clean watchdog test.
+ + Cleaned up response committing and flushing
+ + Handler RFC2109 cookies (like any browser handles them!)
+ + Added default webapp servlet mapping /servlet/name/*
+ + Improved path spec interpretation by looking at 2.3 spec
+ + Implemented security-role-ref for servlets
+ + Protected servletConfig from downcast security problems
+ + Made test harnesses work with ant.
+ + improved ant documentation.
+ + Removed most deprecation warnings
+ + Fixed JarFileResource to handle jar files without directories.
+ + Implemented war file support
+ + Java2 style classloading
+ + Improved default log format for clarity.
+ + Separated context attributes and initParams.
+
+jetty-3.0.B04 - 12 October 2000
+ + Restricted context mapping to simple model for servlets.
+ + Fixed problem with session ID in paths
+ + Added modified version of JasperB3.2 for JSP
+ + Moved FileBase to docroot
+ + Merged and renamed third party jars.
+ + Do not try multiple servlets for a request.
+ + Implemented Context.getContext(uri)
+ + Added webdefault.xml for web applications.
+ + Redirect to index files, so index.jsp works.
+ + Filthy hack to teach jasper JspServer Jetty classpath
+
+jetty-3.0.B03 - 09 October 2000
+ + Expanded import package.*; lines
+ + Expanded leading tabs to spaces
+ + Improved Context to Handler contract.
+ + Parse but not handler startup ordering in web applications.
+ + Send request log via a LogSink
+ + Added append mode in RolloverFileLogSink
+ + Made LogSink a Lifecycle interface
+ + Improved handler toString
+ + Redirect context only paths.
+ + Pass object to LogSink
+ + Implemented request dispatching.
+ + Redo dynamic servlets handling
+ + Improved Log rollover.
+ + Simplified path translation and real path calculation.
+ + Catch stop and destroy exceptions in HttpServer.stop()
+ + Handle ignorable spaces in XmlConfiguration
+ + Handle ignorable spaces in WebApplication
+ + Warn about explicit sets of WebApplication
+ + Remove 411 checks as IE breaks this rule after redirect.
+ + Removed last remnants JDK 1.1 support
+ + Added release script
+
+jetty-2.4.7 - 06 October 2000
+ + Allow Objects to be passed to LogSink
+ + Set content length on errors for keep alive.
+ + Added encode methods to URI
+ + Improved win32 build
+ + fixes to SSL doco
+ + Support key and keystore passwords
+ + Various improvements to  ServletDispatch, PropertyTree and associated
+   classes.
+
+jetty-3.0.B02 - 24 August 2000
+ + Fixed LineInput bug with SSL giving CR pause LF.
+ + Fixed HTTP/1.0 input close bug
+ + Fixed bug in TestRFC2616
+ + Improved ThreadedServer stop and destroy
+ + Use resources in WebApplication
+ + Added CGI servlet
+
+jetty-3.0.B01 - 21 August 2000
+ + SSL implemented with JsseListener
+ + Partial implementation of webapp securitycontraints
+ + Implemented more webapp configuration
+ + Switched to the aelfred XML parser from microstar, which is only partially
+   validating, but small and lightweight
+
+jetty-2.4.6 - 16 August 2000
+ + Turn Linger off before closing sockets, to allow restart.
+ + JsseListener & SunJsseListener added and documented
+ + com.mortbay.Util.KeyPairTool added to handle openSSL SSL keys.
+ + Minor changes to compile with jikes.
+ + Added passive mode methods to FTP
+
+jetty-3.0.A99 - 10 August 2000
+ + Implemented jetty.xml configuration
+ + Added Xmlconfiguration utility
+ + ServletLoader simplied and uses ResourcePath
+ + Replaced FileHandler with ResourceHandler
+ + Use SAX XML parsing instead of DOM for space saving.
+ + Removed FileBase. Now use ResourceBase instead
+ + Added Resource abstraction
+ + Make it compile cleanly with jikes.
+ + Re-added commented out imports for JDK-1.1 compile
+
+jetty-3.0.A98 - 20 July 2000
+ + Implemented Jetty demos and Site as Web Application.
+ + Implemented WebApplicationContext
+ + Switched to JDK1.2 only
+ + ServletRequest.getServerPort() returns 80 rather than 0
+ + Fixed constructor to RolloverFileLogSink
+ + Improved synchronization on LogSink
+ + Allow HttpRequest.toString() handles bad requests.
+
+jetty-3.0.A97 - 13 July 2000
+ + Tempory request log implementation
+ + Less verbose debug
+ + Better tuned SocketListener parameters
+ + Started RequestDispatcher implementation.
+ + Added WML mappings
+ + Fixed makefiles for BSD ls
+ + Fixed persistent commits with no content (eg redirect+keep-alive).
+ + Implemented servlet isSecure().
+ + Implemented servlet getLocale(s).
+ + Formatted version in server info string.
+ + Protect setContentLength from a late set in default servlet HEAD handling.
+ + Added error handling to LifeCycleThread
+ + implemented removeAttribute on requests
+
+jetty-2.4.5 - 09 July 2000
+ + Don't mark a session invalid until after values unbound.
+ + Formatted version in server info.
+ + Added HtmlExpireFilter and removed response cache revention from HtmlFilter.
+ + Fixed transaction handling in JDBC wrappers
+
+jetty-3.0.A96 - 27 June 2000
+ + Fixed bug with HTTP/1.1 Head reqests to servlets.
+ + Supressed un-needed chunking EOF indicators.
+
+jetty-3.0.A95 - 24 June 2000
+ + Fixed getServletPath for default "/"
+ + Handle spaces in file names in FileHandler.
+
+jetty-3.0.A94 - 19 June 2000
+ + Implemented Sessions.
+ + PathMap exact matches can terminate with ; or # for URL sessions and
+   targets.
+ + Added HandlerContext to allow grouping of handlers into units with the same
+   file, resource and class configurations.
+ + Cleaned up commit() and added complete() to HttpResponse
+ + Updated license to clarify that commercial usage IS OK!
+
+jetty-3.0.A93 - 14 June 2000
+ + Major rethink! Moved to 2.2 servlet API
+ + Lots of changes and probably unstable
+
+jetty-3.0.A92 - 07 June 2000
+ + Added HTML classes to jar
+ + Fixed redirection bug in FileHandler
+
+jetty-2.4.4 - 03 June 2000
+ + Many debug call optimizations
+ + Added RolloverFileLogSink
+ + Improved LogSink configuration
+ + Support System.property expansions in PropertyTrees.
+ + Added uk.org.gosnell.Servlets.CgiServlet to contrib
+ + HttpRequest.setRequestPath does not null pathInfo.
+ + BasicAuthHandler uses getResourcePath so it can be used behind request
+   dispatching
+ + Added HTML.Composite.replace
+ + FileHandler implements IfModifiedSince on index files.
+ + Added build-win32.mak
+
+jetty-3.0.A91 - 03 June 2000
+ + Improved LogSink mechanism
+ + Implemented realPath and getResource methods for servlets.
+ + Abstracted ServletHandler
+ + Simplified HttpServer configuration methods and arguments
+ + Simplified class loading
+ + Added HTML classes from Jetty2
+
+jetty-3.0.A9 - 07 May 2000
+ + Improvided finally handling of output end game.
+ + Fixed double chunking bug in SocketListener.
+ + File handler checks modified headers on directory indexes.
+ + ServletLoader tries unix then platform separator for zip separator.
+
+jetty-3.0.A8 - 04 May 2000
+ + Servlet2_1 class loading re-acrchitected. See README.
+ + Moved Sevlet2_1 handler to com.mortbay.Servlet2_1
+ + addCookie takes an int maxAge rather than a expires date.
+ + Added LogSink extensible log architecture.
+ + Code.ignore only outputs when debug is verbose.
+ + Added Tenlet class for reverse telnet.
+
+jetty-2.4.3 - 04 May 2000
+ + Pass Cookies with 0 max age to browser.
+ + Allow CRLF in UrlEncoded
+
+jetty-2.4.2 - 23 April 2000
+ + Added LogSink and FileLogSink classes to allow extensible Log handling.
+ + Handle nested RequestDispatcher includes.
+ + Modified GNUJSP to prevent close in nested requests.
+ + Added GNUJSP to JettyServer.prp file.
+
+jetty-3.0.A7 - 15 April 2000
+ + Include java 1.2 source hierarchy
+ + removed excess ';' from source
+ + fixed flush problem with chunked output for IE5
+ + Added InetGateway to help debug IE5 problems
+ + added removeValue method to MultiMap
+
+jetty-2.4.1 - 09 April 2000
+ + Removed debug println from ServletHolder.
+ + Set encoding before exception in FileHandler.
+ + Fixed bug in HtmlFilter for tags split between writes.
+
+jetty-3.0.A6 - 09 April 2000
+ + Integrated skeleton 2.1 Servlet container
+ + Improved portability of Frame and Debug.
+ + Dates forced to use US locale
+ + Removed Converter utilities and InetGateway.
+ + added bin/useJava2Collections to convert to JDK1.2
+
+jetty-2.4.0 - 24 March 2000
+ + Upgraded to gnujsp 1.0.0
+ + Added per servlet resourceBase configuration.
+ + Absolute URIs are returned by getRequestURI (if sent by browser).
+ + Improved parsing of stack trace in debug mode.
+ + Implemented full handling of cookie max age.
+ + Moved SetUID native code to contrib hierarchy
+ + Form parameters only decoded for POSTs
+ + RequestDispatcher handles URI parameters
+ + Fixed bug with RequestDispatcher.include()
+ + Fixed caste problem in UrlEncoded
+ + Fixed null pointer in ThreadedServer with stopAll
+ + Added VirtualHostHandler for virtual host handling
+ + Added doc directory with a small start
+
+jetty-2.3.5 - 25 January 2000
+ + Fixed nasty bug with HTTP/1.1 redirects.
+ + ProxyHandler sends content for POSTs etc.
+ + Force locale of date formats to US.
+ + Fixed expires bug in Cookies
+ + Added configuration option to turn off Keep-Alive in HTTP/1.0
+ + Allow configured servlets to be auto reloaded.
+ + Allow properties to be configured for dynamic servlets.
+ + Added contrib/com/kiwiconsulting/jetty JSSE SSL adaptor to release.
+
+jetty-2.3.4 - 18 January 2000
+ + include from linux rather than genunix for native builds
+ + Fixed IllegalStateException handling in DefaultExceptionHandler
+ + MethodTag.invoke() is now public.
+ + Improved HtmlFilter.activate header modifications.
+ + Cookie map keyed on domain as well as name and path.
+ + DictionaryConverter handles null values.
+ + URI decodes applies URL decoding to the path.
+ + Servlet properties allow objects to be stored.
+ + Fixed interaction with resourcePaths and proxy demo.
+
+jetty-3.0.A5 - 19 October 1999
+ + Use ISO8859_1 instead of UTF8 for headers etc.
+ + Use char array in UrlEncoded.decode
+ + Do our own URL string encoding with 8859-1
+ + Replaced LF wait in LineInput with state boolean.
+
+jetty-2.3.3 - 19 October 1999
+ + Replaced UTF8 encoding with ISO-8859-1 for headers.
+ + Use UrlEncoded for form parameters.
+ + Do our own URL encoding with ISO-8859-1
+ + HTTP.HTML.EmbedUrl uses contents encoding.
+
+jetty-2.3.2 - 17 October 1999
+ + Fixed getReader bug with HttpRequest.
+ + Updated UrlEncoded with Jetty3 version.
+
+jetty-3.0.A4 - 16 October 1999
+ + Request attributes
+ + Basic Authentication Handler.
+ + Added LF wait after CR to LineInput.
+ + UTF8 in UrlDecoded.decodeString.
+
+jetty-2.3.1 - 14 October 1999
+ + Force UTF8 for FTP commands
+ + Force UTF8 for HTML
+ + Changed demo servlets to use writers in preference to outputstreams
+ + NullHandler/Server default name.name.PROPERTIES to load
+   prefix/name.name.properties
+ + Use UTF8 in HTTP headers
+ + Added Oracle DB adapter
+ + Added assert with no message to Code
+ + ThreadedServer calls setSoTimeout(_maxThreadIdleMs) on accepted sockets.
+   Idle reads will timeout.
+ + Prevented thread churn on idle server.
+ + HTTP/1.0 Keep-Alive (about time!).
+ + Fixed GNUJSP 1.0 resource bug.
+
+jetty-3.0.A3 - 14 October 1999
+ + Added LifeCycle interface to Utils implemented by ThreadPool,
+   ThreadedServer, HttpListener & HttpHandler
+ + StartAll, stopAll and destroyAll methods added to HttpServer.
+ + MaxReadTimeMs added to ThreadedServer.
+ + Added service method to HttpConnection for specialization.
+
+jetty-3.0.A2 - 13 October 1999
+ + UTF8 handling on raw output stream.
+ + Reduced flushing on writing response.
+ + Fixed LineInput problem with repeated CRs
+ + Cleaned up Util TestHarness.
+ + Prevent entity content for responses 100-199,203,304
+ + Added cookie support and demo.
+ + HTTP/1.0 Keep-alive (about time!)
+ + Virtual Hosts.
+ + NotFound Handler
+ + OPTION * Handling.
+ + TRACE handling.
+ + HEAD handling.
+
+jetty-3.0.A1 - 12 October 1999
+ + LineInput uses own buffering and uses character encodings.
+ + Added MultiMap for common handling of multiple valued parameters.
+ + Added parameters to HttpRequest
+ + Quick port of FileHandler
+ + Setup demo pages.
+ + Added PathMap implementing mapping as defined in the 2.2 API specification
+   (ie. /exact, /prefix/*, *.extention & default ).
+ + Added HttpHandler interface with start/stop/destroy lifecycle
+ + Updated HttpListener is start/stop/destroy lifecycle.
+ + Implemented simple extension architecture in HttpServer.
+
+jetty-3.0.A0 - 09 October 1999
+ + Started fresh repository in CVS
+ + Moved com.mortbay.Base classes to com.mortbay.Util
+ + Cleanup of UrlEncoded, using 1.2 Collections.
+ + Cleanup of URI, using 1.2 Collections.
+ + Extended URI to handle absolute URLs
+ + Cleanup of LineInput, using 1.2 Collections.
+ + Moved HttpInput/OutputStream to ChunkableInput/OutputStream.
+ + Cleaned up chunking code to use LineInput and reduce buffering.
+ + Added support for transfer and content encoding filters.
+ + Added support for servlet 2.2 outbut buffer control.
+ + Generalized notification of outputStream events.
+ + Split HttpHeader into HttpFields and HttpMessage.
+ + HttpMessage supports chunked trailers.
+ + HttpMessage supports message states.
+ + Added generalized HTTP Connection.
+ + Cleanup of HttpRequest and decoupled from Servlet API
+ + Cleanup and abstraction of ThreadPool.
+ + ThreadedServer based on ThreadPool.
+ + Cleanup of HttpResponse and decoupled from Servlet API
+ + Created RFC2616 test harness.
+ + gzip and deflate request transfer encodings
+ + TE field coding and trailer handler
+ + HttpExceptions now produce error pages with specific detail of the
+   exception.
+
+jetty-2.3.0 - 05 October 1999
+ + Added SetUID class with native Unix call to set the effective User ID.
+ + FTP closes files after put/get.
+ + FTP uses InetAddress of command socket for data socket.
+
+jetty-2.3.0A - 22 September 1999
+ + Added GNUJSP 1.0 for the JSP 1.0 API.
+ + Use javax.servlet classes from JWSDK1.0
+ + Added "Powered by Jetty" button.
+ + ServerContext available to HtmlFilters via context param
+ + Made session IDs less predictable and removed race.
+ + Added BuildJetty.java file.
+ + Expanded tabs to spaces in source.
+
+jetty-2.2.8 - 15 September 1999
+ + Fixed bug in Element.attribute with empty string values.
+ + Made translation of getRequestURI() optional.
+ + Removed recursion from TranslationHandler
+ + Added disableLog() to turn off logging.
+ + Allow default table attributes to be overriden.
+ + Improved quoting in HTML element values
+
+jetty-2.2.7 - 09 September 1999
+ + Reverted semantics of getRequestURI() to return untranslated URI.
+ + Added GzipFilter for content encoding.
+ + Added default row, head and cell elements to Table.
+ + FileHandler passes POST request through if the file does not exist.
+
+jetty-2.2.6 - 05 September 1999
+ + New implementation of ThreadPool, avoids a thread leak problem.
+ + Fixed Cookie max age order of magnitude bug.
+ + Cookies always available from getCookies.
+ + Cookies parameter renamed to CookiesAsParameters
+ + HttpRequest.getSession() always returns a session as per the latest API
+   spec.
+ + Added destroy() method on all HttpHandlers.
+ + ServletHandler.destroy destroys all servlets.
+ + FileHandler does not server files ending in '/'
+ + Ignore duplicate single valued headers, rather than reply with bad request,
+   as IE4 breaks the rules.
+ + Allow the handling of getPathTranslated to be configured in ServletHandler.
+ + Removed JRUN options from ServletHandler configuration.
+ + Added ServletRunnerHandler to the contrib directories.
+ + Updated HTML package to better support CSS:
+ + cssClass, cssID and style methods added to element.
+ + SPAN added to Block
+ + media added to Style
+ + class StyleLink added.
+
+jetty-2.2.5 - 19 August 1999
+ + Fixed bug with closing connections in ThreadedServer
+ + Made start and stop non final in ThreadedServer
+ + Better default handling of ServletExceptions
+ + Always close connection after a bad request.
+ + Set Expires header in HtmlFilter.
+ + Don't override the cookie as parameter option.
+ + Limited growth in MultiPartResponse boundary.
+ + Improved error messages from Jetty.Server.
+ + Close loaded class files so Win32 can overwrite them before GC (what a silly
+   file system!).
+
+jetty-2.2.4 - 02 August 1999
+ + ThreadedServer can use subclasses of Thread.
+ + Better help on Jetty.Server
+ + HttpRequests may be passed to HttpFilter constructors.
+ + HtmlFilter blanks IfModifiedSince headers on construction
+ + Fixed bugs in HtmlFilter parser and added TestHarness.
+ + Improved cfg RCS script.
+
+jetty-2.2.3 - 27 July 1999
+ + Fixed parser bug in HtmlFilter
+ + Made setInitialize public in ServletHolder
+ + Improved performance of com.mortbay.HTML.Heading
+ + Added stop call to HttpServer, used by Exit Servlet.
+ + Simplified JDBC connection handling so that it works with Java1.2 - albeit
+   less efficiently.
+ + FileHandler defaults to allowing directory access.
+ + JDBC tests modified to use cloudscape as DB.
+
+jetty-2.2.2 - 22 July 1999
+ + Fixed bug in HtmlFilter that prevented single char buffers from being
+   written.
+ + Implemented getResourceAsStream in FileJarServletLoader
+ + Fixed bug with CLASSPATH in FileJarServletLoader after attempt to load from
+   a jar.
+ + Fixed bug in com.mortbay.Util.IO with thread routines.
+ + Moved more test harnesses out of classes.
+ + File handler passes through not allowed options for non existant files.
+ + NotFoundHandler can repond with SC_METHOD_NOT_ALLOWED.
+ + Improved com.mortbay.Base.Log handling of different JVMs
+ + Minor fixes to README
+
+jetty-2.2.1 - 18 July 1999
+ + Comma separate header fields.
+ + Protect against duplicate single valued headers.
+ + Less verbose debug in PropertyTree
+ + Ignore IOException in ThreadedServer.run() when closing.
+ + Limit maximum line length in HttpInputStream.
+ + Response with SC_BAD_REQUEST rather than close in more circumstances
+ + Handle continuation lines in HttpHeader.
+ + HtmlFilter resets last-modified and content-length headers.
+ + Implemented com.mortbay.Util.IO as a ThreadPool
+ + Decoupled ExceptionHandler configuration from Handler stacks. Old config
+   style will produce warning and Default behavior. See new config file format
+   for changes.
+ + Added TerseExceptionHandler
+ + Added optional resourceBase property to HttpConfiguration. This is used as a
+   URL prefix in the getResource API and was suggested by the JSERV and Tomcat
+   implementors.
+
+jetty-2.2.0 - 01 July 1999
+ + Improved feature description page.
+ + Added Protekt SSL HttpListener
+ + Moved GNUJSP and Protekt listener to a contrib hierarchy.
+ + ThreadedServer.stop() closes socket before interrupting threads.
+ + Exit servlet improved (a little).
+ + Fixed some of the javadoc formatting.
+
+jetty-2.2.Beta4 - 29 June 1999
+ + FileHandler flushes files from cache in DELETE method.
+ + ThreadedServer.stop() now waits until all threads are stopped.
+ + Options "allowDir" added to FileHandler.
+ + Added getGlobalProperty to Jetty.Server and used this to configure default
+   page type.
+ + Updated README.txt
+ + Restructured com.mortbay.Jetty.Server for better clarity and documentation.
+ + Added comments to configuration files.
+ + Made ServerSocket and accept call generic in ThreadedServer for SSL
+   listeners.
+ + Altered meaning of * in PropertyTree to assist in abbreviated configuration
+   files.
+ + Added JettyMinimalDemo.prp as an example of an abbreviated configuration.
+ + Expanded Mime.prp file
+ + Added property handling to ServletHandler to read JRUN servlet configuration
+   files.
+
+jetty-2.2.Beta3 - 22 June 1999
+ + Re-implemented ThreadedServer to improve and balance performance.
+ + Added file cache to FileHandler
+ + Implemented efficient version of ServletContext.getResourceAsStream() that
+   does not open a new socket connection (as does getResource()).
+ + LookAndFeelServlet uses getResourceAsStream to get the file to wrap. This
+   allows it to benefit from any caching done and to wrap arbitrary content
+   (not just files).
+ + Restructure demo so that LookAndFeel content comes from simple handler
+   stack.
+ + Fixed file and socket leaks in Include and Embed tags.
+ + Ran dos2unix on all text files
+ + Applied contributed patch of spelling and typo corrections
+ + Added alternate constructors to HTML.Include for InputStream.
+ + Server.shutdown() clears configuration so that server may be restarted in
+   same virtual machine.
+ + Improved Block.write.
+ + Fixed bug in HttpResponse flush.
+
+jetty-2.2.Beta2 - 12 June 1999
+ + Added all write methods to HttpOutputStream$SwitchOutputStream
+ + Added com.mortbay.Jetty.Server.shutdown() for gentler shutdown of server.
+   Called from Exit servlet
+ + HttpRequest.getParameterNames() no longer alters the order returned by
+   getQueryString().
+ + Handle  path info of a dynamic loaded servlets and correctly set the servlet
+   path.
+ + Standardized date format in persistent cookies.
+
+jetty-2.2.Beta1 - 07 June 1999
+ + Defined abstract ServletLoader, derivations of which can be specified in
+   HttpConfiguration properties.
+ + Implemented all HttpServer attribute methods by mapping to the
+   HttpConfiguration properties.  Dynamic reconfiguration is NOT supported by
+   these methods (but we are thinking about it).
+ + Close files after use to avoid "file leak" under heavy load.
+ + Fixed missing copyright messages from some contributions
+ + Fixed incorrect version numbers in a few places.
+ + Improved ThreadPool synchronization and added minThreads.
+ + Allow configuration of MinListenerThreads, MaxListenerThreads,
+   MaxListenerThreadIdleMs
+ + HtmlFilter optimized for being called by a buffered writer.
+ + Don't warn about IOExceptions unless Debug is on.
+ + Limit the job queue only grow to the max number of threads.
+ + Included GNUJSP 0.9.9
+ + Optional use of DateCache in log file format
+ + Fixed cache in FileJarServletLoader
+ + Destroy requests and responses to help garbage collector.
+ + Restructure ThreadedServer to reduce object creation.
+
+jetty-2.2.Beta0 - 31 May 1999
+ + Servlet loader handles jar files with different files separator.
+ + ThreadedServer gently shuts down.
+ + Handle malformed % characters in URLs.
+ + Included and improved version of ThreadPool for significant performance
+   improvement under high load.
+ + HttpRequest.getCookies returns empty array rather than null for no cookies.
+ + Added HttpResponse.requestHandled() method to avoid bug with servlet doHead
+   method.
+ + Added Page.rewind() method to allow a page to be written multiple times
+ + Added "Initialize" attribute to servlet configuration to allow servlet to be
+   initialized when loaded.
+ + LogHandler changed to support only a single outfile and optional append.
+ + Included contributed com.mortbay.Jetty.StressTester class
+ + Token effort to keep test files out of the jar
+ + Removed support for STF
+
+jetty-2.2.Alpha1 - 07 May 1999
+ + ServletHolder can auto reload servlets
+ + Dynamic servlets can have autoReload configured
+ + Wait for requests to complete before reloading.
+ + Call destroy on old servlets when reloading.
+ + Made capitalization of config file more consistent(ish)
+ + Fixed bug in SessionDump
+
+jetty-2.2.Alpha0 - 06 May 1999
+ + Improved PropertyTree implementation
+ + Old Jetty.Server class renamed to Jetty.Server21
+ + New Server class using PropertyTree for configuration
+ + HttpHandlers given setProperties method to configure via Properties.
+ + HttpListener class can be configured
+ + Mime suffix mapping can be configured.
+ + Removed historic API from sessions
+ + Improved SessionDump servlet
+ + Fixed date overflow in Cookies
+ + HttpResponse.sendError avoids IllegalStateException
+ + Added ServletLoader implementation if ClassLoader.
+ + Dynamic loading of servlets.
+ + Added reload method to ServletHolder, but no way to call it yet.
+ + Changed options for FileServer
+ + Implemented ServletServer
+ + Removed SimpleServletServer
+
+jetty-2.1.7 - 22 April 1999
+ + Fixed showstopper bug with getReader and getWriter in requests and
+   responses.
+ + HttpFilter uses package interface to get HttpOutputStream
+
+jetty-2.1.6 - 21 April 1999
+ + Reduced initial size of most hashtables to reduce default memory overheads.
+ + Throw IllegalStateException as required from gets of
+   input/output/reader/writer in requests/responses.
+ + New simpler version of PropertyTree
+ + Updated PropertyTreeEditor
+ + Return EOF from HttpInputStream that has a content length.
+ + Added additional date formats for HttpHeader.getDateHeader
+
+jetty-2.1.5 - 15 April 1999
+ + Session URL encoding fixed for relative URLs.
+ + Reduced session memory overhead of sessions
+ + Form parameters protected against multiple decodes when redirected.
+ + Added setType methods to com.mortbay.FTP.Ftp
+ + Fixed bugs with invalid sessions
+ + Page factory requires response for session encoding
+ + Moved SessionHandler to front of stacks
+ + HtmlFilter now expands <!=SESSION> to the URL encoded session if required.
+ + Instrumented most of the demo to support URL session encoding.
+ + Implemented HttpRequest.getReader()
+ + Servlet log has been diverted to com.mortbay.Base.Log.event() Thus debug
+   does not need to be turned on to see servlet logs.
+ + Fixed alignment bug in TableForm
+ + Removed RFCs from package
+ + Fixed bug in ServletDispatch for null pathInfo
+
+jetty-2.1.4 - 26 March 1999
+ + Fixed problem compiling PathMap under some JDKs.
+ + Reduced HTML dependence in HTTP package to allow minimal configuration
+ + Tightened license agreement so that binary distributions are required to
+   include the license file.
+ + HttpRequest attributes implemented.
+ + Session max idle time implemented.
+ + pathInfo returns null for zero length pathInfo (as per spec). Sorry if this
+   breaks your servlets - it is a pain!
+ + fixed bug in getRealPath
+ + getPathTranslated now call getRealPath with pathInfo (as per spec).
+
+jetty-2.1.3 - 19 March 1999
+ + Added support for suffixes to PathMap
+ + Included GNUJSP implementation of Java Server Pages
+ + Use Java2 javadoc
+
+jetty-2.1.2 - 09 March 1999
+ + JSDK 2.1.1
+ + API documentation for JSDK 2.1.1
+ + Cascading style sheet HTML element added.
+ + Fixed trailing / bug in FileHandler (again!).
+ + Converted most servlets to HttpServlets using do Methods.
+
+jetty-2.1.1 - 05 March 1999
+ + Reduced number of calls to getRemoteHost for optimization
+ + Faster version of HttpInputStream.readLine().
+ + com.mortbay.Base.DateCache class added and used to speed date handling.
+ + Handle '.' in configured paths (temp fix until PropertyTrees)
+ + Fast char buffer handling in HttpInputStream
+ + Faster version of HttpHeader.read()
+ + Faster version of HttpRequest
+ + Size all StringBuffers
+
+jetty-2.1.0 - 22 February 1999
+ + Session URL Encoding
+ + PropertyTrees (see new Demo page)
+ + ServletDispatch (see new Demo page)
+ + image/jpg -> image/jpeg
+ + Deprecated com.mortbay.Util.STF
+ + getServlet methods return null.
+
+jetty-2.1.B1 - 13 February 1999
+ + Fixed bug with if-modified-since in FileHandler
+ + Added video/quicktime to default MIME types.
+ + Fixed bug with MultipartRequest.
+ + Updated DefaultExceptionHandler.
+ + Updated InetAddrPort.
+ + Updated URI.
+ + Implemented Handler translations and getRealPath.
+ + Improved handling of File.separator in FileHandler.
+ + Implemented RequestDispatcher (NOT Tested!).
+ + Implemented getResource and getResourceAsStream (NOT Tested!).
+ + Replace package com.mortbay.Util.Gateway with class
+   com.mortbay.Util.InetGateway
+
+jetty-2.1.B0 - 30 January 1999
+ + Uses JSDK2.1 API, but not all methods implemented.
+ + Added support for PUT, MOVE, DELETE in FileHandler
+ + FileHandler now sets content length.
+ + Added plug gateway classes com.mortbay.Util.Gateway
+ + Fixed command line bug with SimpleServletConfig
+ + Minor changes to support MS J++ and its non standard language extensions -
+   MMMmmm should have left it unchanged!
+
+jetty-2.0.5 - 15 December 1998
+ + Temp fix to getCharacterEncoding
+ + added getHeaderNoParams
+
+jetty-2.0.4 - 10 December 1998
+ + Use real release of JSDK2.0 (rather than beta).
+ + Portability issues solved for Apple's
+ + Improved error code returns
+ + Removed MORTBAY_HOME support from Makefiles
+ + Improved default Makefile behaviour
+ + Implement getCharacterEncoding
+
+jetty-2.0.3 - 13 November 1998
+ + Limit threads in ThreadedServer and low priority listener option greatly
+   improve performance under worse case loads.
+ + Fix bug with index files for Jetty.Server. Previously servers configured
+   with com.mortbay.Jetty.Server would not handle index.html files.  Need to
+   make this configurable in the prp file.
+ + Fixed errors in README file: com.mortbay.Jetty.Server was called
+   com.mortbay.HTTP.Server
+
+jetty-2.0.2 - 01 November 1998
+ + Use JETTY_HOME rather than MORTBAY_HOME for build environment
+ + Add thread pool to threaded server for significant performance improvement.
+ + Buffer files during configuration
+ + Buffer HTTP Response headers.
+
+jetty-2.0.1 - 27 October 1998
+ + Released under an Open Source license.
+
+jetty-2.0.0 - 25 October 1998
+ + Removed exceptional case from FileHandler redirect.
+ + Removed Chat demo (too many netscape dependencies).
+ + Fixed Code.formatObject handling of null objects.
+ + Added multipart/form-data demo.
+
+jetty-2.0.Beta3 - 29 September 1998
+ + Send 301 for directories without trailing / in FileHandler
+ + Ignore exception from HttpListener
+ + Properly implemented multiple listening addresses
+ + Added com.mortbay.Jetty.Server (see README.Jetty)
+ + Demo converted to an instance of com.mortbay.Jetty.Server
+ + Fixed Log Handler again.
+ + Added com.mortbay.HTTP.MultiPartRequest to handle file uploads
+
+jetty-2.0Beta2 - 01 July 1998
+ + Fixed Log Handler for HTTP/1.1
+ + Slight improvement in READMEEs
+
+jetty-2.0Beta1 - 01 June 1998
+ + Improved performance of Code.debug() calls, significantly in the case of non
+   matching debug patterns.
+ + Fixed bug with calls to service during initialization of servlet
+ + Provided addSection on com.mortbay.HTML.Page
+ + Provided reset on com.mortbay.HTML.Composite.
+ + Proxy demo in different server instance
+ + Handle full URLs in HTTP requests (to some extent)
+ + Improved performance with special asciiToLowerCase
+ + Warn if MSIE used for multi part MIME.
+
+jetty-2.0Alpha2 - 01 May 1998
+ + JDK1.2 javax.servlet API
+ + Added date format to Log
+ + Added timezone to Log
+ + Handle params in getIntHeader and getDateHeader
+ + Removed HttpRequest.getByteContent
+ + Use javax.servlet.http.HttpUtils.parsePostData
+ + Use javax.servlet.http.Cookie
+ + Use javax.servlet.http.HttpSession
+ + Handle Single Threaded servlets with servlet pool
+
+jetty-1.3.5 - 01 May 1998
+ + Fixed socket inet bug in FTP
+ + Debug triggers added to com.mortbay.Base.Code
+ + Added date format to Log
+ + Correct handling of multiple parameters
+
+jetty-2.0Alpha1 - 08 April 1998
+ + Fixed forward bug with no port number
+ + Removed HttpRequestHeader class
+ + Debug triggers added to com.mortbay.Base.Code
+ + Handle HTTP/1.1 Host: header
+ + Correct formatting of Date HTTP headers
+ + HttpTests test harness
+ + Add HTTP/1.1 Date: header
+ + Handle file requests with If-Modified-Since: or If-Unmodified-Since:
+ + Handle HEAD properly
+ + Send Connection: close
+ + Requires Host: header for 1.1 requests
+ + Sends chunked data for 1.1 responses of unknown length.
+ + handle extra spaces in HTTP headers
+ + Really fixed handling of multiple parameters
+ + accept chunked data
+ + Send 100 Continue for HTTP/1.1 requests (concerned about push???)
+ + persistent connections
+
+jetty-1.3.4 - 15 March 1998
+ + Fixed handling of multiple parameters in query and form content.
+   "?A=1%2C2&A=C%2CD" now returns two values ("1,2" & "C,D") rather than 4.
+ + ServletHandler now takes an optional file base directory name which is used
+   to set the translated path for pathInfo in servlet requests.
+ + Dump servlet enhanced to exercise these changes.
+
+jetty-1.3.3
+ + Fixed TableForm.addButtonArea bug.
+ + TableForm.extendRow() uses existing cell
+ + Closed exception window in HttpListener.java
+
+jetty-1.3.2
+ + Fixed proxy bug with no port number
+ + Added per Table cell composite factories
+
+jetty-1.3.1
+ + Minor fixes in SmtpMail
+ + ForwardHandler only forwards as http/1.0 (from Tobias.Miller)
+ + Improved parsing of stack traces
+ + Better handling of InvocationTargetException in debug
+ + Minor release adjustments for Tracker
+
+jetty-1.3.0
+ + Added DbAdaptor to JDBC wrappers
+ + Beta release of Tracker
+
+jetty-1.2.0
+ + Reintroduced STF
+ + Fixed install bug for nested classes
+ + Better Debug configuration
+ + DebugServlet
+ + Alternate look and feel for Jetty
+
+jetty-1.1.1
+ + Improved documentation
+
+jetty-1.1
+ + Improved connection caching in java.mortbay.JDBC
+ + Moved HttpCode to com.mortbay.Util
+
+jetty-1.0.1
+ + Bug fixes
+
+jetty-1.0
+ + First release in com.mortbay package structure
+ + Included Util, JDBC, HTML, HTTP, Jetty
+
diff --git a/lib/javax.servlet-3.0.0.v201112011016-sources.jar b/lib/javax.servlet-3.0.0.v201112011016-sources.jar
new file mode 100644
index 0000000..2baa97b
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016-sources.jar
Binary files differ
diff --git a/lib/javax.servlet-3.0.0.v201112011016-sources.jar.sha1 b/lib/javax.servlet-3.0.0.v201112011016-sources.jar.sha1
new file mode 100644
index 0000000..aea41c3
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016-sources.jar.sha1
@@ -0,0 +1 @@
+15c914135cf30177b83c321250c458396289cd37
\ No newline at end of file
diff --git a/lib/javax.servlet-3.0.0.v201112011016.jar b/lib/javax.servlet-3.0.0.v201112011016.jar
new file mode 100644
index 0000000..b135409
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016.jar
Binary files differ
diff --git a/lib/javax.servlet-3.0.0.v201112011016.jar.sha1 b/lib/javax.servlet-3.0.0.v201112011016.jar.sha1
new file mode 100644
index 0000000..2603fb9
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016.jar.sha1
@@ -0,0 +1 @@
+0aaaa85845fb5c59da00193f06b8e5278d8bf3f8
\ No newline at end of file
diff --git a/lib/javax.servlet-3.0.0.v201112011016.pom b/lib/javax.servlet-3.0.0.v201112011016.pom
new file mode 100644
index 0000000..2bcfad6
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016.pom
@@ -0,0 +1,17 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.eclipse.jetty.orbit</groupId>
+    <artifactId>jetty-orbit</artifactId>
+    <version>1</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.eclipse.jetty.orbit</groupId>
+  <artifactId>javax.servlet</artifactId>
+  <version>3.0.0.v201112011016</version>
+  <name>Jetty Orbit :: Servlet API</name>
+  <description>
+    This artifact originates from the Orbit Project at Eclipse, 
+    it is an osgi bundle and is signed as well.
+  </description>
+  <packaging>orbit</packaging>
+</project>
diff --git a/lib/javax.servlet-3.0.0.v201112011016.pom.sha1 b/lib/javax.servlet-3.0.0.v201112011016.pom.sha1
new file mode 100644
index 0000000..787a813
--- /dev/null
+++ b/lib/javax.servlet-3.0.0.v201112011016.pom.sha1
@@ -0,0 +1 @@
+b23491173f52c804489f6625a661f4ba946f4e51
\ No newline at end of file
diff --git a/lib/jetty-util-6.1.26.jar b/lib/jetty-util-6.1.26.jar
new file mode 100644
index 0000000..cd23752
--- /dev/null
+++ b/lib/jetty-util-6.1.26.jar
Binary files differ
diff --git a/lib/jetty-util-6.1.26.jar.sha1 b/lib/jetty-util-6.1.26.jar.sha1
new file mode 100644
index 0000000..e00b3a8
--- /dev/null
+++ b/lib/jetty-util-6.1.26.jar.sha1
@@ -0,0 +1 @@
+e5642fe0399814e1687d55a3862aa5a3417226a9
\ No newline at end of file
diff --git a/lib/jetty-util-6.1.26.pom b/lib/jetty-util-6.1.26.pom
new file mode 100644
index 0000000..fb52f3b
--- /dev/null
+++ b/lib/jetty-util-6.1.26.pom
@@ -0,0 +1,111 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <artifactId>project</artifactId>
+    <groupId>org.mortbay.jetty</groupId>
+    <version>6.1.26</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.mortbay.jetty</groupId>
+  <artifactId>jetty-util</artifactId>
+  <name>Jetty Utilities</name>
+  <description>Utility classes for Jetty</description>
+  <build>
+    <testResources>
+      <testResource>
+        <directory>src/test/java</directory>
+        <includes>
+          <include>**/*Test.java</include>
+          <include>org/mortbay/**/*.xml</include>
+        </includes>
+        <excludes>
+          <exclude>**/Abstract*.java</exclude>
+        </excludes>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>clean</id>
+            <phase>clean</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <tasks>
+                <delete failonerror="false" file="../../lib/${project.artifactId}-${project.version}.${project.packaging}" />
+                <delete failonerror="false" file="../../etc/jetty-logging.xml" />
+              </tasks>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copyjar</id>
+            <phase>install</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <tasks>
+                <copy failonerror="false" file="target/${project.artifactId}-${project.version}.${project.packaging}" todir="../../lib/" />
+                <copy failonerror="false" file="src/main/config/etc/jetty-logging.xml" todir="../../etc" />
+              </tasks>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${maven-bundle-plugin-version}</version>
+        <extensions>true</extensions>
+        <executions>
+          <execution>
+            <goals>
+              <goal>manifest</goal>
+            </goals>
+            <configuration>
+              <instructions>
+                <Bundle-SymbolicName>org.mortbay.jetty.util</Bundle-SymbolicName>
+                <Bundle-RequiredExecutionEnvironment>J2SE-1.4</Bundle-RequiredExecutionEnvironment>
+                <Import-Package>!org.mortbay.*,org.slf4j;resolution:=optional,*</Import-Package>
+                <Bundle-DocURL>http://jetty.mortbay.org</Bundle-DocURL>
+              </instructions>
+            </configuration>
+           </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <!--
+        Required for OSGI
+        -->
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>               
+            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mortbay.jetty</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>${servlet-version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <optional>true</optional>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/lib/jetty-util-6.1.26.pom.sha1 b/lib/jetty-util-6.1.26.pom.sha1
new file mode 100644
index 0000000..c4edc57
--- /dev/null
+++ b/lib/jetty-util-6.1.26.pom.sha1
@@ -0,0 +1 @@
+392748d8f7f97d4b37576ac710fceffa58ba294e
\ No newline at end of file
diff --git a/lib/slf4j-api-1.6.1.jar b/lib/slf4j-api-1.6.1.jar
new file mode 100644
index 0000000..f1f4fdd
--- /dev/null
+++ b/lib/slf4j-api-1.6.1.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.1.jar.sha1 b/lib/slf4j-api-1.6.1.jar.sha1
new file mode 100644
index 0000000..3f1a76e
--- /dev/null
+++ b/lib/slf4j-api-1.6.1.jar.sha1
@@ -0,0 +1 @@
+6f3b8a24bf970f17289b234284c94f43eb42f0e4
\ No newline at end of file
diff --git a/lib/slf4j-api-1.6.1.pom b/lib/slf4j-api-1.6.1.pom
new file mode 100644
index 0000000..e7e09ff
--- /dev/null
+++ b/lib/slf4j-api-1.6.1.pom
@@ -0,0 +1,101 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.slf4j</groupId>
+    <artifactId>slf4j-parent</artifactId>
+    <version>1.6.1</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.slf4j</groupId>
+  <artifactId>slf4j-api</artifactId>
+  <packaging>jar</packaging>
+  <name>SLF4J API Module</name>
+
+  <url>http://www.slf4j.org</url>
+  <description>The slf4j API</description>
+
+  <dependencies>
+
+  </dependencies> 
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <forkMode>once</forkMode>
+          <reportFormat>plain</reportFormat>
+          <trimStackTrace>false</trimStackTrace>
+          <excludes>
+            <exclude>**/AllTest.java</exclude>
+            <exclude>**/PackageTest.java</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
+              <Bundle-Description>${project.description}</Bundle-Description>
+              <Implementation-Version>${project.version}</Implementation-Version>
+            </manifestEntries>
+            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+          </archive>
+        </configuration>
+        <executions>
+          <execution>
+            <id>bundle-test-jar</id>
+            <phase>package</phase>
+            <goals>
+              <goal>jar</goal>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>process-classes</phase>
+            <goals>
+             <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <tasks>
+            <echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo>
+            <delete dir="target/classes/org/slf4j/impl"/>
+          </tasks>
+        </configuration>
+      </plugin>
+
+    </plugins>
+
+  </build>
+  
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>clirr-maven-plugin</artifactId>
+        <configuration>
+          <comparisonVersion>1.5.6</comparisonVersion>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+</project>
\ No newline at end of file
diff --git a/lib/slf4j-api-1.6.1.pom.sha1 b/lib/slf4j-api-1.6.1.pom.sha1
new file mode 100644
index 0000000..2ff79af
--- /dev/null
+++ b/lib/slf4j-api-1.6.1.pom.sha1
@@ -0,0 +1 @@
+bd86aca3b3779fa5aa5e4442a5db2ebf4035365c
\ No newline at end of file
diff --git a/lib/slf4j-jdk14-1.6.1.jar b/lib/slf4j-jdk14-1.6.1.jar
new file mode 100644
index 0000000..6eb6367
--- /dev/null
+++ b/lib/slf4j-jdk14-1.6.1.jar
Binary files differ
diff --git a/lib/slf4j-jdk14-1.6.1.jar.sha1 b/lib/slf4j-jdk14-1.6.1.jar.sha1
new file mode 100644
index 0000000..2e18640
--- /dev/null
+++ b/lib/slf4j-jdk14-1.6.1.jar.sha1
@@ -0,0 +1 @@
+251899d8c17e29ed4c53d98c88e54241a14d9591
\ No newline at end of file
diff --git a/lib/slf4j-jdk14-1.6.1.pom b/lib/slf4j-jdk14-1.6.1.pom
new file mode 100644
index 0000000..50df72b
--- /dev/null
+++ b/lib/slf4j-jdk14-1.6.1.pom
@@ -0,0 +1,69 @@
+<project 
+  xmlns="http://maven.apache.org/POM/4.0.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<parent>
+		<groupId>org.slf4j</groupId>
+		<artifactId>slf4j-parent</artifactId>
+    	<version>1.6.1</version>
+	</parent>
+	
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>org.slf4j</groupId>
+	<artifactId>slf4j-jdk14</artifactId>
+
+	<packaging>jar</packaging>
+	<name>SLF4J JDK14 Binding</name>
+
+	<url>http://www.slf4j.org</url>
+	<description>
+		The slf4j JDK14 binding
+	</description>
+
+  <dependencies>
+	  <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+		</dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <type>test-jar</type>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+		<plugins>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.4</source>
+					<target>1.4</target>
+				</configuration>
+			</plugin>
+
+			<plugin>
+			  <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
+              <Bundle-Description>${project.description}</Bundle-Description>
+              <Implementation-Version>${project.version}</Implementation-Version>
+            </manifestEntries>
+            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+          </archive>
+        </configuration>			
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file
diff --git a/lib/slf4j-jdk14-1.6.1.pom.sha1 b/lib/slf4j-jdk14-1.6.1.pom.sha1
new file mode 100644
index 0000000..169a426
--- /dev/null
+++ b/lib/slf4j-jdk14-1.6.1.pom.sha1
@@ -0,0 +1 @@
+6f0ca912337d5b0d1711f8e0f4f283cd13ec518d
\ No newline at end of file
diff --git a/pom.xml_saved b/pom.xml_saved
new file mode 100644
index 0000000..04141b4
--- /dev/null
+++ b/pom.xml_saved
@@ -0,0 +1,779 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.jetty</groupId>
+    <artifactId>jetty-parent</artifactId>
+    <version>20</version>
+  </parent>
+  <artifactId>jetty-project</artifactId>
+  <version>8.1.15.v20140411</version>
+  <name>Jetty :: Project</name>
+  <url>http://www.eclipse.org/jetty</url>
+  <packaging>pom</packaging>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <jetty.url>http://www.eclipse.org/jetty</jetty.url>
+    <orbit-servlet-api-version>3.0.0.v201112011016</orbit-servlet-api-version>
+    <build-support-version>1.1</build-support-version>
+    <slf4j-version>1.6.1</slf4j-version>
+    <jetty-test-policy-version>1.2</jetty-test-policy-version>
+  </properties>
+  <scm>
+    <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</connection>
+    <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project.git</developerConnection>
+    <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree</url>
+  </scm>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <verbose>false</verbose>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-release-plugin</artifactId>
+        <configuration>
+          <autoVersionSubmodules>true</autoVersionSubmodules>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <configuration>
+              <resourceBundles>
+                <resourceBundle>org.eclipse.jetty.toolchain:jetty-artifact-remote-resources:1.1</resourceBundle>
+              </resourceBundles>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- source maven plugin creates the source bundle and adds manifest -->
+      <plugin>
+        <inherited>true</inherited>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration>
+              <archive>
+                <manifestEntries>
+                  <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
+                  <Bundle-Name>${project.name}</Bundle-Name>
+                  <Bundle-SymbolicName>${bundle-symbolic-name}.source;singleton:=true</Bundle-SymbolicName>
+                  <Bundle-Vendor>Eclipse.org - Jetty</Bundle-Vendor>
+                  <Bundle-Version>${parsedVersion.osgiVersion}</Bundle-Version>
+                  <Eclipse-SourceBundle>${bundle-symbolic-name};version="${parsedVersion.osgiVersion}";roots:="."</Eclipse-SourceBundle>
+                </manifestEntries>
+              </archive>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Build helper maven plugin sets the parsedVersion.osgiVersion property -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>set-osgi-version</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>parse-version</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.jetty.toolchain</groupId>
+        <artifactId>jetty-version-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-version</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>attach-version-text</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Enforcer Plugin -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>enforce-java</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requireMavenVersion>
+                  <version>[2.0.6,)</version>
+                </requireMavenVersion>
+                <requireJavaVersion>
+                  <version>[1.5,)</version>
+                </requireJavaVersion>
+                <versionTxtRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.VersionTxtRule" />
+                <versionOsgiRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireOsgiCompatibleVersionRule" />
+                <versionRedhatRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireRedhatCompatibleVersionRule" />
+                <versionDebianRule implementation="org.eclipse.jetty.toolchain.enforcer.rules.RequireDebianCompatibleVersionRule" />
+             </rules>
+            </configuration>
+          </execution>
+          <execution>
+            <id>enforce-orbit-deps</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <!-- Banned Dependencies (should use Orbit based versions now) -->
+                <bannedDependencies>
+                  <includes>
+                    <include>javax.servlet</include>
+                    <include>org.apache.geronimo.specs</include>
+                    <include>javax.mail</include>
+                    <include>javax.activation</include>
+                  </includes>
+                  <searchTransitive>true</searchTransitive>
+                  <message>This dependency is banned, use the ORBIT provided dependency instead.</message>
+                </bannedDependencies>
+              </rules>
+              <fail>true</fail>
+            </configuration>
+          </execution>
+        </executions>
+        <dependencies>
+           <dependency>
+             <groupId>org.eclipse.jetty.toolchain</groupId>
+             <artifactId>jetty-build-support</artifactId>
+             <version>${build-support-version}</version>
+           </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>named-logging-enforcement</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+            <configuration>
+              <verbose>true</verbose>
+            </configuration>
+          </execution>
+        </executions>
+        <configuration>
+          <targetJdk>1.6</targetJdk>
+          <rulesets>
+            <ruleset>jetty/pmd_logging_ruleset.xml</ruleset>
+          </rulesets>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.eclipse.jetty.toolchain</groupId>
+            <artifactId>jetty-build-support</artifactId>
+            <version>${build-support-version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <inherited>false</inherited>
+        <groupId>com.mycila.maven-license-plugin</groupId>
+        <artifactId>maven-license-plugin</artifactId>
+        <version>1.10.b1</version>
+        <configuration>
+          <header>header-template.txt</header>
+          <failIfMissing>true</failIfMissing>
+          <aggregate>true</aggregate>
+          <strictCheck>true</strictCheck>
+          <properties>
+             <copyright-range>${project.inceptionYear}-2014</copyright-range>
+          </properties>
+          <mapping>
+            <java>DOUBLESLASH_STYLE</java>
+          </mapping>
+          <includes>
+            <include>**/*.java</include>
+          </includes>
+          <excludes>
+            <exclude>jetty-util/src/main/java/org/eclipse/jetty/util/security/UnixCrypt.java</exclude>
+            <exclude>jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/DefaultPolicyLoader.java</exclude>
+            <exclude>jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java</exclude>
+          </excludes>
+        </configuration>
+        <executions>
+          <execution>
+            <id>check-headers</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.jetty.toolchain</groupId>
+          <artifactId>jetty-version-maven-plugin</artifactId>
+          <version>1.0.10</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <configuration>
+            <archive>
+              <manifestEntries>
+                <Implementation-Version>${project.version}</Implementation-Version>
+                <Implementation-Vendor>Eclipse.org - Jetty</Implementation-Vendor>
+                <url>${jetty.url}</url>
+              </manifestEntries>
+            </archive>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <configuration>
+            <failIfNoTests>false</failIfNoTests>
+            <!--systemProperties>
+              <property>
+                <name>org.eclipse.jetty.io.AbstractBuffer.boundsChecking</name>
+                <value>true</value>
+              </property>
+            </systemProperties-->
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <extensions>true</extensions>
+          <configuration>
+            <instructions>
+              <Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
+              <Bundle-DocURL>${jetty.url}</Bundle-DocURL>
+              <Bundle-Vendor>Eclipse Jetty Project</Bundle-Vendor>
+              <Bundle-Classpath>.</Bundle-Classpath>
+              <Export-Package>${bundle-symbolic-name}.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"</Export-Package>
+              <Bundle-Copyright>Copyright (c) 2008-2014 Mort Bay Consulting Pty. Ltd.</Bundle-Copyright>
+              <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+            </instructions>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <dependencies>
+            <dependency>
+              <groupId>org.eclipse.jetty.toolchain</groupId>
+              <artifactId>jetty-assembly-descriptors</artifactId>
+              <version>1.0</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>findbugs-maven-plugin</artifactId>
+          <configuration>
+            <findbugsXmlOutput>true</findbugsXmlOutput>
+            <xmlOutput>true</xmlOutput>
+            <effort>Max</effort>
+            <onlyAnalyze>org.eclipse.jetty.*</onlyAnalyze>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-dependency-plugin</artifactId>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jxr-plugin</artifactId>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-javadoc-plugin</artifactId>
+          <configuration>
+            <docfilessubdirs>true</docfilessubdirs>
+            <detectLinks>false</detectLinks>
+            <detectJavaApiLink>true</detectJavaApiLink>
+            <excludePackageNames>org.slf4j.*;org.mortbay.*</excludePackageNames>
+            <links>
+              <link>http://download.eclipse.org/jetty/stable-7/apidocs/</link>
+            </links>
+            <tags>
+              <tag>
+                <name>org.apache.xbean.XBean</name>
+                <placement>a</placement>
+                <head>Apache XBean:</head>
+              </tag>
+            </tags>
+            </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-pmd-plugin</artifactId>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>2.1</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.8</version>
+        <configuration>
+          <maxmemory>512m</maxmemory>
+          <docfilessubdirs>true</docfilessubdirs>
+          <detectLinks>true</detectLinks>
+          <detectJavaApiLink>true</detectJavaApiLink>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>2.7.1</version>
+        <configuration>
+          <targetJdk>1.5</targetJdk>
+          <rulesets>
+            <ruleset>jetty/pmd_ruleset.xml</ruleset>
+          </rulesets>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>2.3.2</version>
+      </plugin>
+    </plugins>
+  </reporting>
+<!--
+  <repositories>
+    <repository>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+      <id>sonatype-snapshots</id>
+      <name>Sonatype Jetty Snapshots</name>
+      <url>http://oss.sonatype.org/content/groups/jetty</url>
+    </repository>
+  </repositories>
+-->
+  <modules>
+    <module>jetty-util</module>
+    <module>jetty-jmx</module>
+    <module>jetty-io</module>
+    <module>jetty-http</module>
+    <module>jetty-websocket</module>
+    <module>jetty-continuation</module>
+    <module>jetty-server</module>
+    <module>jetty-client</module>
+    <module>jetty-xml</module>
+    <module>jetty-security</module>
+    <module>jetty-jaspi</module>
+    <module>jetty-servlet</module>
+    <module>jetty-webapp</module>
+    <module>jetty-servlets</module>
+    <module>jetty-deploy</module>
+    <module>jetty-ajp</module>
+    <module>jetty-jndi</module>
+    <module>jetty-annotations</module>
+    <module>jetty-plus</module>
+    <module>jetty-rewrite</module>
+    <module>jetty-policy</module>
+    <module>jetty-monitor</module>
+    <module>jetty-start</module>
+    <module>jetty-nested</module>
+    <module>jetty-overlay-deployer</module>
+    <module>jetty-nosql</module>
+    <module>jetty-http-spi</module>
+    <module>jetty-jsp</module>
+    <module>jetty-distribution</module>
+    <!--module>test-continuation-jetty6</module-->
+  </modules>
+  <dependencyManagement>
+    <dependencies>
+      <!-- Orbit Deps -->
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.servlet</artifactId>
+        <version>${orbit-servlet-api-version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.annotation</artifactId>
+        <version>1.1.0.v201108011116</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>org.objectweb.asm</artifactId>
+        <version>3.1.0.v200803061910</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.activation</artifactId>
+        <version>1.1.0.v201105071233</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.mail.glassfish</artifactId>
+        <version>1.4.1.v201005082020</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.transaction</artifactId>
+        <version>1.1.1.v201105210645</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.security.auth.message</artifactId>
+        <version>1.0.0.v201108011116</version>
+      </dependency>
+      <!--
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.servlet.jsp</artifactId>
+        <version>2.1.0.v201105211820</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.servlet.jsp.jstl</artifactId>
+        <version>1.2.0.v201105211821</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.el</artifactId>
+        <version>2.1.0.v201105211819</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>com.sun.el</artifactId>
+        <version>1.0.0.v201105211818</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>org.apache.jasper.glassfish</artifactId>
+        <version>2.1.0.v201110031002</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>org.apache.taglibs.standard.glassfish</artifactId>
+        <version>1.2.0.v201112081803</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>org.eclipse.jdt.core</artifactId>
+        <version>3.7.1</version>
+      </dependency>
+        -->
+
+      <!-- Old Deps -->
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-plugin-tools-api</artifactId>
+        <version>2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.toolchain</groupId>
+        <artifactId>jetty-test-helper</artifactId>
+        <version>2.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>jcl104-over-slf4j</artifactId>
+        <version>${slf4j-version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>log4j-over-slf4j</artifactId>
+        <version>${slf4j-version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>${slf4j-version}</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-core</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-library</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>1.9.5</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <!--
+    Usage:
+    configure settings.xml for jetty.eclipse.website server entry
+    > mvn -Paggregate-site javadoc:aggregate jxr:jxr
+    > mvn -N site:deploy
+    or
+    > mvn -N site:sshdeploy     (for ssh users w/passphrase and ssh-agent)
+   -->
+  <profiles>
+    <profile>
+      <!-- Modules that are only for JDK7+ builds -->
+      <id>JDK7-plus-modules</id>
+      <activation>
+        <jdk>[1.7,)</jdk>
+      </activation>
+      <modules>
+        <module>jetty-spdy</module>
+      </modules>
+    </profile>
+    <profile>
+      <id>eclipse-release</id>
+   <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>enforce-java</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requireJavaVersion>
+                  <version>[1.7,)</version>
+                </requireJavaVersion>
+              </rules>    
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+    </profile>
+    <profile>
+      <!--
+        Moves the jetty-aggregate build tree to a profile called 'aggregates'.
+        It is active by default, but being in a profile allows it to be
+        disabled via the "-P-aggregates" command line on maven.
+        (Useful for running site plugin with deep reporting and avoiding
+         duplicate hits on aggregated classes) -->
+      <id>aggregates</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+        <file>
+          <exists>${basedir}/pom.xml</exists>
+        </file>
+      </activation>
+      <modules>
+        <module>jetty-aggregate</module>
+      </modules>
+    </profile>
+    <profile>
+      <!--
+        Moves the jetty-osgi build tree to a profile called 'osgi'.
+        It is active by default, but being in a profile allows it to be
+        disabled via the "-P-osgi" command line on maven (if need be).
+        -->
+      <id>osgi</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+        <file>
+          <exists>${basedir}/pom.xml</exists>
+        </file>
+      </activation>
+      <modules>
+        <module>jetty-osgi</module>
+      </modules>
+    </profile>
+    <profile>
+      <id>update-version</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.eclipse.jetty.toolchain</groupId>
+            <artifactId>jetty-version-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>gen-versiontxt</id>
+                <phase>generate-resources</phase>
+                <goals>
+                  <goal>update-version-text</goal>
+                </goals>
+                <configuration>
+                  <refreshTags>true</refreshTags>
+                  <copyGenerated>true</copyGenerated>
+                  <attachArtifact>false</attachArtifact>
+                  <updateDate>true</updateDate>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>cobertura</id>
+      <reporting>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>cobertura-maven-plugin</artifactId>
+            <configuration>
+              <maxmem>512m</maxmem>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <reportSets>
+              <reportSet>
+                <id>just-javadoc-no-aggregate</id>
+                <reports>
+                  <report>javadoc</report>
+                </reports>
+                <inherited>true</inherited>
+                <configuration>
+                  <minmemory>256m</minmemory>
+                  <maxmemory>1g</maxmemory>
+                  <excludePackageNames>com.acme</excludePackageNames>
+                  <links>
+                    <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+                    <link>http://java.sun.com/javaee/5/docs/api</link>
+                    <link>http://junit.sourceforge.net/javadoc/</link>
+                  </links>
+                  <tags>
+                    <tag>
+                      <name>org.apache.xbean.XBean</name>
+                      <placement>X</placement>
+                      <head />
+                    </tag>
+                  </tags>
+                </configuration>
+              </reportSet>
+            </reportSets>
+          </plugin>
+         </plugins>
+      </reporting>
+      <build>
+        <pluginManagement>
+          <plugins>
+            <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-surefire-plugin</artifactId>
+              <configuration>
+                <testFailureIgnore>true</testFailureIgnore>
+              </configuration>
+            </plugin>
+          </plugins>
+        </pluginManagement>
+      </build>
+    </profile>
+    <profile>
+      <id>maven-3</id>
+      <activation>
+        <file>
+          <!--  This employs that the basedir expression is only recognized by Maven 3.x (see MNG-2363) -->
+          <exists>${basedir}</exists>
+        </file>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-site-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>attach-descriptor</id>
+                <goals>
+                  <goal>attach-descriptor</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>aggregate-site</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-jxr-plugin</artifactId>
+            <configuration>
+              <aggregate>true</aggregate>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <configuration>
+              <excludePackageNames>com.acme</excludePackageNames>
+              <links>
+                <link>http://java.sun.com/javase/6/docs/api/</link>
+                <link>http://java.sun.com/javaee/6/docs/api</link>
+                <link>http://junit.sourceforge.net/javadoc/</link>
+              </links>
+              <tags>
+                <tag>
+                  <name>org.apache.xbean.XBean</name>
+                  <placement>X</placement>
+                  <head />
+                </tag>
+              </tags>
+              <header>
+                <![CDATA[
+                    <script type="text/javascript">
+                      var _gaq = _gaq || [];
+                      _gaq.push(['_setAccount', 'UA-1149868-7']);
+                      _gaq.push(['_trackPageview']);
+                      (function() {
+                        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+                        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+                        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+                      })();
+                   </script>
+                ]]>
+              </header>           
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
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;>
