Merge branch 'apache-jsp-osgi' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project into apache-jsp-osgi
diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
index 4cd7993..9c66c8d 100644
--- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
+++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java
@@ -23,14 +23,14 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
 
 import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
 
 import org.apache.jasper.servlet.JasperInitializer;
 import org.apache.jasper.servlet.TldPreScanned;
 import org.apache.jasper.servlet.TldScanner;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
 import org.xml.sax.SAXException;
 
 /**
@@ -39,6 +39,7 @@
  */
 public class JettyJasperInitializer extends JasperInitializer
 {
+   private static final Logger LOG = Log.getLogger(JettyJasperInitializer.class);
     
     /**
      * NullTldScanner
@@ -99,14 +100,18 @@
         String tmp = context.getInitParameter("org.eclipse.jetty.jsp.precompiled");
         if (tmp!=null && !tmp.equals("") && Boolean.valueOf(tmp))
         {
+            if (LOG.isDebugEnabled()) LOG.debug("Jsp precompilation detected");
             return new NullTldScanner(context, namespaceAware, validate, blockExternal);
         }
         
         Collection<URL> tldUrls = (Collection<URL>)context.getAttribute("org.eclipse.jetty.tlds");
-        if (tldUrls != null && !tldUrls.isEmpty())
+        if (tldUrls != null)
         {
+            if (LOG.isDebugEnabled()) LOG.debug("Tld pre-scan detected");
             return new TldPreScanned(context,namespaceAware,validate,blockExternal,tldUrls);
         }
+        
+        if (LOG.isDebugEnabled()) LOG.debug("Defaulting to jasper tld scanning");
         return super.newTldScanner(context, namespaceAware, validate, blockExternal);
     }
     
diff --git a/examples/pom.xml b/examples/pom.xml
index f0add20..b803d82 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -47,6 +47,5 @@
     -->
     <module>async-rest</module>
     <module>embedded</module>
-    <module>quickstart</module>
   </modules>
 </project>
diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
index 0e399f0..9c6af51 100644
--- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
+++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/protonego-impl/alpn.mod
@@ -34,3 +34,9 @@
 lib/
 lib/alpn/
 
+[license]
+ALPN is a hosted at github under the GPL v2 with ClassPath Exception.
+ALPM replaces/modified OpenJDK classes in the java.sun.security.ssl package.
+http://github.com/jetty-project/jetty-alpn
+http://openjdk.java.net/legal/gplv2+ce.html
+
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
index af9d0d2..ee698bb 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java
@@ -88,11 +88,14 @@
                 channel.bind(bindAddress);
             configure(client, channel);
             channel.configureBlocking(false);
-            channel.connect(address);
 
             context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, destination.getHost());
             context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, destination.getPort());
-            selectorManager.connect(channel, context);
+
+            if (channel.connect(address))
+                selectorManager.accept(channel, context);
+            else
+                selectorManager.connect(channel, context);
         }
         // Must catch all exceptions, since some like
         // UnresolvedAddressException are not IOExceptions.
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
index f54d02b..f1932eb 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java
@@ -18,6 +18,11 @@
 
 package org.eclipse.jetty.http;
 
+import static org.eclipse.jetty.http.HttpTokens.CARRIAGE_RETURN;
+import static org.eclipse.jetty.http.HttpTokens.LINE_FEED;
+import static org.eclipse.jetty.http.HttpTokens.SPACE;
+import static org.eclipse.jetty.http.HttpTokens.TAB;
+
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 
@@ -365,22 +370,22 @@
         
         if (_cr)
         {
-            if (ch!=HttpTokens.LINE_FEED)
+            if (ch!=LINE_FEED)
                 throw new BadMessage("Bad EOL");
             _cr=false;
             return ch;
         }
 
-        if (ch>=0 && ch<HttpTokens.SPACE)
+        if (ch>=0 && ch<SPACE)
         {
-            if (ch==HttpTokens.CARRIAGE_RETURN)
+            if (ch==CARRIAGE_RETURN)
             {
                 if (buffer.hasRemaining())
                 {
                     if(_maxHeaderBytes>0 && _state.ordinal()<State.END.ordinal())
                         _headerBytes++;
                     ch=buffer.get();
-                    if (ch!=HttpTokens.LINE_FEED)
+                    if (ch!=LINE_FEED)
                         throw new BadMessage("Bad EOL");
                 }
                 else
@@ -392,8 +397,8 @@
                 }
             }
             // Only LF or TAB acceptable special characters
-            else if (!(ch==HttpTokens.LINE_FEED || ch==HttpTokens.TAB))
-                throw new BadMessage("Illegal character");
+            else if (!(ch==LINE_FEED || ch==TAB))
+                throw new IllegalCharacter(ch,buffer);
         }
         
         return ch;
@@ -433,7 +438,7 @@
         {
             int ch=next(buffer);
 
-            if (ch > HttpTokens.SPACE)
+            if (ch > SPACE)
             {
                 _string.setLength(0);
                 _string.append((char)ch);
@@ -508,7 +513,7 @@
             switch (_state)
             {
                 case METHOD:
-                    if (ch == HttpTokens.SPACE)
+                    if (ch == SPACE)
                     {
                         _length=_string.length();
                         _methodString=takeString();
@@ -517,8 +522,13 @@
                             _methodString=method.asString();
                         setState(State.SPACE1);
                     }
-                    else if (ch < HttpTokens.SPACE)
-                        throw new BadMessage(ch<0?"Illegal character":"No URI");
+                    else if (ch < SPACE)
+                    {
+                        if (ch==LINE_FEED)
+                            throw new BadMessage("No URI");
+                        else
+                            throw new IllegalCharacter(ch,buffer);
+                    }
                     else
                         _string.append((char)ch);
                     break;
@@ -534,7 +544,7 @@
                         setState(State.SPACE1);
                     }
                     else if (ch < HttpTokens.SPACE)
-                        throw new BadMessage(ch<0?"Illegal character":"No Status");
+                        throw new IllegalCharacter(ch,buffer);
                     else
                         _string.append((char)ch);
                     break;
@@ -1147,8 +1157,8 @@
                             _length=_string.length();
                         break;
                     }
-                     
-                    throw new BadMessage("Illegal character");
+
+                    throw new IllegalCharacter(ch,buffer);
 
                 case HEADER_VALUE:
                     if (ch>HttpTokens.SPACE || ch<0)
@@ -1172,8 +1182,8 @@
                         setState(State.HEADER);
                         break; 
                     }
-
-                    throw new BadMessage("Illegal character");
+                    
+                    throw new IllegalCharacter(ch,buffer);
 
                 case HEADER_IN_VALUE:
                     if (ch>=HttpTokens.SPACE || ch<0 || ch==HttpTokens.TAB)
@@ -1201,7 +1211,8 @@
                         setState(State.HEADER);
                         break;
                     }
-                    throw new BadMessage("Illegal character");
+
+                    throw new IllegalCharacter(ch,buffer);
                     
                 default:
                     throw new IllegalStateException(_state.toString());
@@ -1578,6 +1589,29 @@
     }
 
     /* ------------------------------------------------------------------------------- */
+    public Trie<HttpField> getFieldCache()
+    {
+        return _connectionFields;
+    }
+
+    /* ------------------------------------------------------------------------------- */
+    private String getProxyField(ByteBuffer buffer)
+    {
+        _string.setLength(0);
+        _length=0;
+        
+        while (buffer.hasRemaining())
+        {
+            // process each character
+            byte ch=next(buffer);
+            if (ch<=' ')
+                return _string.toString();
+            _string.append((char)ch);    
+        }
+        throw new BadMessage();
+    }
+    
+    /* ------------------------------------------------------------------------------- */
     @Override
     public String toString()
     {
@@ -1632,11 +1666,17 @@
         public int getHeaderCacheSize();
     }
 
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
     public interface ProxyHandler 
     {
         void proxied(String protocol, String sAddr, String dAddr, int sPort, int dPort);
     }
-    
+
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
     public interface RequestHandler<T> extends HttpHandler<T>
     {
         /**
@@ -1657,6 +1697,9 @@
         public abstract boolean parsedHostHeader(String host,int port);
     }
 
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
     public interface ResponseHandler<T> extends HttpHandler<T>
     {
         /**
@@ -1665,24 +1708,14 @@
         public abstract boolean startResponse(HttpVersion version, int status, String reason);
     }
 
-    public Trie<HttpField> getFieldCache()
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    /* ------------------------------------------------------------------------------- */
+    private class IllegalCharacter extends BadMessage
     {
-        return _connectionFields;
-    }
-
-    private String getProxyField(ByteBuffer buffer)
-    {
-        _string.setLength(0);
-        _length=0;
-        
-        while (buffer.hasRemaining())
+        IllegalCharacter(byte ch,ByteBuffer buffer)
         {
-            // process each character
-            byte ch=next(buffer);
-            if (ch<=' ')
-                return _string.toString();
-            _string.append((char)ch);    
+            super(String.format("Illegal character 0x%x in state=%s in '%s'",ch,_state,BufferUtil.toDebugString(buffer)));
         }
-        throw new BadMessage();
     }
 }
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
index 0e6fd88..83b4dce 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java
@@ -21,6 +21,8 @@
 import java.io.Closeable;
 import java.io.IOException;
 import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
 import java.net.SocketTimeoutException;
 import java.nio.channels.CancelledKeyException;
 import java.nio.channels.SelectionKey;
@@ -39,6 +41,7 @@
 
 import org.eclipse.jetty.util.ConcurrentArrayQueue;
 import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.annotation.ManagedAttribute;
 import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.component.ContainerLifeCycle;
 import org.eclipse.jetty.util.component.Dumpable;
@@ -65,6 +68,7 @@
     private final ManagedSelector[] _selectors;
     private long _connectTimeout = DEFAULT_CONNECT_TIMEOUT;
     private long _selectorIndex;
+    private int _priorityDelta;
     
     protected SelectorManager(Executor executor, Scheduler scheduler)
     {
@@ -110,6 +114,42 @@
         _connectTimeout = milliseconds;
     }
 
+
+    @ManagedAttribute("The priority delta to apply to selector threads")
+    public int getSelectorPriorityDelta()
+    {
+        return _priorityDelta;
+    }
+
+    /**
+     * Sets the selector thread priority delta to the given amount.
+     * <p>This allows the selector threads to run at a different priority.
+     * Typically this would be used to lower the priority to give preference
+     * to handling previously accepted connections rather than accepting
+     * new connections.</p>
+     *
+     * @param selectorPriorityDelta the amount to change the thread priority
+     *                              delta to (may be negative)
+     * @see Thread#getPriority()
+     */
+    public void setSelectorPriorityDelta(int selectorPriorityDelta)
+    {
+        int oldDelta = _priorityDelta;
+        _priorityDelta = selectorPriorityDelta;
+        if (oldDelta != selectorPriorityDelta && isStarted())
+        {
+            for (ManagedSelector selector : _selectors)
+            {
+                Thread thread = selector._thread;
+                if (thread != null)
+                {
+                    int deltaDiff = selectorPriorityDelta - oldDelta;
+                    thread.setPriority(Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY, thread.getPriority() - deltaDiff)));
+                }
+            }
+        }
+    }
+    
     /**
      * Executes the given task in a different thread.
      *
@@ -140,11 +180,13 @@
 
     /**
      * <p>Registers a channel to perform a non-blocking connect.</p>
-     * <p>The channel must be set in non-blocking mode, and {@link SocketChannel#connect(SocketAddress)}
-     * must be called prior to calling this method.</p>
+     * <p>The channel must be set in non-blocking mode, {@link SocketChannel#connect(SocketAddress)}
+     * must be called prior to calling this method, and the connect operation must not be completed
+     * (the return value of {@link SocketChannel#connect(SocketAddress)} must be false).</p>
      *
      * @param channel    the channel to register
      * @param attachment the attachment object
+     * @see #accept(SocketChannel, Object)
      */
     public void connect(SocketChannel channel, Object attachment)
     {
@@ -153,16 +195,27 @@
     }
 
     /**
+     * @see #accept(SocketChannel, Object)
+     */
+    public void accept(SocketChannel channel)
+    {
+        accept(channel, null);
+    }
+
+    /**
      * <p>Registers a channel to perform non-blocking read/write operations.</p>
      * <p>This method is called just after a channel has been accepted by {@link ServerSocketChannel#accept()},
-     * or just after having performed a blocking connect via {@link Socket#connect(SocketAddress, int)}.</p>
+     * or just after having performed a blocking connect via {@link Socket#connect(SocketAddress, int)}, or
+     * just after a non-blocking connect via {@link SocketChannel#connect(SocketAddress)} that completed
+     * successfully.</p>
      *
      * @param channel the channel to register
+     * @param attachment the attachment object
      */
