Merge remote-tracking branch 'origin/master' into jetty-9.1
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
index 1c0bae8..8e5791a 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
@@ -450,6 +450,7 @@
     /**
      * is the session id known to mongo, and is it valid
      */
+    @Override
     public boolean idInUse(String sessionId)
     {        
         /*
@@ -473,6 +474,7 @@
     }
 
     /* ------------------------------------------------------------ */
+    @Override
     public void addSession(HttpSession session)
     {
         if (session == null)
@@ -494,6 +496,7 @@
     }
 
     /* ------------------------------------------------------------ */
+    @Override
     public void removeSession(HttpSession session)
     {
         if (session == null)
@@ -508,6 +511,7 @@
     }
 
     /* ------------------------------------------------------------ */
+    @Override
     public void invalidateAll(String sessionId)
     {
         synchronized (_sessionsIds)
@@ -520,7 +524,7 @@
             Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
             for (int i=0; contexts!=null && i<contexts.length; i++)
             {
-                SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+                SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
                 if (sessionHandler != null) 
                 {
                     SessionManager manager = sessionHandler.getSessionManager();
@@ -532,26 +536,7 @@
                 }
             }
         }      
-    }
-
-    /* ------------------------------------------------------------ */
-    // TODO not sure if this is correct
-    public String getClusterId(String nodeId)
-    {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
-    }
-
-    /* ------------------------------------------------------------ */
-    // TODO not sure if this is correct
-    public String getNodeId(String clusterId, HttpServletRequest request)
-    {
-        if (_workerName!=null)
-            return clusterId+'.'+_workerName;
-
-        return clusterId;
-    }
-    
+    } 
     
     /* ------------------------------------------------------------ */
     @Override
