diff --git a/apps/jetty/java/src/org/mortbay/util/URI.java b/apps/jetty/java/src/org/mortbay/util/URI.java
new file mode 100644
index 0000000000000000000000000000000000000000..073951a57cce54141e092f392db4f690aa952d24
--- /dev/null
+++ b/apps/jetty/java/src/org/mortbay/util/URI.java
@@ -0,0 +1,982 @@
+// ========================================================================
+// $Id: URI.java,v 1.40 2009/05/16 02:02:00 gregwilkins Exp $
+// Copyright 199-2004 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.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.mortbay.log.LogFactory;
+
+/* ------------------------------------------------------------ */
+/** URI Holder.
+ * This class assists with the decoding and encoding or HTTP URI's.
+ * It differs from the java.net.URL class as it does not provide
+ * communications ability, but it does assist with query string
+ * formatting.
+ * <P>ISO_8859_1 encoding is used by default for % encoded characters. This
+ * may be overridden with the org.mortbay.util.URI.charset system property.
+ * @see UrlEncoded
+ * @version $Id: URI.java,v 1.40 2009/05/16 02:02:00 gregwilkins Exp $
+ * @author Greg Wilkins (gregw)
+ */
+public class URI
+    implements Cloneable
+{
+    private static Log log = LogFactory.getLog(URI.class);
+
+    public static final String __CHARSET=System.getProperty("org.mortbay.util.URI.charset",StringUtil.__UTF_8);
+    public static final boolean __CHARSET_IS_DEFAULT=__CHARSET.equals(StringUtil.__UTF_8);
+    
+    /* ------------------------------------------------------------ */
+    private String _uri;
+    private String _scheme;
+    private String _host;
+    private int _port;
+    private String _path;
+    private String _encodedPath;
+    private String _query;
+    private UrlEncoded _parameters;
+    private boolean _dirty;
+    
+    /* ------------------------------------------------------------ */
+    /** Copy Constructor .
+     * @param uri
+     */
+    public URI(URI uri)
+        throws IllegalArgumentException
+    {
+        _uri=uri.toString();
+        _scheme=uri._scheme;
+        _host=uri._host;
+        _port=uri._port;
+        _path=uri._path;
+        _encodedPath=uri._encodedPath;
+        _query=uri._query;
+        if (uri._parameters!=null) 
+            _parameters=(UrlEncoded)uri._parameters.clone();
+        _dirty=false;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Construct from a String.
+     * The string must contain a URI path, but optionaly may contain a
+     * scheme, host, port and query string.
+     * 
+     * @param uri [scheme://host[:port]]/path[?query]
+     */
+    public URI(String uri)
+        throws IllegalArgumentException
+    {
+        setURI(uri);
+    }
+    
+    /* ------------------------------------------------------------ */
+    public void setURI(String uri)
+        throws IllegalArgumentException
+    {
+        try
+        {    
+            _uri=uri;
+            _scheme=null;
+            _host=null;
+            _port=0;
+            _path=null;
+            _encodedPath=null;
+            _query=null;
+            if (_parameters!=null)
+                _parameters.clear();
+            
+            // Scan _uri for host, port, path & query
+            int maxi=uri.length()-1;
+            int mark=0;
+            int state=0;
+            int i=0;
+
+            if (maxi==0 || uri.charAt(0)=='/' && uri.charAt(1)!='/')
+            {
+                state=3;
+                _scheme=null;
+                _host=null;
+                _port=0;
+            }
+            else
+            {
+                for (i=0;state<3 && i<=maxi;i++)
+                {
+                    char c=uri.charAt(i);
+                    switch(state)
+                    {
+                      case 0: // looking for scheme or path
+                          if (c==':' &&
+                              uri.charAt(i+1)=='/' &&
+                              uri.charAt(i+2)=='/')
+                          {
+                              // found end of scheme & start of host
+                              _scheme=uri.substring(mark,i);
+                              i+=2;
+                              mark=i+1;
+                              state=1;
+                          }
+                          else if (i==0 && c=='/')
+                          {
+                              // Found path
+                              state=3;
+                          }
+                          else if (i==0 && c=='*')
+                          {
+                              state=5;
+                              _path="*";
+                              _encodedPath="*";
+                          }
+                          continue;
+                          
+                      case 1: // Get host & look for port or path
+                          if (c==':')
+                          {
+                              // found port
+                              _host=uri.substring(mark,i);
+                              mark=i+1;
+                              state=2;
+                          }
+                          else if (c=='/')
+                          {
+                              // found path
+                              _host=uri.substring(mark,i);
+                              mark=i;
+                              state=3;
+                          }
+                          continue;
+                          
+                      case 2: // Get port & look for path
+                          if (c=='/')
+                          {
+                              _port=TypeUtil.parseInt(uri,mark,i-mark,10);
+                              mark=i;
+                              state=3;
+                          }
+                          continue;
+                    }
+                }
+            }
+            
+            // State 3 - Get path & look for query
+            _query=null;
+            for (i++;i<=maxi;i++)
+            {
+                char c=uri.charAt(i); 
+                if (c=='?')
+                {
+                    // Found query
+                    _encodedPath=uri.substring(mark,i);
+                    _path=decodePath(_encodedPath);
+
+                    mark=i+1;
+                    state=4;
+                    break;
+                }
+            }
+
+            // complete last state
+            switch(state)
+            {
+              case 0:
+                  _dirty=false;
+                  _encodedPath=_uri;
+                  _path=decodePath(_encodedPath);
+                  break;
+                  
+              case 1:
+                  _dirty=true;
+                  _encodedPath="/";
+                  _path=_encodedPath;
+                  _host=uri.substring(mark);
+                  break;
+                  
+              case 2:
+                  _dirty=true;
+                  _encodedPath="/";
+                  _path=_encodedPath;
+                  _port=TypeUtil.parseInt(uri,mark,-1,10);
+                  break;
+              case 3:
+                  _dirty=(mark==maxi);
+                  _encodedPath=uri.substring(mark);
+                  _path=decodePath(_encodedPath);
+                  break;
+                  
+              case 4:
+                  _dirty=false; 
+                  if (mark<=maxi)
+                      _query=uri.substring(mark);
+                  break;
+                  
+              case 5:
+                  _dirty=false; 
+            }
+        
+            if (_query!=null && _query.length()>0)
+            {
+                if (_parameters==null)
+                    _parameters= new UrlEncoded();
+                else
+                    _parameters.clear();
+                _parameters.decode(_query,__CHARSET);
+            }
+            else
+                _query=null;           
+        }
+        catch (Exception e)
+        {
+            LogSupport.ignore(log,e);
+            throw new IllegalArgumentException("Malformed URI '"+uri+
+                                               "' : "+e.toString());
+        }        
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Is the URI an absolute URL? 
+     * @return True if the URI has a scheme or host
+     */
+    public boolean isAbsolute()
+    {
+        return _scheme!=null || _host!=null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri scheme.
+     * @return the URI scheme
+     */
+    public String getScheme()
+    {
+        return _scheme;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the uri scheme.
+     * @param scheme the uri scheme
+     */
+    public void setScheme(String scheme)
+    {
+        _scheme=scheme;
+        _dirty=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri host.
+     * @return the URI host
+     */
+    public String getHost()
+    {
+        return _host;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the uri host.
+     * @param host the uri host
+     */
+    public void setHost(String host)
+    {
+        _host=host;
+        _dirty=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri port.
+     * @return the URI port
+     */
+    public int getPort()
+    {
+        return _port;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the uri port.
+     * A port of 0 implies use the default port.
+     * @param port the uri port
+     */
+    public void setPort(int port)
+    {
+        _port=port;
+        _dirty=true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri path.
+     * @return the URI path
+     */
+    public String getPath()
+    {
+        return _path;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the encoded uri path.
+     * @return the URI path
+     */
+    public String getEncodedPath()
+    {
+        return _encodedPath;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the uri path.
+     * @param path the URI path
+     */
+    public void setPath(String path)
+    {
+        _path=path;
+        _encodedPath=encodePath(_path);
+        _dirty=true;
+    }
+    
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri query String.
+     * @return the URI query string
+     */
+    public String getQuery()
+    {
+        if (_dirty && _parameters!=null)
+        {
+            _query = _parameters.encode(__CHARSET);
+            if (_query!=null && _query.length()==0)
+                _query=null;
+        }
+        return _query;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Set the uri query String.
+     * @param query the URI query string
+     */
+    public void setQuery(String query)
+    {
+        _query=query;
+        
+        if (_parameters!=null)
+            _parameters.clear();
+        else if (query!=null)
+            _parameters=new UrlEncoded();
+        
+        if (query!=null)
+            _parameters.decode(query,__CHARSET);
+        
+        cleanURI();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri query _parameters names.
+     * @return  Unmodifiable set of URI query _parameters names
+     */
+    public Set getParameterNames()
+    {
+        if (_parameters==null)
+            return Collections.EMPTY_SET;
+        return _parameters.keySet();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri query _parameters.
+     * @return the URI query _parameters
+     */
+    public MultiMap getParameters()
+    {
+        if (_parameters==null)
+            _parameters=new UrlEncoded();
+        _dirty=true;
+        return _parameters;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get the uri query _parameters.
+     * @return the URI query _parameters in an unmodifiable map.
+     */
+    public Map getUnmodifiableParameters()
+    {
+        if (_parameters==null)
+            return Collections.EMPTY_MAP;
+        return Collections.unmodifiableMap(_parameters);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add the uri query _parameters to a MultiMap
+     */
+    public void putParametersTo(MultiMap map)
+    {
+        if (_parameters!=null && _parameters.size()>0)
+            map.putAll(_parameters);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Clear the URI _parameters.
+     */
+    public void clearParameters()
+    {
+        if (_parameters!=null)
+        {
+            _dirty=true;
+            _parameters.clear();
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add encoded _parameters.
+     * @param encoded A HTTP encoded string of _parameters: e.g.. "a=1&b=2"
+     */
+    public void put(String encoded)
+    {
+        UrlEncoded params = new UrlEncoded(encoded);
+        put(params);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add name value pair to the uri query _parameters.
+     * @param name name of value
+     * @param value The value, which may be a multi valued list or
+     * String array.
+     */
+    public Object put(Object name, Object value)
+    {
+        return getParameters().put(name,value);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Add dictionary to the uri query _parameters.
+     */
+    public void put(Map values)
+    {
+        getParameters().putAll(values);
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Get named value 
+     */
+    public String get(String name)
+    {
+        if (_parameters==null)
+            return null;
+        return (String)_parameters.get(name);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Get named multiple values.
+     * @param name The parameter name
+     * @return Umodifiable list of values or null
+     */
+    public List getValues(String name)
+    {
+        if (_parameters==null)
+            return null;
+        return _parameters.getValues(name);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Remove named value 
+     */
+    public void remove(String name)
+    {
+        if (_parameters!=null)
+        {
+            _dirty=
+                _parameters.remove(name)!=null;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** @return the URI string encoded.
+     */
+    public String toString()
+    {
+        if (_dirty)
+        {
+            getQuery();
+            cleanURI();
+        }
+        return _uri;
+    }
+
+    /* ------------------------------------------------------------ */
+    private void cleanURI()
+    {
+        StringBuffer buf = new StringBuffer(_uri.length()*2);
+        synchronized(buf)
+        {
+            if (_scheme!=null)
+            {
+                buf.append(_scheme);
+                buf.append("://");
+                buf.append(_host);
+                if (_port>0)
+                {
+                    buf.append(':');
+                    buf.append(_port);
+                }
+            }
+
+            buf.append(_encodedPath);
+            
+            if (_query!=null && _query.length()>0)
+            {
+                buf.append('?');
+                buf.append(_query);
+            }
+            _uri=buf.toString();
+            _dirty=false;
+        }
+    }
+    
+                
+    /* ------------------------------------------------------------ */
+    /** Encode a URI path.
+     * This is the same encoding offered by URLEncoder, except that
+     * the '/' character is not encoded.
+     * @param path The path the encode
+     * @return The encoded path
+     */
+    public static String encodePath(String path)
+    {
+        if (path==null || path.length()==0)
+            return path;
+        
+        StringBuffer 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.
+     */
+    public static StringBuffer encodePath(StringBuffer buf, String path)
+    {
+        if (buf==null)
+        {
+        loop:
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                switch(c)
+                {
+                  case '%':
+                  case '?':
+                  case ';':
+                  case '#':
+                  case ' ':
+                      buf=new StringBuffer(path.length()<<1);
+                      break loop;
+                }
+            }
+            if (buf==null)
+                return null;
+        }
+        
+        synchronized(buf)
+        {
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);       
+                switch(c)
+                {
+                  case '%':
+                      buf.append("%25");
+                      continue;
+                  case '?':
+                      buf.append("%3F");
+                      continue;
+                  case ';':
+                      buf.append("%3B");
+                      continue;
+                  case '#':
+                      buf.append("%23");
+                      continue;
+                  case ' ':
+                      buf.append("%20");
+                      continue;
+                  default:
+                      buf.append(c);
+                      continue;
+                }
+            }
+        }
+
+        return buf;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Encode a URI path.
+     * @param path The path the encode
+     * @param buf StringBuffer 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.
+     */
+    public static StringBuffer encodeString(StringBuffer buf,
+                                            String path,
+                                            String encode)
+    {
+        if (buf==null)
+        {
+        loop:
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                if (c=='%' || encode.indexOf(c)>=0)
+                {    
+                    buf=new StringBuffer(path.length()<<1);
+                    break loop;
+                }
+            }
+            if (buf==null)
+                return null;
+        }
+        
+        synchronized(buf)
+        {
+            for (int i=0;i<path.length();i++)
+            {
+                char c=path.charAt(i);
+                if (c=='%' || encode.indexOf(c)>=0)
+                {
+                    buf.append('%');
+                    StringUtil.append(buf,(byte)(0xff&c),16);
+                }
+                else
+                    buf.append(c);
+            }
+        }
+
+        return buf;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /* Decode a URI path.
+     * @param path The path the encode
+     * @param buf StringBuffer to encode path into
+     */
+    public static String decodePath(String path)
+    {
+        int len=path.length();
+        byte[] bytes=null;
+        int n=0;
+        boolean noDecode=true;
+        
+        for (int i=0;i<len;i++)
+        {
+            char c = path.charAt(i);
+            
+            byte b = (byte)(0xff & c);
+
+            if (c=='%' && (i+2)<len)
+            {
+                noDecode=false;
+                b=(byte)(0xff&TypeUtil.parseInt(path,i+1,2,16));
+                i+=2;
+            }
+            else if (bytes==null)
+            {
+                n++;
+                continue;
+            }
+            
+            if (bytes==null)
+            {
+                noDecode=false;
+                bytes=new byte[len];
+                for (int j=0;j<n;j++)
+                    bytes[j]=(byte)(0xff & path.charAt(j));                
+            }
+            
+            bytes[n++]=b;
+        }
+
+        if (noDecode)
+            return path;
+
+        try
+        {    
+            return new String(bytes,0,n,__CHARSET);
+        }
+        catch(UnsupportedEncodingException e)
+        {
+            log.warn(LogSupport.EXCEPTION,e);
+            return new String(bytes,0,n);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Clone URI.
+     * @return cloned URI
+     */
+    public Object clone()
+	throws CloneNotSupportedException
+    {
+         URI u = (URI)super.clone();
+         if (_parameters!=null)
+             u._parameters=(UrlEncoded)_parameters.clone();
+         _dirty=false;
+         
+         return u;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /** Add two URI path segments.
+     * Handles null and empty paths, path and query params (eg ?a=b or
+     * ;JSESSIONID=xxx) and avoids duplicate '/'
+     * @param p1 URI path segment 
+     * @param p2 URI path segment
+     * @return Legally combined path segments.
+     */
+    public static String addPaths(String p1, String p2)
+    {
+        if (p1==null || p1.length()==0)
+        {
+            if (p2==null || p2.length()==0)
+                return p1;
+            return p2;
+        }
+        if (p2==null || p2.length()==0)
+            return p1;
+        
+        int split=p1.indexOf(';');
+        if (split<0)
+            split=p1.indexOf('?');
+        if (split==0)
+            return p2+p1;
+        if (split<0)
+            split=p1.length();
+
+        StringBuffer buf = new StringBuffer(p1.length()+p2.length()+2);
+        buf.append(p1);
+        
+        if (buf.charAt(split-1)=='/')
+        {
+            if (p2.startsWith("/"))
+            {
+                buf.deleteCharAt(split-1);
+                buf.insert(split-1,p2);
+            }
+            else
+                buf.insert(split,p2);
+        }
+        else
+        {
+            if (p2.startsWith("/"))
+                buf.insert(split,p2);
+            else
+            {
+                buf.insert(split,'/');
+                buf.insert(split+1,p2);
+            }
+        }
+
+        return buf.toString();
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Return the parent Path.
+     * Treat a URI like a directory path and return the parent directory.
+     */
+    public static String parentPath(String p)
+    {
+        if (p==null || "/".equals(p))
+            return null;
+        int slash=p.lastIndexOf('/',p.length()-2);
+        if (slash>=0)
+            return p.substring(0,slash+1);
+        return null;
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Strip parameters from a path.
+     * Return path upto any semicolon parameters.
+     */
+    public static String stripPath(String path)
+    {
+        if (path==null)
+            return null;
+        int semi=path.indexOf(';');
+        if (semi<0)
+            return path;
+        return path.substring(0,semi);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /** Convert a path to a cananonical form.
+     * All instances of "." and ".." are factored out.  Null is returned
+     * if the path tries to .. above it's root.
+     * @param path 
+     * @return path or null.
+     */
+    public static String canonicalPath(String path)
+    {
+        if (path==null || path.length()==0)
+            return path;
+
+        int end=path.length();
+        int start = path.lastIndexOf('/', end);
+
+    search:
+        while (end>0)
+        {
+            switch(end-start)
+            {
+              case 2: // possible single dot
+                  if (path.charAt(start+1)!='.')
+                      break;
+                  break search;
+              case 3: // possible double dot
+                  if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.')
+                      break;
+                  break search;
+            }
+            
+            end=start;
+            start=path.lastIndexOf('/',end-1);
+        }
+
+        // If we have checked the entire string
+        if (start>=end)
+            return path;
+        
+        StringBuffer buf = new StringBuffer(path);
+        int delStart=-1;
+        int delEnd=-1;
+        int skip=0;
+        
+        while (end>0)
+        {
+            switch(end-start)
+            {       
+              case 2: // possible single dot
+                  if (buf.charAt(start+1)!='.')
+                  {
+                      if (skip>0 && --skip==0)
+                      {   
+                          delStart=start>=0?start:0;
+                          if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                              delStart++;
+                      }
+                      break;
+                  }
+                  
+                  if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/')
+                      break;
+                  
+                  if(delEnd<0)
+                      delEnd=end;
+                  delStart=start;
+                  if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/')
+                  {
+                      delStart++;
+                      if (delEnd<buf.length() && buf.charAt(delEnd)=='/')
+                          delEnd++;
+                      break;
+                  }
+                  if (end==buf.length())
+                      delStart++;
+                  
+                  end=start--;
+                  while (start>=0 && buf.charAt(start)!='/')
+                      start--;
+                  continue;
+                  
+              case 3: // possible double dot
+                  if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.')
+                  {
+                      if (skip>0 && --skip==0)
+                      {   delStart=start>=0?start:0;
+                      	  if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                      	      delStart++;
+                      }
+                      break;
+                  }
+                  
+                  delStart=start;
+                  if (delEnd<0)
+                      delEnd=end;
+
+                  skip++;
+                  end=start--;
+                  while (start>=0 && buf.charAt(start)!='/')
+                      start--;
+                  continue;
+
+              default:
+                  if (skip>0 && --skip==0)
+                  {
+                      delStart=start>=0?start:0;
+                      if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
+                          delStart++;
+                  }
+            }     
+            
+            // Do the delete
+            if (skip<=0 && delStart>=0 && delStart>=0)
+            {  
+                buf.delete(delStart,delEnd);
+                delStart=delEnd=-1;
+                if (skip>0)
+                    delEnd=end;
+            }
+            
+            end=start--;
+            while (start>=0 && buf.charAt(start)!='/')
+                start--;
+        }      
+
+        // Too many ..
+        if (skip>0)
+            return null;
+        
+        // Do the delete
+        if (delEnd>=0)
+            buf.delete(delStart,delEnd);
+
+        return buf.toString();
+    }
+
+    /* ------------------------------------------------------------ */
+    /** 
+     * @param uri URI
+     * @return True if the uri has a scheme
+     */
+    public static boolean hasScheme(String uri)
+    {
+        for (int i=0;i<uri.length();i++)
+        {
+            char c=uri.charAt(i);
+            if (c==':')
+                return true;
+            if (!(c>='a'&&c<='z' ||
+                  c>='A'&&c<='Z' ||
+                  (i>0 &&(c>='0'&&c<='9' ||
+                          c=='.' ||
+                          c=='+' ||
+                          c=='-'))
+                  ))
+                break;
+        }
+        return false;
+    }
+    
+}
+
+
+