-    public void accept(final SocketChannel channel)
+    public void accept(SocketChannel channel, Object attachment)
     {
         final ManagedSelector selector = chooseSelector();
-        selector.submit(selector.new Accept(channel));
+        selector.submit(selector.new Accept(channel, attachment));
     }
     
     /**
@@ -173,7 +226,7 @@
      * 
      * @param server the server channel to register
      */
-    public void acceptor(final ServerSocketChannel server)
+    public void acceptor(ServerSocketChannel server)
     {
         final ManagedSelector selector = chooseSelector();
         selector.submit(selector.new Acceptor(server));
@@ -479,9 +532,13 @@
         {
             _thread = Thread.currentThread();
             String name = _thread.getName();
+            int priority = _thread.getPriority();
             try
             {
-                _thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id);
+                if (_priorityDelta != 0)
+                    _thread.setPriority(Math.max(Thread.MIN_PRIORITY, Math.min(Thread.MAX_PRIORITY, priority + _priorityDelta)));
+
+                _thread.setName(String.format("%s-selector-%s@%h/%d", name, SelectorManager.this.getClass().getSimpleName(), SelectorManager.this.hashCode(), _id));
                 if (LOG.isDebugEnabled())
                     LOG.debug("Starting {} on {}", _thread, this);
                 while (isRunning())
@@ -494,6 +551,8 @@
                 if (LOG.isDebugEnabled())
                     LOG.debug("Stopped {} on {}", _thread, this);
                 _thread.setName(name);
+                if (_priorityDelta != 0)
+                    _thread.setPriority(priority);
             }
         }
 
