alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (java5.patch)

This example Jetty source code file (java5.patch) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

concurrenthashmap, hashmap, index, index, list, map, object, string, string, stringbuffer, stringbuffer, stringbuilder, stringbuilder, the

The Jetty java5.patch source code

Index: modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java
===================================================================
--- modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java	(revision 2256)
+++ modules/jetty/src/test/java/org/mortbay/jetty/HttpServerTestBase.java	(working copy)
@@ -236,7 +236,7 @@
             {
 
                 int[] points=new int[pointCount];
-                StringBuffer message=new StringBuffer();
+                StringBuilder message=new StringBuilder();
 
                 message.append("iteration #"+(i+1));
 
@@ -281,7 +281,7 @@
             for (int i=0; i<bytes.length; i+=3)
             {
                 int[] points=new int[] { i };
-                StringBuffer message=new StringBuffer();
+                StringBuilder message=new StringBuilder();
 
                 message.append("iteration #"+(i+1));
 
@@ -333,7 +333,7 @@
             {
                 Socket client=new Socket(HOST,port);
                 OutputStream os=client.getOutputStream();
-                StringBuffer message=new StringBuffer();
+                StringBuilder message=new StringBuilder();
 
                 message.append("iteration #"+(i+1));
                 writeFragments(bytes,badPoints[i],message,os);
@@ -691,7 +691,7 @@
         {
             br=new BufferedReader(new InputStreamReader(client.getInputStream()));
 
-            StringBuffer sb=new StringBuffer();
+            StringBuilder sb=new StringBuilder();
             String line;
 
             while ((line=br.readLine())!=null)
@@ -738,7 +738,7 @@
         return server;
     }
 
-    private void writeFragments(byte[] bytes, int[] points, StringBuffer message, OutputStream os) throws IOException, InterruptedException
+    private void writeFragments(byte[] bytes, int[] points, StringBuilder message, OutputStream os) throws IOException, InterruptedException
     {
         int last=0;
 
Index: modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/NCSARequestLog.java	(working copy)
@@ -226,76 +226,74 @@
             if (_fileOut == null)
                 return;
 
-            StringBuffer buf = new StringBuffer(160);
+            StringBuilder buf = new StringBuilder(160);
             String log =null;
-            synchronized(buf) // for efficiency until we can use StringBuilder
+            if (_logServer)
             {
-                if (_logServer)
-                {
-                    buf.append(request.getServerName());
-                    buf.append(' ');
-                }
+                buf.append(request.getServerName());
+                buf.append(' ');
+            }
 
-                String addr = null;
-                if (_preferProxiedForAddress) 
-                {
-                    addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
-                }
+            String addr = null;
+            if (_preferProxiedForAddress) 
+            {
+                addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
+            }
 
-                if (addr == null) 
-                    addr = request.getRemoteAddr();
+            if (addr == null) 
+                addr = request.getRemoteAddr();
 
-                buf.append(addr);
-                buf.append(" - ");
-                String user = request.getRemoteUser();
-                buf.append((user == null)? " - " : user);
-                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());
-                buf.append(' ');
-                buf.append(request.getProtocol());
-                buf.append("\" ");
-                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)));
+            buf.append(addr);
+            buf.append(" - ");
+            String user = request.getRemoteUser();
+            buf.append((user == null)? " - " : user);
+            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());
+            buf.append(' ');
+            buf.append(request.getProtocol());
+            buf.append("\" ");
+            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)));
 
-                long responseLength=response.getContentCount();
-                if (responseLength >=0)
+
+            long responseLength=response.getContentCount();
+            if (responseLength >=0)
+            {
+                buf.append(' ');
+                if (responseLength > 99999)
+                    buf.append(Long.toString(responseLength));
+                else 
                 {
-                    buf.append(' ');
-                    if (responseLength > 99999)
-                        buf.append(Long.toString(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(' ');
+                    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));
                 }
-                else 
-                    buf.append(" - ");
-
-                log = buf.toString();
+                buf.append(' ');
             }