@@ -563,6 +548,24 @@
         synchronized (_sessionsIds)
         {
             _sessionsIds.remove(oldClusterId);//remove the old one from the list
+
+            /* ------------------------------------------------------------ */
+            // TODO not sure if this is correct
+            public String getClusterId(String nodeId)
+            {
+                int dot=nodeId.lastIndexOf('.');
+                return (dot>0)?nodeId.substring(0,dot):nodeId;
+            }
+
+            /* ------------------------------------------------------------ */
+            // TODO not sure if this is correct
+            public String getNodeId(String clusterId, HttpServletRequest request)
+            {
+                if (_workerName!=null)
+                    return clusterId+'.'+_workerName;
+
+                return clusterId;
+            }
             _sessionsIds.add(newClusterId); //add in the new session id to the list
 
             //tell all contexts to update the id 
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
index 6c3cc5c..ee3c4c6 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
@@ -35,6 +35,7 @@
 import org.eclipse.jetty.server.NetworkConnector;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.session.AbstractSessionIdManager;
 import org.eclipse.jetty.server.session.HashSessionIdManager;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
@@ -99,7 +100,7 @@
 
         if (nodeName != null)
         {
-            HashSessionIdManager sessionIdManager = new HashSessionIdManager();
+            AbstractSessionIdManager sessionIdManager = new HashSessionIdManager();
             sessionIdManager.setWorkerName(nodeName);
             server.setSessionIdManager(sessionIdManager);
         }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
index e3df34f..3ddc0bd 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
@@ -37,6 +37,7 @@
     protected Random _random;
     protected boolean _weakRandom;
     protected String _workerName;
+    protected String _workerAttr;
     protected long _reseed=100000L;
 
     /* ------------------------------------------------------------ */
@@ -58,6 +59,7 @@
      *
      * @return String or null
      */
+    @Override
     public String getWorkerName()
     {
         return _workerName;
@@ -67,11 +69,16 @@
     /**
      * Set the workname. If set, the workername is dot appended to the session
      * ID and can be used to assist session affinity in a load balancer.
+     * A worker name starting with $ is used as a request attribute name to
+     * lookup the worker name that can be dynamically set by a request
+     * customiser.
      *
      * @param workerName
      */
     public void setWorkerName(String workerName)
     {
+        if (isRunning())
+            throw new IllegalStateException(getState());
         if (workerName.contains("."))
             throw new IllegalArgumentException("Name cannot contain '.'");
         _workerName=workerName;
@@ -114,27 +121,28 @@
      *
      * @see org.eclipse.jetty.server.SessionIdManager#newSessionId(javax.servlet.http.HttpServletRequest, long)
      */
+    @Override
     public String newSessionId(HttpServletRequest request, long created)
     {
         synchronized (this)
         {
-            if (request!=null)
-            {
-                // A requested session ID can only be used if it is in use already.
-                String requested_id=request.getRequestedSessionId();
-                if (requested_id!=null)
-                {
-                    String cluster_id=getClusterId(requested_id);
-                    if (idInUse(cluster_id))
-                        return cluster_id;
-                }
+            if (request==null)
+                return newSessionId(created);
 
-                // Else reuse any new session ID already defined for this request.
-                String new_id=(String)request.getAttribute(__NEW_SESSION_ID);
-                if (new_id!=null&&idInUse(new_id))
-                    return new_id;
+            // A requested session ID can only be used if it is in use already.
+            String requested_id=request.getRequestedSessionId();
+            if (requested_id!=null)
+            {
+                String cluster_id=getClusterId(requested_id);
+                if (idInUse(cluster_id))
+                    return cluster_id;
             }
 
+            // Else reuse any new session ID already defined for this request.
+            String new_id=(String)request.getAttribute(__NEW_SESSION_ID);
+            if (new_id!=null&&idInUse(new_id))
+                return new_id;
+
             // pick a new unique ID!
             String id = newSessionId(request.hashCode());
 
@@ -190,15 +198,16 @@
 
 
     /* ------------------------------------------------------------ */
+    @Override
     public abstract void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request);
 
-
     
     /* ------------------------------------------------------------ */
     @Override
     protected void doStart() throws Exception
     {
        initRandom();
+       _workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
     }
 
     /* ------------------------------------------------------------ */
@@ -232,5 +241,39 @@
             _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory());
     }
 
+    /** Get the session ID with any worker ID.
+     *
+     * @param clusterId
+     * @param request
+     * @return sessionId plus any worker ID.
+     */
+    @Override
+    public String getNodeId(String clusterId, HttpServletRequest request)
+    {
+        if (_workerName!=null)
+        {
+            if (_workerAttr==null)
+                return clusterId+'.'+_workerName;
+
+            String worker=(String)request.getAttribute(_workerAttr);
+            if (worker!=null)
+                return clusterId+'.'+worker;
+        }
+    
+        return clusterId;
+    }
+
+    /** Get the session ID without any worker ID.
+     *
+     * @param nodeId the node id
+     * @return sessionId without any worker ID.
+     */
+    @Override
+    public String getClusterId(String nodeId)
+    {
+        int dot=nodeId.lastIndexOf('.');
+        return (dot>0)?nodeId.substring(0,dot):nodeId;
+    }
+
 
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
index 218fe3d..0ebd29b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
@@ -81,38 +81,7 @@
         }
         return sessions;
     }
-    /* ------------------------------------------------------------ */
-    /** Get the session ID with any worker ID.
-     *
-     * @param clusterId
-     * @param request
-     * @return sessionId plus any worker ID.
-     */
-    public String getNodeId(String clusterId,HttpServletRequest request)
-    {
-        // used in Ajp13Parser
-        String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
-        if (worker!=null)
-            return clusterId+'.'+worker;
-
-        if (_workerName!=null)
-            return clusterId+'.'+_workerName;
-
-        return clusterId;
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Get the session ID without any worker ID.
-     *
-     * @param nodeId the node id
-     * @return sessionId without any worker ID.
-     */
-    public String getClusterId(String nodeId)
-    {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
-    }
-
+    
     /* ------------------------------------------------------------ */
     @Override
     protected void doStart() throws Exception
@@ -132,6 +101,7 @@
     /**
      * @see SessionIdManager#idInUse(String)
      */
+    @Override
     public boolean idInUse(String id)
     {
         synchronized (this)
@@ -144,6 +114,7 @@
     /**
      * @see SessionIdManager#addSession(HttpSession)
      */
+    @Override
     public void addSession(HttpSession session)
     {
         String id = getClusterId(session.getId());
@@ -165,6 +136,7 @@
     /**
      * @see SessionIdManager#removeSession(HttpSession)
      */
+    @Override
     public void removeSession(HttpSession session)
     {
         String id = getClusterId(session.getId());
@@ -199,6 +171,7 @@
     /**
      * @see SessionIdManager#invalidateAll(String)
      */
+    @Override
     public void invalidateAll(String id)
     {
         Collection<WeakReference<HttpSession>> sessions;
@@ -221,6 +194,7 @@
     
     
     /* ------------------------------------------------------------ */
+    @Override
     public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
     {
         //generate a new id
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 15deaef..6590e24 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -29,11 +29,7 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
 import java.util.Random;
 import java.util.Set;
@@ -380,6 +376,7 @@
     }
 
 
+    @Override
     public void addSession(HttpSession session)
     {
         if (session == null)
@@ -422,6 +419,7 @@
 
 
 
+    @Override
     public void removeSession(HttpSession session)
     {
         if (session == null)
@@ -456,32 +454,7 @@
     }
 
 
-    /**
-     * Get the session id without any node identifier suffix.
-     *
-     * @see org.eclipse.jetty.server.SessionIdManager#getClusterId(java.lang.String)
-     */
-    public String getClusterId(String nodeId)
-    {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
-    }
-
-
-    /**
-     * Get the session id, including this node's id as a suffix.
-     *
-     * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest)
-     */
-    public String getNodeId(String clusterId, HttpServletRequest request)
-    {
-        if (_workerName!=null)
-            return clusterId+'.'+_workerName;
-
-        return clusterId;
-    }
-
-
+    @Override
     public boolean idInUse(String id)
     {
         if (id == null)
@@ -515,6 +488,7 @@
      *
      * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
      */
+    @Override
     public void invalidateAll(String id)
     {
         //take the id out of the list of known sessionids for this node
@@ -527,7 +501,7 @@
             Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
             for (int i=0; contexts!=null && i<contexts.length; i++)
             {
-                SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+                SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
                 if (sessionHandler != null)
                 {
                     SessionManager manager = sessionHandler.getSessionManager();
@@ -542,6 +516,7 @@
     }
 
 
+    @Override
     public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
     {
         //generate a new id
@@ -556,7 +531,7 @@
             Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
             for (int i=0; contexts!=null && i<contexts.length; i++)
             {
-                SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+                SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
                 if (sessionHandler != null) 
                 {
                     SessionManager manager = sessionHandler.getSessionManager();
@@ -971,7 +946,7 @@
         Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
         for (int i=0; contexts!=null && i<contexts.length; i++)
         {
-            SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
             if (sessionHandler != null)
             {
                 SessionManager manager = sessionHandler.getSessionManager();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
index 1d604f8..3368841 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java
@@ -227,6 +227,7 @@
         "Host: whatever\r\n"+
         "Content-Type: multipart/form-data; boundary=\"AaB03x\"\r\n"+
         "Content-Length: "+multipart.getBytes().length+"\r\n"+
+        "Connection: close\r\n"+
         "\r\n"+
         multipart;
 
@@ -353,12 +354,13 @@
         };
 
         results.clear();
-        _connector.getResponses(
+        String response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: myhost\n"+
                 "Connection: close\n"+
                 "\n");
         int i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://myhost/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("myhost",results.get(i++));
@@ -366,12 +368,13 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: myhost:8888\n"+
                 "Connection: close\n"+
                 "\n");
         i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://myhost:8888/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("myhost",results.get(i++));
@@ -379,13 +382,14 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: 1.2.3.4\n"+
                 "Connection: close\n"+
                 "\n");
         i=0;
-        
+
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://1.2.3.4/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("1.2.3.4",results.get(i++));
@@ -393,12 +397,13 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: 1.2.3.4:8888\n"+
                 "Connection: close\n"+
                 "\n");
         i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://1.2.3.4:8888/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("1.2.3.4",results.get(i++));
@@ -406,12 +411,13 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: [::1]\n"+
                 "Connection: close\n"+
                 "\n");
         i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://[::1]/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("::1",results.get(i++));
@@ -419,12 +425,13 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: [::1]:8888\n"+
                 "Connection: close\n"+
                 "\n");
         i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("http://[::1]:8888/",results.get(i++));
         assertEquals("0.0.0.0",results.get(i++));
         assertEquals("::1",results.get(i++));
@@ -432,7 +439,7 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: [::1]\n"+
                 "x-forwarded-for: remote\n"+
@@ -440,6 +447,7 @@
                 "Connection: close\n"+
                 "\n");
         i=0;
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("https://[::1]/",results.get(i++));
         assertEquals("remote",results.get(i++));
         assertEquals("::1",results.get(i++));
@@ -447,7 +455,7 @@
         
         
         results.clear();
-        _connector.getResponses(
+        response=_connector.getResponses(
                 "GET / HTTP/1.1\n"+
                 "Host: [::1]:8888\n"+
                 "Connection: close\n"+
@@ -455,7 +463,7 @@
                 "x-forwarded-proto: https\n"+
                 "\n");
         i=0;
-        
+        assertThat(response,Matchers.containsString("200 OK"));
         assertEquals("https://[::1]:8888/",results.get(i++));
         assertEquals("remote",results.get(i++));
         assertEquals("::1",results.get(i++));
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
index 11ad5a9..960fa62 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
@@ -102,7 +102,7 @@
         Assert.assertTrue(testDir.exists());
         Assert.assertTrue(testDir.canWrite());
         
-        HashSessionIdManager idManager = new HashSessionIdManager();
+        AbstractSessionIdManager idManager = new HashSessionIdManager();
         idManager.setWorkerName("foo");
         manager.setSessionIdManager(idManager);
         
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
index f5b58e2..0c52028 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
@@ -58,6 +58,7 @@
         /**
          * @see org.eclipse.jetty.server.SessionIdManager#idInUse(java.lang.String)
          */
+        @Override
         public boolean idInUse(String id)
         {
             return false;
@@ -66,6 +67,7 @@
         /**
          * @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
          */
+        @Override
         public void addSession(HttpSession session)
         {
 
@@ -74,6 +76,7 @@
         /**
          * @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
          */
+        @Override
         public void removeSession(HttpSession session)
         {
 
@@ -82,28 +85,12 @@
         /**
          * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
          */
+        @Override
         public void invalidateAll(String id)
         {
 
         }
 
-        /**
-         * @see org.eclipse.jetty.server.SessionIdManager#getClusterId(java.lang.String)
-         */
-        public String getClusterId(String nodeId)
-        {
-            int dot=nodeId.lastIndexOf('.');
-            return (dot>0)?nodeId.substring(0,dot):nodeId;
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest)
-         */
-        public String getNodeId(String clusterId, HttpServletRequest request)
-        {
-            return clusterId+'.'+_workerName;
-        }
-
         @Override
         public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
         {
@@ -119,6 +106,7 @@
         /**
          * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
          */
+        @Override
         protected void addSession(AbstractSession session)
         {
 
@@ -127,6 +115,7 @@
         /**
          * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
          */
+        @Override
         public AbstractSession getSession(String idInCluster)
         {
             return null;
@@ -135,6 +124,7 @@
         /**
          * @see org.eclipse.jetty.server.session.AbstractSessionManager#invalidateSessions()
          */
+        @Override
         protected void invalidateSessions() throws Exception
         {
 
@@ -143,6 +133,7 @@
         /**
          * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
          */
+        @Override
         protected AbstractSession newSession(HttpServletRequest request)
         {
             return null;
@@ -151,6 +142,7 @@
         /**
          * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
          */
+        @Override
         protected boolean removeSession(String idInCluster)
         {
             return false;