@@ -812,11 +871,13 @@
 
         private class Accept implements Runnable
         {
-            private final SocketChannel _channel;
+            private final SocketChannel channel;
+            private final Object attachment;
 
-            public Accept(SocketChannel channel)
+            private Accept(SocketChannel channel, Object attachment)
             {
-                this._channel = channel;
+                this.channel = channel;
+                this.attachment = attachment;
             }
 
             @Override
@@ -824,13 +885,13 @@
             {
                 try
                 {
-                    SelectionKey key = _channel.register(_selector, 0, null);
-                    EndPoint endpoint = createEndPoint(_channel, key);
+                    SelectionKey key = channel.register(_selector, 0, attachment);
+                    EndPoint endpoint = createEndPoint(channel, key);
                     key.attach(endpoint);
                 }
                 catch (Throwable x)
                 {
-                    closeNoExceptions(_channel);
+                    closeNoExceptions(channel);
                     LOG.debug(x);
                 }
             }
@@ -843,7 +904,7 @@
             private final Object attachment;
             private final Scheduler.Task timeout;
 
-            public Connect(SocketChannel channel, Object attachment)
+            private Connect(SocketChannel channel, Object attachment)
             {
                 this.channel = channel;
                 this.attachment = attachment;
@@ -863,7 +924,7 @@
                 }
             }
 
-            protected void failed(Throwable failure)
+            private void failed(Throwable failure)
             {
                 if (failed.compareAndSet(false, true))
                 {
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
index e599b27..18d4406 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
@@ -416,7 +416,10 @@
                 _scheduler = new ScheduledExecutorScheduler();
                 _ownScheduler = true;
                 _scheduler.start();
-            }
+            }   
+            else if (!_scheduler.isStarted())
+                throw new IllegalStateException("Shared scheduler not started");
+            
 
             //setup the scavenger thread
             if (_scavengePeriod > 0)
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
index b43ce73..0fe85f9 100644
--- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
+++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
@@ -250,15 +250,18 @@
             channel.socket().setTcpNoDelay(true);
             channel.configureBlocking(false);
             InetSocketAddress address = new InetSocketAddress(host, port);
-            channel.connect(address);
 
             AsyncContext asyncContext = request.startAsync();
             asyncContext.setTimeout(0);
 
             if (LOG.isDebugEnabled())
                 LOG.debug("Connecting to {}", address);
+
             ConnectContext connectContext = new ConnectContext(request, response, asyncContext, HttpConnection.getCurrentConnection());
-            selector.connect(channel, connectContext);
+            if (channel.connect(address))
+                selector.accept(channel, connectContext);
+            else
+                selector.connect(channel, connectContext);
         }
         catch (Exception x)
         {
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
index 40d99b0..bcbc106 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java
@@ -222,6 +222,7 @@
                 .timeout(5, TimeUnit.SECONDS)
                 .send();
 
+        Assert.assertEquals("OK", response.getReason());
         Assert.assertEquals(200, response.getStatus());
         Assert.assertTrue(response.getHeaders().containsKey(PROXIED_HEADER));
     }
diff --git a/jetty-server/src/main/config/etc/jetty-http.xml b/jetty-server/src/main/config/etc/jetty-http.xml
index c3f74f3..75012f3 100644
--- a/jetty-server/src/main/config/etc/jetty-http.xml
+++ b/jetty-server/src/main/config/etc/jetty-http.xml
@@ -22,6 +22,8 @@
     <Arg>
       <New class="org.eclipse.jetty.server.ServerConnector">
         <Arg name="server"><Ref refid="Server" /></Arg>
+        <Arg name="acceptors" type="int"><Property name="http.acceptors" default="-1"/></Arg>
+        <Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg>
         <Arg name="factories">
           <Array type="org.eclipse.jetty.server.ConnectionFactory">
             <Item>
@@ -35,6 +37,8 @@
         <Set name="port"><Property name="jetty.port" default="80" /></Set>
         <Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
         <Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set>
+        <Set name="acceptorPriorityDelta"><Property name="http.acceptorPriorityDelta" default="0"/></Set>
+        <Set name="selectorPriorityDelta"><Property name="http.selectorPriorityDelta" default="0"/></Set>
       </New>
     </Arg>
   </Call>
diff --git a/jetty-server/src/main/config/etc/jetty-https.xml b/jetty-server/src/main/config/etc/jetty-https.xml
index 419f8d1..a019cb9 100644
--- a/jetty-server/src/main/config/etc/jetty-https.xml
+++ b/jetty-server/src/main/config/etc/jetty-https.xml
@@ -23,26 +23,30 @@
     <Arg>
       <New class="org.eclipse.jetty.server.ServerConnector">
         <Arg name="server"><Ref refid="Server" /></Arg>
-          <Arg name="factories">
-            <Array type="org.eclipse.jetty.server.ConnectionFactory">
-              <Item>
-                <New class="org.eclipse.jetty.server.SslConnectionFactory">
-                  <Arg name="next">http/1.1</Arg>
-                  <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
-                </New>
-              </Item>
-              <Item>
-                <New class="org.eclipse.jetty.server.HttpConnectionFactory">
-                  <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
-                </New>
-              </Item>
-            </Array>
-          </Arg>
-          <Set name="host"><Property name="jetty.host" /></Set>
-          <Set name="port"><Property name="https.port" default="443" /></Set>
-          <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
-          <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
-        </New>
+        <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg>
+        <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
+        <Arg name="factories">
+          <Array type="org.eclipse.jetty.server.ConnectionFactory">
+            <Item>
+              <New class="org.eclipse.jetty.server.SslConnectionFactory">
+                <Arg name="next">http/1.1</Arg>
+                <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
+              </New>
+            </Item>
+            <Item>
+              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+                <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
+              </New>
+            </Item>
+          </Array>
+        </Arg>
+        <Set name="host"><Property name="jetty.host" /></Set>
+        <Set name="port"><Property name="https.port" default="443" /></Set>
+        <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
+        <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
+        <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set>
+        <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set>
+      </New>
     </Arg>
   </Call>
 </Configure>
diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod
index 8740af3c..dc34bc3 100644
--- a/jetty-server/src/main/config/modules/http.mod
+++ b/jetty-server/src/main/config/modules/http.mod
@@ -9,10 +9,19 @@
 etc/jetty-http.xml
 
 [ini-template]
-## HTTP Connector Configuration
-# HTTP port to listen on
+### HTTP Connector Configuration
+
+## HTTP port to listen on
 jetty.port=8080
-# HTTP idle timeout in milliseconds
+
+## HTTP idle timeout in milliseconds
 http.timeout=30000
-# HTTP Socket.soLingerTime in seconds. (-1 to disable)
+
+## HTTP Socket.soLingerTime in seconds. (-1 to disable)
 # http.soLingerTime=-1
+
+## Parameters to control the number and priority of acceptors and selectors
+# http.selectors=1
+# http.acceptors=1
+# http.selectorPriorityDelta=0
+# http.acceptorPriorityDelta=0
diff --git a/jetty-server/src/main/config/modules/ssl.mod b/jetty-server/src/main/config/modules/ssl.mod
index 449f581..ef47192 100644
--- a/jetty-server/src/main/config/modules/ssl.mod
+++ b/jetty-server/src/main/config/modules/ssl.mod
@@ -12,24 +12,29 @@
 http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/plain/jetty-server/src/main/config/etc/keystore|etc/keystore
 
 [ini-template]
-## SSL Keystore Configuration
+### SSL Keystore Configuration
 # define the port to use for secure redirection
 jetty.secure.port=8443
 