-            
+            else 
+                buf.append(" - ");
+
+            log = buf.toString();
+
+
             synchronized(_writer)
             {
                 _writer.write(log);
Index: modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/InclusiveByteRange.java	(working copy)
@@ -175,7 +175,7 @@
     /* ------------------------------------------------------------ */
     public String toHeaderRangeString(long size)
     {
-        StringBuffer sb = new StringBuffer(40);
+        StringBuilder sb = new StringBuilder(40);
         sb.append("bytes ");
         sb.append(getFirst(size));
         sb.append('-');
@@ -188,7 +188,7 @@
     /* ------------------------------------------------------------ */
     public static String to416HeaderRangeString(long size)
     {
-        StringBuffer sb = new StringBuffer(40);
+        StringBuilder sb = new StringBuilder(40);
         sb.append("bytes */");
         sb.append(size);
         return sb.toString();
@@ -198,7 +198,7 @@
     /* ------------------------------------------------------------ */
     public String toString()
     {
-        StringBuffer sb = new StringBuffer(60);
+        StringBuilder sb = new StringBuilder(60);
         sb.append(Long.toString(first));
         sb.append(":");
         sb.append(Long.toString(last));
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionIdManager.java	(working copy)
@@ -25,7 +25,7 @@
 import org.mortbay.jetty.SessionIdManager;
 import org.mortbay.jetty.servlet.AbstractSessionManager.Session;
 import org.mortbay.log.Log;
-import org.mortbay.util.MultiMap;
+import org.mortbay.util.ConcurrentMultiMap;
 
 /* ------------------------------------------------------------ */
 /**
@@ -37,7 +37,7 @@
     protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG";
     protected final static String SESSION_ID_RANDOM_ALGORITHM_ALT = "IBMSecureRandom";
 
-    MultiMap _sessions;
+    ConcurrentMultiMap _sessions;
     protected Random _random;
     private boolean _weakRandom;
     private String _workerName;
@@ -133,7 +133,7 @@
             }
         }
         _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory());
-        _sessions=new MultiMap();
+        _sessions=new ConcurrentMultiMap();
     }
 
     /* ------------------------------------------------------------ */
@@ -159,10 +159,7 @@
      */
     public void addSession(HttpSession session)
     {
-        synchronized (this)
-        {
-            _sessions.add(getClusterId(session.getId()),session);
-        }
+        _sessions.add(getClusterId(session.getId()),session);
     }
 
     /* ------------------------------------------------------------ */
@@ -171,10 +168,7 @@
      */
     public void removeSession(HttpSession session)
     {
-        synchronized (this)
-        {
-            _sessions.removeValue(getClusterId(session.getId()),session);
-        }
+        _sessions.removeValue(getClusterId(session.getId()),session);
     }
 
     /* ------------------------------------------------------------ */
@@ -183,19 +177,16 @@
      */
     public void invalidateAll(String id)
     {
-        synchronized (this)
-        {
-            // Do not use interators as this method tends to be called recursively 
-            // by the invalidate calls.
-            while (_sessions.containsKey(id))
-            {
-                Session session=(Session)_sessions.getValue(id,0);
-                if (session.isValid())
-                    session.invalidate();
-                else
-                    _sessions.removeValue(id,session);
-            }
-        }
+	// Do not use interators as this method tends to be called recursively 
+	// by the invalidate calls.
+	while (_sessions.containsKey(id))
+	{
+	    Session session=(Session)_sessions.getValue(id,0);
+	    if (session.isValid())
+		session.invalidate();
+	    else
+		_sessions.removeValue(id,session);
+	}
     }
 
     /* ------------------------------------------------------------ */
@@ -259,4 +250,4 @@
         _weakRandom=false;
     }
 
-}
\ No newline at end of file
+}
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/ServletHandler.java	(working copy)
@@ -21,6 +21,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -94,7 +95,7 @@
     private transient Map _servletNameMap=new HashMap();
     private transient PathMap _servletPathMap;
     
-    protected transient HashMap _chainCache[];
+    protected transient ConcurrentHashMap _chainCache[];
 
 
     /* ------------------------------------------------------------ */
@@ -139,7 +140,7 @@
         updateMappings();
         
         if(_filterChainsCached)
-            _chainCache=     new HashMap[]{null,new HashMap(),new HashMap(),null,new HashMap(),null,null,null,new HashMap()};
+            _chainCache=     new ConcurrentHashMap[]{null,new ConcurrentHashMap(),new ConcurrentHashMap(),null,new ConcurrentHashMap(),null,null,null,new ConcurrentHashMap()};
 
         super.doStart();
         
@@ -468,17 +469,13 @@
         
         if (_filterChainsCached && _chainCache!=null)
         {
-            synchronized(this)
-            {
-                if(_chainCache[requestType].containsKey(key))
-                    return (FilterChain)_chainCache[requestType].get(key);
-            }
+            FilterChain chain = (FilterChain)_chainCache[requestType].get(key);
+            if (chain!=null)
+                return chain;
         }
         
-        
         // Build list of filters
         Object filters= null;
-    
         
         // Path filters
         if (pathInContext!=null && _filterPathMappings!=null)
@@ -523,12 +520,9 @@
         {
             if (LazyList.size(filters) > 0)
                 chain= new CachedChain(filters, servletHolder);
-            synchronized(this)
-            {
-                if (_maxFilterChainsCacheSize>0 && _chainCache[requestType].size()>_maxFilterChainsCacheSize)
-                    _chainCache[requestType].clear();
-                _chainCache[requestType].put(key,chain);
-            }
+	    if (_maxFilterChainsCacheSize>0 && _chainCache[requestType].size()>_maxFilterChainsCacheSize)
+		_chainCache[requestType].clear();
+	    _chainCache[requestType].put(key,chain);
         }
         else if (LazyList.size(filters) > 0)
             chain = new Chain(filters, servletHolder);
@@ -1150,7 +1144,7 @@
         /* ------------------------------------------------------------ */
         public String toString()
         {
-            StringBuffer b = new StringBuffer();
+            StringBuilder b = new StringBuilder();
             for (int i=0; i<LazyList.size(_chain);i++)
             {
                 b.append(LazyList.get(_chain, i).toString());
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/HashSessionManager.java	(working copy)
@@ -30,6 +30,8 @@
 import java.util.Timer;
 import java.util.TimerTask;
 
+import java.util.concurrent.ConcurrentHashMap;
+
 import javax.servlet.http.HttpServletRequest;
 
 import org.mortbay.log.Log;
@@ -43,6 +45,7 @@
  */
 public class HashSessionManager extends AbstractSessionManager
 {
+    private static int __id;
     private Timer _timer;
     private TimerTask _task;
     private int _scavengePeriodMs=30000;
@@ -63,10 +66,10 @@
      */
     public void doStart() throws Exception
     {
-        _sessions=new HashMap();
+        _sessions=new ConcurrentHashMap(); // TODO: use syncronizedMap for JDK 1.4
         super.doStart();
 
-        _timer=new Timer(true);
+        _timer=new Timer("HashSessionScavenger-"+__id++, true);
         
         setScavengePeriod(getScavengePeriod());
 
Index: modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/servlet/DefaultServlet.java	(working copy)
@@ -421,19 +421,22 @@
                 if (!endsWithSlash || (pathInContext.length()==1 && request.getAttribute("org.mortbay.jetty.nullPathInfo")!=null))
                 {
                     StringBuffer buf=request.getRequestURL();
-                    int param=buf.lastIndexOf(";");
-                    if (param<0)
-                        buf.append('/');
-                    else
-                        buf.insert(param,'/');
-                    String q=request.getQueryString();
-                    if (q!=null&&q.length()!=0)
+                    synchronized(buf)
                     {
-                        buf.append('?');
-                        buf.append(q);
+                        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()));
                     }
-                    response.setContentLength(0);
-                    response.sendRedirect(response.encodeRedirectURL(buf.toString()));
                 }
                 // else look for a welcome file
                 else if (null!=(welcome=getWelcomeFile(resource)))
Index: modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java	(working copy)
@@ -347,7 +347,7 @@
             return null;
         URLClassLoader loader = (URLClassLoader)_classLoader;
         URL[] urls =loader.getURLs();
-        StringBuffer classpath=new StringBuffer();
+        StringBuilder classpath=new StringBuilder();
         for (int i=0;i<urls.length;i++)
         {
             try
Index: modules/jetty/src/main/java/org/mortbay/jetty/Response.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/Response.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/Response.java	(working copy)
@@ -385,7 +385,7 @@
 
         if (!URIUtil.hasScheme(location))
         {
-            StringBuffer buf = _connection.getRequest().getRootURL();
+            StringBuilder buf = _connection.getRequest().getRootURL();
             if (location.startsWith("/"))
                 buf.append(URIUtil.canonicalPath(location));
             else
Index: modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/HttpGenerator.java	(working copy)
@@ -368,7 +368,7 @@
         HttpFields.Field transfer_encoding = null;
         boolean keep_alive = false;
         boolean close=false;
-        StringBuffer connection = null;
+        StringBuilder connection = null;
 
         if (fields != null)
         {
@@ -439,7 +439,7 @@
                                             
                                             default:
                                                 if (connection==null)
-                                                    connection=new StringBuffer();
+                                                    connection=new StringBuilder();
                                                 else
                                                     connection.append(',');
                                                 connection.append(values[i]);
@@ -448,7 +448,7 @@
                                     else
                                     {
                                         if (connection==null)
-                                            connection=new StringBuffer();
+                                            connection=new StringBuilder();
                                         else
                                             connection.append(',');
                                         connection.append(values[i]);
@@ -479,7 +479,7 @@
                             default:
                             {
                                 if (connection==null)
-                                    connection=new StringBuffer();
+                                    connection=new StringBuilder();
                                 else
                                     connection.append(',');
                                 connection.append(field.getValue());
Index: modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/security/Password.java	(working copy)
@@ -122,31 +122,29 @@
     /* ------------------------------------------------------------ */
     public static String obfuscate(String s)
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         byte[] b = s.getBytes();
-        
-        synchronized(buf)
+
+        buf.append(__OBFUSCATE);
+        for (int i=0;i<b.length;i++)
         {
-            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);
+            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');
-                  case 2:buf.append('0');
-                  case 3:buf.append('0');
-                  default:buf.append(x);
-                }
+            switch(x.length())
+            {
+                case 1:buf.append('0');
+                case 2:buf.append('0');
+                case 3:buf.append('0');
+                default:buf.append(x);
             }
-            return buf.toString();
         }
+        return buf.toString();
+
     }
     
     /* ------------------------------------------------------------ */
Index: modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/security/HTAccessHandler.java	(working copy)
@@ -668,7 +668,7 @@
         /* ------------------------------------------------------------ */
         public String toString()
         {
-            StringBuffer buf=new StringBuffer();
+            StringBuilder buf=new StringBuilder();
 
             buf.append("AuthUserFile=");
             buf.append(_userFile);
Index: modules/jetty/src/main/java/org/mortbay/jetty/Request.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/jetty/Request.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/jetty/Request.java	(working copy)
@@ -1580,25 +1580,22 @@
      * 
      * @return "scheme://host:port"
      */
-    public StringBuffer getRootURL()
+    public StringBuilder getRootURL()
     {
-        StringBuffer url = new StringBuffer(48);
-        synchronized (url)
-        {
-            String scheme = getScheme();
-            int port = getServerPort();
+        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;
+        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;
     }
 
     /* ------------------------------------------------------------ */
Index: modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/xml/XmlConfiguration.java	(working copy)
@@ -830,16 +830,13 @@
             else
             {
                 // Get the multiple items as a single string
-                StringBuffer buf = new StringBuffer();
-                synchronized (buf)
+                StringBuilder buf = new StringBuilder();
+                for (int i = first; i <= last; i++)
                 {
-                    for (int i = first; i <= last; i++)
-                    {
-                        Object item = node.get(i);
-                        buf.append(itemValue(obj, item));
-                    }
-                    value = buf.toString();
+                    Object item = node.get(i);
+                    buf.append(itemValue(obj, item));
                 }
+                value = buf.toString();
             }
         }
 
Index: modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/xml/XmlParser.java	(working copy)
@@ -669,12 +669,9 @@
          */
         public synchronized String toString(boolean tag)
         {
-            StringBuffer buf = new StringBuffer();
-            synchronized (buf)
-            {
-                toString(buf, tag);
-                return buf.toString();
-            }
+            StringBuilder buf = new StringBuilder();
+            toString(buf, tag);
+            return buf.toString();
         }
 
         /* ------------------------------------------------------------ */
@@ -692,7 +689,7 @@
         }
 
         /* ------------------------------------------------------------ */
-        private synchronized void toString(StringBuffer buf, boolean tag)
+        private synchronized void toString(StringBuilder buf, boolean tag)
         {
             if (tag)
             {
Index: modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/io/BufferUtil.java	(working copy)
@@ -315,7 +315,7 @@
             if (bytes!=null)
                 return new String(bytes,buffer.getIndex(),buffer.length(),StringUtil.__ISO_8859_1);
             
-            StringBuffer b = new StringBuffer(buffer.length());
+            StringBuilder b = new StringBuilder(buffer.length());
             for (int i=buffer.getIndex(),c=0;c<buffer.length();i++,c++)
                 b.append((char)(0x7f&buffer.peek(i)));
             return b.toString();
Index: modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/io/AbstractBuffer.java	(working copy)
@@ -495,7 +495,7 @@
 
     public String toDetailString()
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         buf.append("[");
         buf.append(super.hashCode());
         buf.append(",");
Index: modules/jetty/src/main/java/org/mortbay/resource/Resource.java
===================================================================
--- modules/jetty/src/main/java/org/mortbay/resource/Resource.java	(revision 2256)
+++ modules/jetty/src/main/java/org/mortbay/resource/Resource.java	(working copy)
@@ -432,7 +432,7 @@
         String decodedBase = URIUtil.decodePath(base);
         String title = "Directory: "+decodedBase;
 
-        StringBuffer buf=new StringBuffer(4096);
+        StringBuilder buf=new StringBuilder(4096);
         buf.append("<HTML>");
         buf.append(title);
         buf.append("</TITLE></HEAD><BODY>\n<H1>");
Index: modules/jetty/pom.xml
===================================================================
--- modules/jetty/pom.xml	(revision 2256)
+++ modules/jetty/pom.xml	(working copy)
@@ -25,6 +25,13 @@
     </testResources>
     <plugins>
       <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
         <artifactId>maven-antrun-plugin</artifactId>
         <executions>
           <execution>
Index: modules/util/src/test/java/org/mortbay/util/URITest.java
===================================================================
--- modules/util/src/test/java/org/mortbay/util/URITest.java	(revision 2256)
+++ modules/util/src/test/java/org/mortbay/util/URITest.java	(working copy)
@@ -45,7 +45,7 @@
     public void testEncodePath()
     {
         // test basic encode/decode
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         
         
         buf.setLength(0);
Index: modules/util/src/test/java/org/mortbay/util/StringMapTest.java
===================================================================
--- modules/util/src/test/java/org/mortbay/util/StringMapTest.java	(revision 2256)
+++ modules/util/src/test/java/org/mortbay/util/StringMapTest.java	(working copy)
@@ -133,7 +133,7 @@
         m5.put("aBc", "x");
         m5i.put("AbC", "x");
 
-        StringBuffer buffer=new StringBuffer();
+        StringBuilder buffer=new StringBuilder();
         buffer.append("aBc");
         assertEquals("2",m5.get("abc"));
         assertEquals("x",m5.get(buffer));
Index: modules/util/src/test/java/org/mortbay/util/StringUtilTest.java
===================================================================
--- modules/util/src/test/java/org/mortbay/util/StringUtilTest.java	(revision 2256)
+++ modules/util/src/test/java/org/mortbay/util/StringUtilTest.java	(working copy)
@@ -137,7 +137,7 @@
 
     public void testAppend()
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         buf.append('a');
         StringUtil.append(buf, "abc", 1, 1);
         StringUtil.append(buf, (byte)12, 16);
Index: modules/util/src/main/java/org/mortbay/servlet/GzipFilter.java
===================================================================
--- modules/util/src/main/java/org/mortbay/servlet/GzipFilter.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/servlet/GzipFilter.java	(working copy)
@@ -330,7 +330,7 @@
                 }
                 catch (IOException e)
                 {
-                    throw new IllegalStateException();
+                    throw new IllegalStateException(e);
                 }
             }
         }
Index: modules/util/src/main/java/org/mortbay/servlet/CGI.java
===================================================================
--- modules/util/src/main/java/org/mortbay/servlet/CGI.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/servlet/CGI.java	(working copy)
@@ -373,7 +373,7 @@
      * @throws IOException
      */
     private String getTextLineFromStream( InputStream is ) throws IOException {
-        StringBuffer buffer = new StringBuffer();
+        StringBuilder buffer = new StringBuilder();
         int b;
 
        	while( (b = is.read()) != -1 && b != (int) '\n' ) {
Index: modules/util/src/main/java/org/mortbay/servlet/UserAgentFilter.java
===================================================================
--- modules/util/src/main/java/org/mortbay/servlet/UserAgentFilter.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/servlet/UserAgentFilter.java	(working copy)
@@ -20,6 +20,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -55,7 +56,7 @@
 public class UserAgentFilter implements Filter
 {
     private Pattern _pattern;
-    private Map _agentCache = new HashMap();
+    private Map _agentCache = new ConcurrentHashMap();
     private int _agentCacheSize=1024;
     private String _attribute;
 
@@ -118,11 +119,8 @@
         if (ua==null)
             return null;
         
-        String tag;
-        synchronized(_agentCache)
-        {
-            tag = (String)_agentCache.get(ua);
-        }
+        String tag = (String)_agentCache.get(ua);
+        
 
         if (tag==null)
         {
@@ -144,12 +142,9 @@
             else
                 tag=ua;
 
-            synchronized(_agentCache)
-            {
-                if (_agentCache.size()>=_agentCacheSize)
+            if (_agentCache.size()>=_agentCacheSize)
                     _agentCache.clear();
                 _agentCache.put(ua,tag);
-            }
 
         }
         return tag;
Index: modules/util/src/main/java/org/mortbay/thread/Timeout.java
===================================================================
--- modules/util/src/main/java/org/mortbay/thread/Timeout.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/thread/Timeout.java	(working copy)
@@ -177,7 +177,7 @@
     /* ------------------------------------------------------------ */
     public String toString()
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         buf.append(super.toString());
         
         Task task = _head._next;
Index: modules/util/src/main/java/org/mortbay/util/DateCache.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/DateCache.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/DateCache.java	(working copy)
@@ -156,7 +156,7 @@
             String ss2 = _formatString.substring( zIndex+3 );
             int tzOffset = tz.getRawOffset();
             
-            StringBuffer sb = new StringBuffer(_formatString.length()+10);
+            StringBuilder sb = new StringBuilder(_formatString.length()+10);
             sb.append(ss1);
             sb.append("'");
             if( tzOffset >= 0 )
@@ -255,17 +255,15 @@
 
         // Always format if we get here
         _lastSeconds = seconds;
-        StringBuffer sb=new StringBuffer(_secFormatString.length());
-        synchronized(sb)
-        {
-            sb.append(_secFormatString0);
-            int s=(int)(seconds%60);
-            if (s<10)
-                sb.append('0');
-            sb.append(s);
-            sb.append(_secFormatString1);
-            _lastResult=sb.toString();
-        }
+        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;
     }
@@ -273,9 +271,9 @@
     /* ------------------------------------------------------------ */
     /** Format to string buffer. 
      * @param inDate Date the format
-     * @param buffer StringBuffer
+     * @param buffer StringBuilder
      */
-    public void format(long inDate, StringBuffer buffer)
+    public void format(long inDate, StringBuilder buffer)
     {
         buffer.append(format(inDate));
     }
Index: modules/util/src/main/java/org/mortbay/util/RolloverFileOutputStream.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/RolloverFileOutputStream.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/RolloverFileOutputStream.java	(working copy)
@@ -166,7 +166,7 @@
         synchronized(RolloverFileOutputStream.class)
         {
             if (__rollover==null)
-                __rollover=new Timer(true);
+                __rollover=new Timer(RolloverFileOutputStream.class.getName(),true);
             
             _rollTask=new RollTask();
 
Index: modules/util/src/main/java/org/mortbay/util/ajax/JSON.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/ajax/JSON.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/ajax/JSON.java	(working copy)
@@ -988,7 +988,7 @@
     {
         boolean minus=false;
         long number=0;
-        StringBuffer buffer=null;
+        StringBuilder buffer=null;
 
         longLoop: while (source.hasNext())
         {
@@ -1019,7 +1019,7 @@
                 case '.':
                 case 'e':
                 case 'E':
-                    buffer=new StringBuffer(16);
+                    buffer=new StringBuilder(16);
                     buffer.append(minus?-1*number:number);
                     buffer.append(c);
                     source.next();
@@ -1033,8 +1033,7 @@
         if (buffer==null)
             return TypeUtil.newLong(number);
 
-        synchronized (buffer)
-        {
+
             doubleLoop: while (source.hasNext())
             {
                 char c=source.peek();
@@ -1063,7 +1062,7 @@
                 }
             }
             return new Double(buffer.toString());
-        }
+
     }
 
     protected void seekTo(char seek, Source source)
Index: modules/util/src/main/java/org/mortbay/util/StringUtil.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/StringUtil.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/StringUtil.java	(working copy)
@@ -190,22 +190,20 @@
         if (i == -1)
             return s;
     
-        StringBuffer buf = new StringBuffer(s.length()+with.length());
+        StringBuilder buf = new StringBuilder(s.length()+with.length());
 
-        synchronized(buf)
+        do
         {
-            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();
-        }
+            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();
+        
     }
 
 
@@ -219,13 +217,13 @@
 
 
     /* ------------------------------------------------------------ */
-    /** Append substring to StringBuffer 
-     * @param buf StringBuffer to append to
+    /** 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(StringBuffer buf,
+    public static void append(StringBuilder buf,
                               String s,
                               int offset,
                               int length)
@@ -248,7 +246,7 @@
      * append hex digit
      * 
      */
-    public static void append(StringBuffer buf,byte b,int base)
+    public static void append(StringBuilder buf,byte b,int base)
     {
         int bi=0xff&b;
         int c='0'+(bi/base)%base;
@@ -261,7 +259,6 @@
         buf.append((char)c);
     }
 
-    
     /* ------------------------------------------------------------ */
     public static void append2digits(StringBuffer buf,int i)
     {
@@ -273,6 +270,16 @@
     }
     
     /* ------------------------------------------------------------ */
+    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. 
@@ -346,7 +353,7 @@
     {
         if (name==null)
             return null;
-        StringBuffer buf = new StringBuffer(name.length());
+        StringBuilder buf = new StringBuilder(name.length());
         for (int i=0;i<name.length();i++)
         {
             char c=name.charAt(i);
Index: modules/util/src/main/java/org/mortbay/util/StringMap.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/StringMap.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/StringMap.java	(working copy)
@@ -613,15 +613,12 @@
         public Object setValue(Object o){Object old=_value;_value=o;return old;}
         public String toString()
         {
-            StringBuffer buf=new StringBuffer();
-            synchronized(buf)
-            {
-                toString(buf);
-            }
+            StringBuilder buf=new StringBuilder();
+            toString(buf);
             return buf.toString();
         }
 
-        private void toString(StringBuffer buf)
+        private void toString(StringBuilder buf)
         {
             buf.append("{[");
             if (_char==null)
Index: modules/util/src/main/java/org/mortbay/util/Utf8StringBuffer.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/Utf8StringBuffer.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/Utf8StringBuffer.java	(working copy)
@@ -26,6 +26,7 @@
  * 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://javolution.org
  * 
+ * This class is not synchronized and should probably be called Utf8StringBuilder
  */
 public class Utf8StringBuffer 
 {
Index: modules/util/src/main/java/org/mortbay/util/TypeUtil.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/TypeUtil.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/TypeUtil.java	(working copy)
@@ -395,7 +395,7 @@
     /* ------------------------------------------------------------ */
     public static String toString(byte[] bytes, int base)
     {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         for (int i=0;i<bytes.length;i++)
         {
             int bi=0xff&bytes[i];
@@ -427,7 +427,7 @@
     /* ------------------------------------------------------------ */
     public static String toHexString(byte[] b)
     {   
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         for (int i=0;i<b.length;i++)
         {
             int bi=0xff&b[i];
@@ -446,7 +446,7 @@
     /* ------------------------------------------------------------ */
     public static String toHexString(byte[] b,int offset,int length)
     {   
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         for (int i=offset;i<offset+length;i++)
         {
             int bi=0xff&b[i];
Index: modules/util/src/main/java/org/mortbay/util/UrlEncoded.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/UrlEncoded.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/UrlEncoded.java	(working copy)
@@ -116,57 +116,56 @@
     {
         if (charset==null)
             charset=StringUtil.__UTF8;
-        
-        StringBuffer result = new StringBuffer(128);
-        synchronized(result)
+
+        StringBuilder result = new StringBuilder(128);
+
+        Iterator iter = map.entrySet().iterator();
+        while(iter.hasNext())
         {
-            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)
             {
-                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(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)
+                    if (val!=null)
+                    {
+                        String str=val.toString();
+                        if (str.length()>0)
                         {
-                            String str=val.toString();
-                            if (str.length()>0)
-                            {
-                                result.append('=');
-                                result.append(encodeString(str,charset));
-                            }
-                            else if (equalsForNullValue)
-                                result.append('=');
+                            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();
+            if (iter.hasNext())
+                result.append('&');
         }
+        return result.toString();
     }
 
 
+
     /* -------------------------------------------------------------- */
     /** Decoded parameters to Map.
      * @param content the string containing the encoded parameters
Index: modules/util/src/main/java/org/mortbay/util/MultiMap.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/MultiMap.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/MultiMap.java	(working copy)
@@ -105,21 +105,20 @@
               Object o=LazyList.get(l,0);
               return o==null?null:o.toString();
           default:
-              StringBuffer values=new StringBuffer(128);
-              synchronized(values)
+          {
+              StringBuilder values=new StringBuilder(128);
+              for (int i=0; i<LazyList.size(l); i++)              
               {
-                  for (int i=0; i<LazyList.size(l); i++)              
+                  Object e=LazyList.get(l,i);
+                  if (e!=null)
                   {
-                      Object e=LazyList.get(l,i);
-                      if (e!=null)
-                      {
-                          if (values.length()>0)
-                              values.append(',');
-                          values.append(e.toString());
-                      }
-                  }   
-                  return values.toString();
-              }
+                      if (values.length()>0)
+                          values.append(',');
+                      values.append(e.toString());
+                  }
+              }   
+              return values.toString();
+          }
         }
     }
     
Index: modules/util/src/main/java/org/mortbay/util/Scanner.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/Scanner.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/Scanner.java	(working copy)
@@ -44,6 +44,7 @@
  */
 public class Scanner
 {
+    private static int __scannerId=0;
     private int _scanInterval;
     private List _listeners = Collections.synchronizedList(new ArrayList());
     private Map _prevScan = Collections.EMPTY_MAP;
@@ -239,7 +240,7 @@
 
     public Timer newTimer ()
     {
-        return new Timer(true);
+        return new Timer("Scanner-"+__scannerId++, true);
     }
     
     public void schedule (Timer timer, TimerTask task)
Index: modules/util/src/main/java/org/mortbay/util/ConcurrentMultiMap.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/ConcurrentMultiMap.java	(revision 0)
+++ modules/util/src/main/java/org/mortbay/util/ConcurrentMultiMap.java	(revision 0)
@@ -0,0 +1,303 @@
+// ========================================================================
+// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// 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.
+// ========================================================================
+
+package org.mortbay.util;
+
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/* ------------------------------------------------------------ */
+/** 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
+ *
+ * @see LazyList
+ * @author Greg Wilkins (gregw)
+ */
+public class ConcurrentMultiMap extends ConcurrentHashMap
+    implements Cloneable
+{
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     */
+    public ConcurrentMultiMap()
+    {}
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param size Capacity of the map
+     */
+    public ConcurrentMultiMap(int size)
+    {
+        super(size);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Constructor. 
+     * @param map 
+     */
+    public ConcurrentMultiMap(Map map)
+    {
+        super((map.size()*3)/2);
+        putAll(map);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** 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(super.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=super.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=super.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:
+              StringBuffer values=new StringBuffer(128);
+              synchronized(values)
+              {
+                  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=super.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(Object name, Object value) 
+    {
+        return super.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(Object name, List values) 
+    {
+        return super.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(Object name, String[] values) 
+    {
+        Object list=null;
+        for (int i=0;i<values.length;i++)
+            list=LazyList.add(list,values[i]);
+        return 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(Object name, Object value) 
+    {
+        Object lo = super.get(name);
+        Object ln = LazyList.add(lo,value);
+        if (lo!=ln)
+            super.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(Object name, List values) 
+    {
+        Object lo = super.get(name);
+        Object ln = LazyList.addCollection(lo,values);
+        if (lo!=ln)
+            super.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(Object name, String[] values) 
+    {
+        Object lo = super.get(name);
+        Object ln = LazyList.addCollection(lo,Arrays.asList(values));
+        if (lo!=ln)
+            super.put(name,ln);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Remove value.
+     * @param name The entry key. 
+     * @param value The entry value. 
+     * @return true if it was removed.
+     */
+    public boolean removeValue(Object name,Object value)
+    {
+        Object lo = super.get(name);
+        Object ln=lo;
+        int s=LazyList.size(lo);
+        if (s>0)
+        {
+            ln=LazyList.remove(lo,value);
+            if (ln==null)
+                super.remove(name);
+            else
+                super.put(name, ln);
+        }
+        return LazyList.size(ln)!=s;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Put all contents of map.
+     * @param m Map
+     */
+    public void putAll(Map m)
+    {
+        Iterator i = m.entrySet().iterator();
+        boolean multi=m instanceof MultiMap;
+        while(i.hasNext())
+        {
+            Map.Entry entry =
+                (Map.Entry)i.next();
+            if (multi)
+                super.put(entry.getKey(),LazyList.clone(entry.getValue()));
+            else
+                put(entry.getKey(),entry.getValue());
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @return Map of String arrays
+     */
+    public Map toStringArrayMap()
+    {
+        HashMap map = new HashMap(size()*3/2);
+        
+        Iterator i = super.entrySet().iterator();
+        while(i.hasNext())
+        {
+            Map.Entry entry = (Map.Entry)i.next();
+            Object l = entry.getValue();
+            String[] a = LazyList.toStringArray(l);
+            // for (int j=a.length;j-->0;)
+            //    if (a[j]==null)
+            //         a[j]="";
+            map.put(entry.getKey(),a);
+        }
+        return map;
+    }
+    
+    /* ------------------------------------------------------------ */
+    public Object clone()
+        throws CloneNotSupportedException
+    {
+        ConcurrentMultiMap mm = (ConcurrentMultiMap) super.clone();
+        
+        Iterator iter = mm.entrySet().iterator();
+        while (iter.hasNext())
+        {
+            Map.Entry entry = (Map.Entry)iter.next();
+            entry.setValue(LazyList.clone(entry.getValue()));
+        }
+        
+        return mm;
+    }
+}

Property changes on: modules/util/src/main/java/org/mortbay/util/ConcurrentMultiMap.java
___________________________________________________________________
Name: svn:eol-style
   + native

Index: modules/util/src/main/java/org/mortbay/util/URIUtil.java
===================================================================
--- modules/util/src/main/java/org/mortbay/util/URIUtil.java	(revision 2256)
+++ modules/util/src/main/java/org/mortbay/util/URIUtil.java	(working copy)
@@ -56,17 +56,17 @@
         if (path==null || path.length()==0)
             return path;
         
-        StringBuffer buf = encodePath(null,path);
+        StringBuilder buf = encodePath(null,path);
         return buf==null?path:buf.toString();
     }
         
     /* ------------------------------------------------------------ */
     /** Encode a URI path.
      * @param path The path the encode
-     * @param buf StringBuffer to encode path into (or null)
-     * @return The StringBuffer or null if no substitutions required.
+     * @param buf StringBuilder to encode path into (or null)
+     * @return The StringBuilder or null if no substitutions required.
      */
-    public static StringBuffer encodePath(StringBuffer buf, String path)
+    public static StringBuilder encodePath(StringBuilder buf, String path)
     {
         if (buf==null)
         {
@@ -81,7 +81,7 @@
                   case ';':
                   case '#':
                   case ' ':
-                      buf=new StringBuffer(path.length()<<1);
+                      buf=new StringBuilder(path.length()<<1);
                       break loop;
                 }
             }
@@ -124,13 +124,13 @@
     /* ------------------------------------------------------------ */
     /** Encode a URI path.
      * @param path The path the encode
-     * @param buf StringBuffer to encode path into (or null)
+     * @param buf StringBuilder to encode path into (or null)
      * @param encode String of characters to encode. % is always encoded.
-     * @return The StringBuffer or null if no substitutions required.
+     * @return The StringBuilder or null if no substitutions required.
      */
-    public static StringBuffer encodeString(StringBuffer buf,
-                                            String path,
-                                            String encode)
+    public static StringBuilder encodeString(StringBuilder buf,
+                                             String path,
+                                             String encode)
     {
         if (buf==null)
         {
@@ -140,7 +140,7 @@
                 char c=path.charAt(i);
                 if (c=='%' || encode.indexOf(c)>=0)
                 {    
-                    buf=new StringBuffer(path.length()<<1);
+                    buf=new StringBuilder(path.length()<<1);
                     break loop;
                 }
             }
@@ -169,7 +169,7 @@
     /* ------------------------------------------------------------ */
     /* Decode a URI path.
      * @param path The path the encode
-     * @param buf StringBuffer to encode path into
+     * @param buf StringBuilder to encode path into
      */
     public static String decodePath(String path)
     {
@@ -247,7 +247,7 @@
     /* ------------------------------------------------------------ */
     /* Decode a URI path.
      * @param path The path the encode
-     * @param buf StringBuffer to encode path into
+     * @param buf StringBuilder to encode path into
      */
     public static String decodePath(byte[] buf, int offset, int length)
     {
@@ -321,7 +321,7 @@
         if (split<0)
             split=p1.length();
 
-        StringBuffer buf = new StringBuffer(p1.length()+p2.length()+2);
+        StringBuilder buf = new StringBuilder(p1.length()+p2.length()+2);
         buf.append(p1);
         
         if (buf.charAt(split-1)=='/')
@@ -415,7 +415,7 @@
         if (start>=end)
             return path;
         
-        StringBuffer buf = new StringBuffer(path);
+        StringBuilder buf = new StringBuilder(path);
         int delStart=-1;
         int delEnd=-1;
         int skip=0;
Index: modules/util/pom.xml
===================================================================
--- modules/util/pom.xml	(revision 2256)
+++ modules/util/pom.xml	(working copy)
@@ -37,6 +37,13 @@
     </testResources>
     <plugins>
       <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
         <artifactId>maven-antrun-plugin</artifactId>
         <executions>
           <execution>
</pre>
<div id="after_source_code">
<h2>Other Jetty examples (source code examples)</h2>
<p>Here is a short list of links related to this Jetty java5.patch source code file:</p>
<ul>
  <li><a href="/java/jwarehouse"><img src="/images/scw/find.png" border="0"> The search page</a></li>
  <li><a href="index.shtml"><img src="/images/scw/folder.png" border="0"> Other Jetty source code examples at this package level</a></li>
  <li><a href="/java/jwarehouse/about.shtml"><img src="/images/scw/information.png" border="0"> Click here to learn more about this project</a></li>
</ul>
</div>
</td>
</tr>
</table>
</div>
</div>

<div style="padding-top: 1em; width: 310px; margin-left: auto; margin-right: auto; table {border-collapse: collapse; border: none;}; tr {border-collapse: collapse; border: none; text-align: center;};">
<table width="100%" cellspacing="0" cellpadding="0">
  <tr>
      <td colspan="2" style="border-collapse: collapse; border: none; text-align: center;};">
        <em>... this post is sponsored by my books ...</em>
      </td>
  </tr>
  <tr>
      <td width="150" style="border-collapse: collapse; border: none; text-align: center;};">
        <a href="https://kbhr.co/ckbk-v2"><img
           src="/images/books/scala-cookbook-v2-cover-220h.jpg"
           title="The Scala Cookbook, by Alvin Alexander" height="220" />
           <br /><span style="opacity: 0.4;">#1 New Release!</span></a>
      </td>
      <td width="150" style="border-collapse: collapse; border: none; text-align: center; padding-left: 8px;">
        <a href="http://kbhr.co/fps-book"><img
           src="/images/books/functional-programming-simplified-small.jpg"
           title="Functional Programming, Simplified, by Alvin Alexander"
           height="220" />
           <br /><span style="opacity: 0.4;">FP Best Seller</span></a>
      </td>
  </tr>
</table>
<p> </p>
</div>


<div id="whats_new">
<h2>new blog posts</h2>
<div id="whats_new_list">
<ul>
<li><a class="whats_new_link" href="/photos/als-oasis">Al's Oasis</a></li>
<li><a class="whats_new_link" href="/photos/window-poet">Window of the Poet (painting)</a></li>
<li><a class="whats_new_link" href="/source-code/macos-how-show-file-character-encoding-utf8-ascii">macOS: How to show a file'''s character encoding</a></li>
<br/>
<li><a class="whats_new_link" href="/misc/dream-vacation-for-meditator-meditation">A dream vacation for the meditator in your life</a></li>
<li><a class="whats_new_link" href="/scala/zio-json-solution-parse-decode-json-blank-spaces-type-hierarchy">A ZIO JSON solution to parse/decode JSON with blank spaces in the keys (and a type hierarchy)</a></li>
<li><a class="whats_new_link" href="/scala/zio-http-netty-AnnotatedNoRouteToHostException-null-solution">ZIO HTTP: Netty AnnotatedNoRouteToHostException null solution</a></li>
<br/>
<li><a class="whats_new_link" href="/misc/inside-shinzens-brain-how-zen-master-experiences-daily-life-world-enlightened">Inside Shinzen'''s Brain: How A Zen Master Experiences his Daily Life</a></li>
<li><a class="whats_new_link" href="/misc/shinzen-young-meditating-daily-life-arising-disappearing-the-source-love">Shinzen Young on meditating in his daily life: arising, disappearing, and The Source, and love</a></li>
<li><a class="whats_new_link" href="/scala/zio-zlayer-very-simple-example-dependency-injection-services">ZIO ZLayer: A simple '''Hello, world''' example (dependency injection, services)</a></li>
<br/>
<br/>
</div>
</ul>
</div>


<p> </p>

<p align="center"><font color="#000000" size="2"
face="Verdana,Arial">Copyright 1998-2021 Alvin Alexander, alvinalexander.com<br/>
All Rights Reserved.<br/>
<br/>
A percentage of advertising revenue from<br/>
pages under the <a href="/java/jwarehouse">/java/jwarehouse</a> 
URI on this website is<br/>
paid back to open source projects.</p>


<script>
shuffle(books);
var div = document.getElementById("leftcol");
var pre = '<div style="margin: 0; padding-right: 1.6em"><h2 align="center">favorite books</h2>';
var post = '</div>';
if (adblock) {
  var str = books.slice(0,3).join(" ");
  div.insertAdjacentHTML('beforeend', pre + str + post);
} else {
  var str = books.slice(0,1).join(" ");
  div.insertAdjacentHTML('beforeend', pre + str + post);
}
</script>



<p style="padding-bottom: 80px;"> </p>


</body>