-# Setup a demonstration keystore and truststore
+## Setup a demonstration keystore and truststore
 jetty.keystore=etc/keystore
 jetty.truststore=etc/keystore
 
-# Set the demonstration passwords.
-# Note that OBF passwords are not secure, just protected from casual observation
-# See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
+## Set the demonstration passwords.
+## Note that OBF passwords are not secure, just protected from casual observation
+## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
 jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
 jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g
 jetty.truststore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
 
-# Set the client auth behavior
-# Set to true if client certificate authentication is required
+### Set the client auth behavior
+## Set to true if client certificate authentication is required
 # jetty.ssl.needClientAuth=true
-# Set to true if client certificate authentication is desired
+## Set to true if client certificate authentication is desired
 # jetty.ssl.wantClientAuth=true
 
+## Parameters to control the number and priority of acceptors and selectors
+# ssl.selectors=1
+# ssl.acceptors=1
+# ssl.selectorPriorityDelta=0
+# ssl.acceptorPriorityDelta=0
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index 3106eec..8607994 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -147,6 +147,7 @@
     private String _defaultProtocol;
     private ConnectionFactory _defaultConnectionFactory;
     private String _name;
+    private int _acceptorPriorityDelta;
 
 
     /**
@@ -399,6 +400,30 @@
         }
     }
 
+    @ManagedAttribute("The priority delta to apply to acceptor threads")
+    public int getAcceptorPriorityDelta()
+    {
+        return _acceptorPriorityDelta;
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Set the acceptor thread priority delta.
+     * <p>This allows the acceptor thread to run at a different priority.
+     * Typically this would be used to lower the priority to give preference 
+     * to handling previously accepted connections rather than accepting 
+     * new connections</p>
+     * @param acceptorPriorityDelta
+     */
+    public void setAcceptorPriorityDelta(int acceptorPriorityDelta)
+    {
+        int old=_acceptorPriorityDelta;
+        _acceptorPriorityDelta = acceptorPriorityDelta;
+        if (old!=acceptorPriorityDelta && isStarted())
+        {
+            for (Thread thread : _acceptors)
+                thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,thread.getPriority()-old+acceptorPriorityDelta)));
+        }
+    }
 
     @Override
     @ManagedAttribute("Protocols supported by this connector")
@@ -452,14 +477,18 @@
         @Override
         public void run()
         {
-            Thread current = Thread.currentThread();
-            String name=current.getName();
+            final Thread thread = Thread.currentThread();
+            String name=thread.getName();
             _name=String.format("%s-acceptor-%d@%x-%s",name,_acceptor,hashCode(),AbstractConnector.this.toString());
-            current.setName(_name);
+            thread.setName(_name);
+            
+            int priority=thread.getPriority();
+            if (_acceptorPriorityDelta!=0)
+                thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta)));
 
             synchronized (AbstractConnector.this)
             {
-                _acceptors[_acceptor] = current;
+                _acceptors[_acceptor] = thread;
             }
 
             try
@@ -481,7 +510,9 @@
             }
             finally
             {
-                current.setName(name);
+                thread.setName(name);
+                if (_acceptorPriorityDelta!=0)
+                    thread.setPriority(priority);
 
                 synchronized (AbstractConnector.this)
                 {
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
index ee99477..5307769 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java
@@ -149,6 +149,26 @@
     {
         return _transport;
     }
+
+    /**
+     * Get the idle timeout.
+     * <p>This is implemented as a call to {@link EndPoint#getIdleTimeout()}, but may be
+     * overridden by channels that have timeouts different from their connections.
+     */
+    public long getIdleTimeout()
+    {
+        return _endPoint.getIdleTimeout();
+    }
+
+    /**
+     * Set the idle timeout.
+     * <p>This is implemented as a call to {@link EndPoint#setIdleTimeout(long), but may be
+     * overridden by channels that have timeouts different from their connections.
+     */
+    public void setIdleTimeout(long timeoutMs)
+    {
+        _endPoint.setIdleTimeout(timeoutMs);
+    }
     
     public ByteBufferPool getByteBufferPool()
     {
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index d7cea8b..4454f01 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -24,6 +24,7 @@
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritePendingException;
 import java.util.concurrent.atomic.AtomicReference;
+
 import javax.servlet.ServletOutputStream;
 import javax.servlet.WriteListener;
 
@@ -52,7 +53,14 @@
 {
     private static Logger LOG = Log.getLogger(HttpOutput.class);
     private final HttpChannel<?> _channel;
-    private final SharedBlockingCallback _writeblock=new SharedBlockingCallback();
+    private final SharedBlockingCallback _writeblock=new SharedBlockingCallback()
+    {
+        @Override
+        protected long getIdleTimeout()
+        {
+            return _channel.getIdleTimeout();
+        }
+    };
     private long _written;
     private ByteBuffer _aggregate;
     private int _bufferSize;
@@ -770,14 +778,15 @@
                 }
                 continue;
             }
-
+            
             switch(_state.get())
             {
-                case READY:
                 case CLOSED:
                     // even though a write is not possible, because a close has 
                     // occurred, we need to call onWritePossible to tell async
                     // producer that the last write completed.
+                    // so fall through
+                case READY:
                     try
                     {
                         _writeListener.onWritePossible();
@@ -788,8 +797,9 @@
                         _onError=e;
                     }
                     break;
+                    
                 default:
-
+                    _onError=new IllegalStateException("state="+_state.get());
             }
         }
     }
@@ -834,7 +844,7 @@
         @Override
         public void onCompleteFailure(Throwable e)
         {
-            _onError=e;
+            _onError=e==null?new IOException():e;
             _channel.getState().onWritePossible();
         }
     }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
index 7058425..1a1f5a7 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpTransport.java
@@ -24,7 +24,7 @@
 import org.eclipse.jetty.util.Callback;
 
 public interface HttpTransport
-{
+{    
     void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback);
 
     void send(ByteBuffer content, boolean lastContent, Callback callback);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
index f4da30c..e37b27d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java
@@ -113,6 +113,26 @@
     {
         this(server,null,null,null,acceptors,selectors,new HttpConnectionFactory());
     }
+    
+    /* ------------------------------------------------------------ */
+    /** HTTP Server Connection.
+     * <p>Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.</p>
+     * @param server The {@link Server} this connector will accept connection for. 
+     * @param acceptors 
+     *          the number of acceptor threads to use, or -1 for a default value. Acceptors accept new TCP/IP connections.  If 0, then 
+     *          the selector threads are used to accept connections.
+     * @param selectors
+     *          the number of selector threads, or -1 for a default value. Selectors notice and schedule established connection that can make IO progress.
+     * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections.
+     */
+    public ServerConnector(
+        @Name("server") Server server,
+        @Name("acceptors") int acceptors,
+        @Name("selectors") int selectors,
+        @Name("factories") ConnectionFactory... factories)
+    {
+        this(server,null,null,null,acceptors,selectors,factories);
+    }
 
     /* ------------------------------------------------------------ */
     /** Generic Server Connection with default configuration.
@@ -229,6 +249,29 @@
         return channel!=null && channel.isOpen();
     }
 
+
+    @ManagedAttribute("The priority delta to apply to selector threads")
+    public int getSelectorPriorityDelta()
+    {
+        return _manager.getSelectorPriorityDelta();
+    }
+
+    /**
+     * Sets the selector thread priority delta to the given amount.
+     * <p>This allows the selector threads to run at a different priority.
+     * Typically this would be used to lower the priority to give preference 
+     * to handling previously accepted connections rather than accepting
+     * new connections.</p>
+     *
+     * @param selectorPriorityDelta the amount to set the thread priority delta to
+     *                              (may be negative)
+     * @see Thread#getPriority()
+     */
+    public void setSelectorPriorityDelta(int selectorPriorityDelta)
+    {
+        _manager.setSelectorPriorityDelta(selectorPriorityDelta);
+    }
+    
     /**
      * @return whether this connector uses a channel inherited from the JVM.
      * @see System#inheritedChannel()
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
index 04a90f1..e0b0276 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java
@@ -27,6 +27,7 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.HttpChannel;
 import org.eclipse.jetty.server.HttpConnection;
 import org.eclipse.jetty.server.Request;
 
@@ -79,17 +80,9 @@
     @Override
     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
     {
-        HttpConnection connection = HttpConnection.getCurrentConnection();
-        final EndPoint endp = connection==null?null:connection.getEndPoint();
-        
-        final long idle_timeout;
-        if (endp==null)
-            idle_timeout=-1;
-        else
-        {
-            idle_timeout=endp.getIdleTimeout();
-            endp.setIdleTimeout(_idleTimeoutMs);
-        }
+        final HttpChannel<?> channel = baseRequest.getHttpChannel();
+        final long idle_timeout=baseRequest.getHttpChannel().getIdleTimeout();
+        channel.setIdleTimeout(_idleTimeoutMs);
         
         try
         {
@@ -97,8 +90,6 @@
         }
         finally
         {
-            if (endp!=null)
-            {
                 if (_applyToAsync && request.isAsyncStarted())
                 {
                     request.getAsyncContext().addListener(new AsyncListener()
@@ -116,19 +107,18 @@
                         @Override
                         public void onError(AsyncEvent event) throws IOException
                         {
-                            endp.setIdleTimeout(idle_timeout);
+                            channel.setIdleTimeout(idle_timeout);
                         }
                         
                         @Override
                         public void onComplete(AsyncEvent event) throws IOException
                         {
-                            endp.setIdleTimeout(idle_timeout);
+                            channel.setIdleTimeout(idle_timeout);
                         }
                     });
                 }
                 else 
-                    endp.setIdleTimeout(idle_timeout);
-            }
+                    channel.setIdleTimeout(idle_timeout);
         }
     }
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 535dc5f..434cf9d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -992,6 +992,8 @@
              _ownScheduler = true;
              _scheduler.start();
          }
+         else if (!_scheduler.isStarted())
+             throw new IllegalStateException("Shared scheduler not started");
   
         setScavengeInterval(getScavengeInterval());
     }
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
index b810e5c..43e7c36 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
@@ -156,7 +156,6 @@
                 channel.bind(bindAddress);
             configure(channel);
             channel.configureBlocking(false);
-            channel.connect(address);
 
             context.put(SslClientConnectionFactory.SSL_PEER_HOST_CONTEXT_KEY, ((InetSocketAddress)address).getHostString());
             context.put(SslClientConnectionFactory.SSL_PEER_PORT_CONTEXT_KEY, ((InetSocketAddress)address).getPort());
@@ -164,7 +163,10 @@
             context.put(SPDYClientConnectionFactory.SPDY_SESSION_LISTENER_CONTEXT_KEY, listener);
             context.put(SPDYClientConnectionFactory.SPDY_SESSION_PROMISE_CONTEXT_KEY, promise);
 
-            factory.selector.connect(channel, context);
+            if (channel.connect(address))
+                factory.selector.accept(channel, context);
+            else
+                factory.selector.connect(channel, context);
         }
         catch (IOException x)
         {
diff --git a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
index 040aad1..49024a7 100644
--- a/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
+++ b/jetty-spdy/spdy-http-server/src/main/config/modules/protonego-impl/npn.mod
@@ -29,3 +29,9 @@
 [files]
 lib/
 lib/npn/
+
+[license]
+NPN is a hosted at github under the GPL v2 with ClassPath Exception.
+NPN replaces/modified OpenJDK classes in the java.sun.security.ssl package.
+http://github.com/jetty-project/jetty-npn
+http://openjdk.java.net/legal/gplv2+ce.html
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
index 3a19386..113e31e 100644
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
+++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpChannelOverSPDY.java
@@ -53,6 +53,12 @@
     }
 
     @Override
+    public long getIdleTimeout()
+    {
+        return stream.getIdleTimeout();
+    }
+    
+    @Override
     public boolean headerComplete()
     {
         headersComplete = true;
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
index ce4cf60..22b8377 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java
@@ -86,6 +86,8 @@
 
     public static String join(Collection<?> objs, String delim)
     {
+        if (objs==null)
+            return "";
         StringBuilder str = new StringBuilder();
         boolean needDelim = false;
         for (Object obj : objs)
@@ -392,17 +394,45 @@
         }
 
         boolean transitive = module.isEnabled() && (module.getSources().size() == 0);
-        boolean hasDefinedDefaults = module.getDefaultConfig().size() > 0;
-
-        // If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist
-        if (!module.isEnabled() || (transitive && (hasDefinedDefaults || module.hasLicense()) ) || (topLevel && !FS.exists(startd_ini) && !appendStartIni))
+        boolean buildIni=false;
+        if (module.isEnabled())
+        {
+            // is it an explicit request to create an ini file?
+            if (topLevel && !FS.exists(startd_ini) && !appendStartIni)
+                buildIni=true;
+            
+            // else is it transitive 
+            else if (transitive) 
+            {
+                // do we need an ini anyway?
+                if (module.hasDefaultConfig() || module.hasLicense()) 
+                    buildIni=true;
+                else
+                    StartLog.info("%-15s initialised transitively",name);
+            }
+            
+            // else must be initialized explicitly
+            else 
+            {
+                for (String source : module.getSources())
+                    StartLog.info("%-15s initialised in %s",name,baseHome.toShortForm(source));
+            }
+        }
+        else 
+        {
+            buildIni=true;
+        }
+        
+        
+        // If we need an ini
+        if (buildIni)
         {
             if (module.hasLicense())
             {
-                System.err.printf("%nModule %s LICENSE%n",module.getName());
-                System.err.printf("This module is not provided by the Eclipse Foundation!%n");
-                System.err.printf("It contains software not covered by the Eclipse Public License%n");
-                System.err.printf("The software has not been audited for compliance with its license%n");
+                System.err.printf("%nModule %s:%n",module.getName());
+                System.err.printf(" + contains software not provided by the Eclipse Foundation!%n");
+                System.err.printf(" + contains software not covered by the Eclipse Public License!%n");
+                System.err.printf(" + has not been audited for compliance with its license%n");
                 System.err.printf("%n");
                 for (String l : module.getLicense())
                     System.err.printf("    %s%n",l);
@@ -484,14 +514,6 @@
                 }
             }
         }
-        else if (FS.exists(startd_ini))
-        {
-            StartLog.info("%-15s initialised in %s",name,short_startd_ini);
-        }
-        else
-        {
-            StartLog.info("%-15s initialised transitively",name);
-        }
         
         // Also list other places this module is enabled
         for (String source : module.getSources())
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
index 3b1f79e..a55fd9e 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java
@@ -265,6 +265,12 @@
         }
     }
 
+    public void enable(String name) throws IOException
+    {
+        List<String> empty = Collections.emptyList();
+        enable(name,empty);
+    }
+    
     public void enable(String name, List<String> sources) throws IOException
     {
         if (name.contains("*"))
@@ -310,9 +316,14 @@
 
     private void enableModule(Module module, List<String> sources) throws IOException
     {
+        // Always add the sources
+        if (sources != null)
+            module.addSources(sources);
+        
+        // If already enabled, nothing else to do
         if (module.isEnabled())
         {
-            // already enabled, skip
+            StartLog.debug("Enabled  module: %s (via %s)",module.getName(),Main.join(sources,", "));
             return;
         }
         
@@ -320,10 +331,6 @@
         module.setEnabled(true);
         args.parseModule(module);
         module.expandProperties(args.getProperties());
-        if (sources != null)
-        {
-            module.addSources(sources);
-        }
         
         // enable any parents that haven't been enabled (yet)
         Set<String> parentNames = new HashSet<>();
@@ -349,7 +356,7 @@
             }
             if (parent != null)
             {
-                enableModule(parent,sources);
+                enableModule(parent,null);
             }
         }
     }
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
index 53d24db..7f0b785 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java
@@ -920,6 +920,11 @@
         return builder.toString();
     }
 
+    /* ------------------------------------------------------------ */
+    /** Convert Buffer to a detail debug string of pointers and content
+     * @param buffer
+     * @return A string showing the pointers and content of the buffer
+     */
     public static String toDetailString(ByteBuffer buffer)
     {
         if (buffer == null)
@@ -942,15 +947,33 @@
         buf.append(buffer.remaining());
         buf.append("]={");
 
+        appendDebugString(buf,buffer);
+
+        buf.append("}");
+
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Convert buffer to a Debug String.
+     * @param buffer
+     * @return A string showing the escaped content of the buffer around the
+     * position and limit (marked with &lt;&lt;&lt; and &gt;&gt;&gt;)
+     */
+    public static String toDebugString(ByteBuffer buffer)
+    {
+        if (buffer == null)
+            return "null";
+        StringBuilder buf = new StringBuilder();
+        appendDebugString(buf,buffer);
+        return buf.toString();
+    }
+    
+    private static void appendDebugString(StringBuilder buf,ByteBuffer buffer)
+    {
         for (int i = 0; i < buffer.position(); i++)
         {
-            char c = (char)buffer.get(i);
-            if (c >= ' ' && c <= 127)
-                buf.append(c);
-            else if (c == '\r' || c == '\n')
-                buf.append('|');
-            else
-                buf.append('\ufffd');
+            appendContentChar(buf,buffer.get(i));
             if (i == 16 && buffer.position() > 32)
             {
                 buf.append("...");
@@ -960,13 +983,7 @@
         buf.append("<<<");
         for (int i = buffer.position(); i < buffer.limit(); i++)
         {
-            char c = (char)buffer.get(i);
-            if (c >= ' ' && c <= 127)
-                buf.append(c);
-            else if (c == '\r' || c == '\n')
-                buf.append('|');
-            else
-                buf.append('\ufffd');
+            appendContentChar(buf,buffer.get(i));
             if (i == buffer.position() + 16 && buffer.limit() > buffer.position() + 32)
             {
                 buf.append("...");
@@ -978,13 +995,7 @@
         buffer.limit(buffer.capacity());
         for (int i = limit; i < buffer.capacity(); i++)
         {
-            char c = (char)buffer.get(i);
-            if (c >= ' ' && c <= 127)
-                buf.append(c);
-            else if (c == '\r' || c == '\n')
-                buf.append('|');
-            else
-                buf.append('\ufffd');
+            appendContentChar(buf,buffer.get(i));
             if (i == limit + 16 && buffer.capacity() > limit + 32)
             {
                 buf.append("...");
@@ -992,11 +1003,23 @@
             }
         }
         buffer.limit(limit);
-        buf.append("}");
-
-        return buf.toString();
     }
 
+    private static void appendContentChar(StringBuilder buf, byte b)
+    {
+        if (b == '\\')
+            buf.append("\\\\");   
+        else if (b >= ' ')
+            buf.append((char)b);
+        else if (b == '\r')
+            buf.append("\\r");
+        else if (b == '\n')
+            buf.append("\\n");
+        else if (b == '\t')
+            buf.append("\\t");
+        else
+            buf.append("\\x").append(TypeUtil.toHexString(b));
+    }
 
     private final static int[] decDivisors =
             {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java b/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
index 55aab63..becabc1 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java
@@ -20,6 +20,7 @@
 
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -124,8 +125,8 @@
     @Override
     protected void doStop() throws Exception
     {
-        thread.interrupt();
         super.doStop();
+        thread.interrupt();
     }
 
     @Override
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
index 1813f57..1c4ff34 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java
@@ -23,6 +23,7 @@
 import java.io.InterruptedIOException;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -47,7 +48,11 @@
  */
 public class SharedBlockingCallback
 {
-    private static final Logger LOG = Log.getLogger(SharedBlockingCallback.class);
+    static final Logger LOG = Log.getLogger(SharedBlockingCallback.class);
+
+    final ReentrantLock _lock = new ReentrantLock();
+    final Condition _idle = _lock.newCondition();
+    final Condition _complete = _lock.newCondition();
 
     
     private static Throwable IDLE = new Throwable()
@@ -77,56 +82,64 @@
         }
     };
 
-    final Blocker _blocker;
+    Blocker _blocker;
     
     public SharedBlockingCallback()
     {
-        this(new Blocker());
+        _blocker=new Blocker();
     }
     
-    protected SharedBlockingCallback(Blocker blocker)
+    protected long getIdleTimeout()
     {
-        _blocker=blocker;
+        return -1;
     }
     
     public Blocker acquire() throws IOException
     {
-        _blocker._lock.lock();
+        _lock.lock();
+        long idle = getIdleTimeout();
         try
         {
             while (_blocker._state != IDLE)
-                _blocker._idle.await();
+            {
+                if (idle>0)
+                {
+                    // Wait a little bit longer than the blocker might block
+                    if (!_idle.await(idle*2,TimeUnit.MILLISECONDS))
+                        throw new IOException(new TimeoutException());
+                }
+                else
+                    _idle.await();
+            }
             _blocker._state = null;
         }
         catch (final InterruptedException e)
         {
-            throw new InterruptedIOException()
-            {
-                {
-                    initCause(e);
-                }
-            };
+            throw new InterruptedIOException();
         }
         finally
         {
-            _blocker._lock.unlock();
+            _lock.unlock();
         }
         return _blocker;
     }
 
+    protected void notComplete(Blocker blocker)
+    {
+        LOG.warn("Blocker not complete {}",blocker);
+        if (LOG.isDebugEnabled())
+            LOG.debug(new Throwable());
+    }
     
     /* ------------------------------------------------------------ */
     /** A Closeable Callback.
      * Uses the auto close mechanism to check block has been called OK.
      */
-    public static class Blocker implements Callback, Closeable
+    public class Blocker implements Callback, Closeable
     {
-        final ReentrantLock _lock = new ReentrantLock();
-        final Condition _idle = _lock.newCondition();
-        final Condition _complete = _lock.newCondition();
         Throwable _state = IDLE;
-
-        public Blocker()
+        
+        protected Blocker()
         {
         }
 
@@ -141,8 +154,8 @@
                     _state = SUCCEEDED;
                     _complete.signalAll();
                 }
-                else if (_state == IDLE)
-                    throw new IllegalStateException("IDLE");
+                else
+                    throw new IllegalStateException(_state);
             }
             finally
             {
@@ -158,11 +171,17 @@
             {
                 if (_state == null)
                 {
-                    _state = cause==null?FAILED:cause;
+                    if (cause==null)
+                        _state=FAILED;
+                    else if (cause instanceof BlockerTimeoutException)
+                        // Not this blockers timeout
+                        _state=new IOException(cause);
+                    else 
+                        _state=cause;
                     _complete.signalAll();
                 }
-                else if (_state == IDLE)
-                    throw new IllegalStateException("IDLE",cause);
+                else 
+                    throw new IllegalStateException(_state);
             }
             finally
             {
@@ -183,10 +202,22 @@
                 LOG.warn("Blocking a NonBlockingThread: ",new Throwable());
             
             _lock.lock();
+            long idle = getIdleTimeout();
             try
             {
                 while (_state == null)
-                    _complete.await();
+                {
+                    if (idle>0)
+                    {
+                        // Wait a little bit longer than expected callback idle timeout
+                        if (!_complete.await(idle+idle/2,TimeUnit.MILLISECONDS))
+                            // The callback has not arrived in sufficient time.
+                            // We will synthesize a TimeoutException 
+                            _state=new BlockerTimeoutException();
+                    }
+                    else
+                        _complete.await();
+                }
 
                 if (_state == SUCCEEDED)
                     return;
@@ -204,12 +235,7 @@
             }
             catch (final InterruptedException e)
             {
-                throw new InterruptedIOException()
-                {
-                    {
-                        initCause(e);
-                    }
-                };
+                throw new InterruptedIOException();
             }
             finally
             {
@@ -232,17 +258,19 @@
                 if (_state == IDLE)
                     throw new IllegalStateException("IDLE");
                 if (_state == null)
-                {
-                    LOG.warn("Blocker not complete {}",this);
-                    if (LOG.isDebugEnabled())
-                        LOG.debug(new Throwable());
-                }
+                    notComplete(this);
             }
             finally
             {
                 try 
                 {
-                    _state = IDLE;
+                    // If the blocker timed itself out, remember the state
+                    if (_state instanceof BlockerTimeoutException)
+                        // and create a new Blocker
+                        _blocker=new Blocker();
+                    else
+                        // else reuse Blocker
+                        _state = IDLE;
                     _idle.signalAll();
                     _complete.signalAll();
                 } 
@@ -267,4 +295,8 @@
             }
         }
     }
+    
+    private class BlockerTimeoutException extends TimeoutException
+    { 
+    }
 }
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
index 79629eb..1e81258 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java
@@ -479,7 +479,10 @@
                     @Override
                     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');
+                        out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle ? " IDLE" : "");
+                        if (thread.getPriority()!=Thread.NORM_PRIORITY)
+                            out.append(" prio="+thread.getPriority());
+                        out.append('\n');
                         if (!idle)
                             ContainerLifeCycle.dump(out, indent, Arrays.asList(trace));
                     }
@@ -493,7 +496,8 @@
             }
             else
             {
-                dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : ""));
+                int p=thread.getPriority();
+                dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : "")+ (p==Thread.NORM_PRIORITY?"":(" prio="+p)));
             }
         }
 
diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
index 4ee93a6..c06e507 100644
--- a/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
+++ b/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java
@@ -18,9 +18,17 @@
 
 package org.eclipse.jetty.util;
 
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.eclipse.jetty.util.SharedBlockingCallback.Blocker;
 import org.hamcrest.Matchers;
@@ -29,7 +37,23 @@
 
 public class SharedBlockingCallbackTest
 {
-    final SharedBlockingCallback sbcb= new SharedBlockingCallback();
+    final AtomicInteger notComplete = new AtomicInteger();
+    final SharedBlockingCallback sbcb= new SharedBlockingCallback()
+    {
+        @Override
+        protected long getIdleTimeout()
+        {
+            return 150;
+        }
+
+        @Override
+        protected void notComplete(Blocker blocker)
+        {
+            super.notComplete(blocker);
+            notComplete.incrementAndGet();
+        }
+
+    };
     
     public SharedBlockingCallbackTest()
     {
@@ -46,7 +70,8 @@
             start=System.currentTimeMillis();
             blocker.block();
         }
-        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));     
+        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));  
+        Assert.assertEquals(0,notComplete.get());   
     }
     
     @Test
@@ -74,6 +99,7 @@
         }
         Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L)); 
         Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L)); 
+        Assert.assertEquals(0,notComplete.get());   
     }
     
     @Test
@@ -95,7 +121,8 @@
             start=System.currentTimeMillis();
             Assert.assertEquals(ex,ee.getCause());
         }
-        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(100L));     
+        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(100L));    
+        Assert.assertEquals(0,notComplete.get());    
     }
     
     @Test
@@ -133,6 +160,7 @@
         }
         Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L)); 
         Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
+        Assert.assertEquals(0,notComplete.get());   
     }
 
 
@@ -174,6 +202,58 @@
             blocker.succeeded();
             blocker.block();
         };
-        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(600L));   
+        Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(600L)); 
+        Assert.assertEquals(0,notComplete.get());     
+    }
+
+    @Test
+    public void testBlockerClose() throws Exception
+    {
+        try (Blocker blocker=sbcb.acquire())
+        {
+            SharedBlockingCallback.LOG.info("Blocker not complete "+blocker+" warning is expected...");
+        }
+        
+        Assert.assertEquals(1,notComplete.get());
+    }
+    
+    @Test
+    public void testBlockerTimeout() throws Exception
+    {
+        Blocker b0=null;
+        try
+        {
+            try (Blocker blocker=sbcb.acquire())
+            {
+                b0=blocker;
+                Thread.sleep(400);
+                blocker.block();
+            }
+            fail();
+        }
+        catch(IOException e)
+        {
+            Throwable cause = e.getCause();
+            assertThat(cause,instanceOf(TimeoutException.class));
+        }
+        
+        Assert.assertEquals(0,notComplete.get());
+        
+
+        try (Blocker blocker=sbcb.acquire())
+        {
+            assertThat(blocker,not(equalTo(b0)));
+            try
+            {
+                b0.succeeded();
+                fail();
+            }
+            catch(Exception e)
+            {
+                assertThat(e,instanceOf(IllegalStateException.class));
+                assertThat(e.getCause(),instanceOf(TimeoutException.class));
+            }
+            blocker.succeeded();
+        }
     }
 }
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
index 4617c02..b229101 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java
@@ -71,6 +71,17 @@
             useContainerCache = attr.booleanValue();
         
         if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache);
+        
+        //pre-emptively create empty lists for tlds, fragments and resources as context attributes
+        //this signals that this class has been called. This differentiates the case where this class
+        //has been called but finds no META-INF data from the case where this class was never called
+        if (context.getAttribute(METAINF_TLDS) == null)
+            context.setAttribute(METAINF_TLDS, new HashSet<URL>());
+        if (context.getAttribute(METAINF_RESOURCES) == null)
+            context.setAttribute(METAINF_RESOURCES, new HashSet<Resource>());
+        if (context.getAttribute(METAINF_FRAGMENTS) == null)
+            context.setAttribute(METAINF_FRAGMENTS, new HashMap<Resource, Resource>());
+       
         scanJars(context, context.getMetaData().getContainerResources(), useContainerCache);
         scanJars(context, context.getMetaData().getWebInfJars(), false);
     }
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
index 487002f..729483c 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebDescriptor.java
@@ -251,7 +251,7 @@
            }
         }
 
-        if (_majorVersion < 2 && _minorVersion < 5)
+        if (_majorVersion <= 2 && _minorVersion < 5)
             _metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
         else
         {
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
index 1e4096c..1e68b19 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java
@@ -175,7 +175,7 @@
         // Look for extra resource
         @SuppressWarnings("unchecked")
         Set<Resource> resources = (Set<Resource>)context.getAttribute(RESOURCE_DIRS);
-        if (resources!=null)
+        if (resources!=null && !resources.isEmpty())
         {
             Resource[] collection=new Resource[resources.size()+1];
             int i=0;
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
index ab20d77..cb04029 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
@@ -74,8 +74,14 @@
 
                 InetSocketAddress address = toSocketAddress(wsUri);
 
-                channel.connect(address);
-                getSelector().connect(channel,this);
+                if (channel.connect(address))
+                {
+                    getSelector().accept(channel, this);
+                }
+                else
+                {
+                    getSelector().connect(channel, this);
+                }
             }
             catch (Throwable t)
             {
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
index 4fdc680..838afc9 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/BlockingWriteCallback.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 
+import org.eclipse.jetty.util.Callback;
 import org.eclipse.jetty.util.SharedBlockingCallback;
 import org.eclipse.jetty.websocket.api.WriteCallback;
 
@@ -31,26 +32,55 @@
 {
     public BlockingWriteCallback()
     {
-        super(new WriteBlocker());
     }
         
     public WriteBlocker acquireWriteBlocker() throws IOException
     {
-        return (WriteBlocker)acquire();
+        return new WriteBlocker(acquire());
     }
     
-    public static class WriteBlocker extends Blocker implements WriteCallback
+    public static class WriteBlocker implements WriteCallback, Callback, AutoCloseable
     {
+        Blocker blocker;
+        
+        WriteBlocker(Blocker blocker)
+        {
+            this.blocker=blocker;
+        }
+        
         @Override
         public void writeFailed(Throwable x)
         {
-            failed(x);
+            blocker.failed(x);
         }
 
         @Override
         public void writeSuccess()
         {
-            succeeded();
+            blocker.succeeded();
+        }
+
+        @Override
+        public void succeeded()
+        {
+            blocker.succeeded();
+        }
+
+        @Override
+        public void failed(Throwable x)
+        {
+            blocker.failed(x);
+        }
+        
+        @Override
+        public void close() throws IOException
+        {
+            blocker.close();
+        }
+        
+        public void block() throws IOException
+        {
+            blocker.block();
         }
     }
 }
diff --git a/tests/pom.xml b/tests/pom.xml
index de745ca..9524a5d 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -47,5 +47,6 @@
     <module>test-continuation</module>
     <module>test-loginservice</module>
     <module>test-integration</module>
+    <module>test-quickstart</module>
   </modules>
 </project>
diff --git a/examples/quickstart/pom.xml b/tests/test-quickstart/pom.xml
similarity index 91%
rename from examples/quickstart/pom.xml
rename to tests/test-quickstart/pom.xml
index 08e4695..2874c68 100644
--- a/examples/quickstart/pom.xml
+++ b/tests/test-quickstart/pom.xml
@@ -1,22 +1,21 @@
 <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.examples</groupId>
-    <artifactId>examples-parent</artifactId>
+    <groupId>org.eclipse.jetty.tests</groupId>
+    <artifactId>tests-parent</artifactId>
     <version>9.2.3-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.eclipse.jetty</groupId>
-  <artifactId>example-jetty-quickstart</artifactId>
-  <name>Example :: Jetty Quick Start</name>
-  <description>Jetty Quick Start Example</description>
+  <artifactId>test-quickstart</artifactId>
+  <name>Test :: Jetty Quick Start</name>
+  <description>Jetty Quick Start Test</description>
   <url>http://www.eclipse.org/jetty</url>
   <dependencies>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-quickstart</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
@@ -42,75 +41,63 @@
       <groupId>javax.transaction</groupId>
       <artifactId>javax.transaction-api</artifactId>
       <version>1.2</version>
-      <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.tests</groupId>
       <artifactId>test-mock-resources</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.orbit</groupId>
       <artifactId>javax.mail.glassfish</artifactId>
       <version>1.4.1.v201005082020</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-servlets</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.tests</groupId>
       <artifactId>test-jndi-webapp</artifactId>
       <version>${project.version}</version>
       <type>war</type>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.tests</groupId>
       <artifactId>test-spec-webapp</artifactId>
       <version>${project.version}</version>
       <type>war</type>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>test-jetty-webapp</artifactId>
       <version>${project.version}</version>
       <type>war</type>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.websocket</groupId>
       <artifactId>javax-websocket-server-impl</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.websocket</groupId>
       <artifactId>websocket-server</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>apache-jsp</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>apache-jstl</artifactId>
       <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jetty.toolchain</groupId>
       <artifactId>jetty-test-helper</artifactId>
-      <scope>test</scope>
     </dependency>
     
   </dependencies>
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureJNDIWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureSpecWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/PreconfigureStandardTestWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartJNDIWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartSpecWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartStandardTestWar.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/QuickStartTest.java
diff --git a/examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java b/tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
similarity index 100%
rename from examples/quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
rename to tests/test-quickstart/src/test/java/org/eclipse/jetty/quickstart/Quickstart.java
diff --git a/examples/quickstart/src/test/resources/realm.properties b/tests/test-quickstart/src/test/resources/realm.properties
similarity index 100%
rename from examples/quickstart/src/test/resources/realm.properties
rename to tests/test-quickstart/src/test/resources/realm.properties
diff --git a/examples/quickstart/src/test/resources/test-jndi.xml b/tests/test-quickstart/src/test/resources/test-jndi.xml
similarity index 100%
rename from examples/quickstart/src/test/resources/test-jndi.xml
rename to tests/test-quickstart/src/test/resources/test-jndi.xml
diff --git a/examples/quickstart/src/test/resources/test-spec.xml b/tests/test-quickstart/src/test/resources/test-spec.xml
similarity index 100%
rename from examples/quickstart/src/test/resources/test-spec.xml
rename to tests/test-quickstart/src/test/resources/test-spec.xml
diff --git a/examples/quickstart/src/test/resources/test.xml b/tests/test-quickstart/src/test/resources/test.xml
similarity index 96%
rename from examples/quickstart/src/test/resources/test.xml
rename to tests/test-quickstart/src/test/resources/test.xml
index bbdf08a..41eba0c 100644
--- a/examples/quickstart/src/test/resources/test.xml
+++ b/tests/test-quickstart/src/test/resources/test.xml
@@ -30,6 +30,8 @@
     <Set name="checkWelcomeFiles">true</Set>
   </Get>
 
+  <Set name="parentLoaderPriority">true</Set>
+
   <!-- Non standard error page mapping -->
   <!--
   <Get name="errorHandler">
diff --git a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini
deleted file mode 100644
index 9607fd2..0000000
--- a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# HTTP connector
-#
---module=http
-jetty.port=8080
-