[jboss-cvs] Repository SVN: r4505 - in apache-tomcat: 5.5.9.patch05-brew and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Apr 11 15:39:18 EDT 2008


Author: permaine
Date: 2008-04-11 15:39:17 -0400 (Fri, 11 Apr 2008)
New Revision: 4505

Added:
   apache-tomcat/5.5.9.patch05-brew/
   apache-tomcat/5.5.9.patch05-brew/component-info.xml
   apache-tomcat/5.5.9.patch05-brew/lib/
   apache-tomcat/5.5.9.patch05-brew/lib/catalina-manager.jar
   apache-tomcat/5.5.9.patch05-brew/lib/catalina-optional.jar
   apache-tomcat/5.5.9.patch05-brew/lib/catalina.jar
   apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler-jdt.jar
   apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler.jar
   apache-tomcat/5.5.9.patch05-brew/lib/jasper-runtime.jar
   apache-tomcat/5.5.9.patch05-brew/lib/naming-resources.jar
   apache-tomcat/5.5.9.patch05-brew/lib/servlets-default.jar
   apache-tomcat/5.5.9.patch05-brew/lib/servlets-invoker.jar
   apache-tomcat/5.5.9.patch05-brew/lib/servlets-webdav.jar
   apache-tomcat/5.5.9.patch05-brew/lib/tomcat-ajp.jar
   apache-tomcat/5.5.9.patch05-brew/lib/tomcat-coyote.jar
   apache-tomcat/5.5.9.patch05-brew/lib/tomcat-http.jar
   apache-tomcat/5.5.9.patch05-brew/lib/tomcat-util.jar
   apache-tomcat/5.5.9.patch05-brew/src/
   apache-tomcat/5.5.9.patch05-brew/src/jakarta-tomcat-5.5.9-src.tar.gz
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5-CVE-2007-5461-webdav.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-Bug36863-backport.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2005-2090.5.0.x.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-3835.5.5.x.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7195.5.0.x.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7196.5.x.y.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-0450.5.5.9.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-1858.5.5.9.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2449.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2450_CVE-2007-3386.5.0.x.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-3382_CVE-2007-3385.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-5342.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2008-0128.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-IT168408.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-jboss.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-removeJSSEfor13.patch
   apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9.patch01-JspServlet-5.15.17-backport.patch
Log:
Add Brew-build 5.5.9.patch05-brew

Added: apache-tomcat/5.5.9.patch05-brew/component-info.xml
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/component-info.xml	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/component-info.xml	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,54 @@
+<project name="apache-tomcat-component-info">
+
+   <component id="apache-tomcat"
+      licenseType="apache-2.0"
+      version="5.5.9.patch05-brew"
+      projectHome="http://jakarta.apache.org/tomcat/index.html"
+      description="Tomcat 5.5 servlet 2.4 web container with a fix for the JBAS-2866, as well as backported fixes for CVE-2005-2090, CVE-2006-3835, CVE-2006-7195, CVE-2007-0450, CVE-2007-1858, CVE-2005-3510, plus fixes for CVE-2007-2450 and CVE-2007-3386 and fixes for CVE-2007-5461, also CVE-2007-5342, CVE-2007-3382, CVE-2007-3385, CVE-2007-2449, CVE-2008-0128, CVE-2007-1355, CVE-2006-7196 and IT 168408">
+      <!-- cvsroot=":ext:cvs.devel.redhat.com:/cvs/dist/tomcat5"
+           tag="tomcat5-5_5_9-1_patch05_1jpp_1jb"
+	-->
+      <artifact id="catalina-manager.jar"/>
+      <artifact id="catalina-optional.jar"/>
+      <artifact id="catalina.jar"/>
+      <artifact id="jasper-compiler-jdt.jar"/>
+      <artifact id="jasper-compiler.jar"/>
+      <artifact id="jasper-runtime.jar"/>
+      <artifact id="naming-resources.jar"/>
+      <artifact id="servlets-default.jar"/>
+      <artifact id="servlets-invoker.jar"/>
+      <artifact id="servlets-webdav.jar"/>
+      <artifact id="tomcat-ajp.jar"/>
+      <artifact id="tomcat-coyote.jar"/>
+      <artifact id="tomcat-http.jar"/>
+      <artifact id="tomcat-util.jar"/>
+
+      <import componentref="apache-logging">
+         <compatible version="1.0.3"/>
+         <compatible version="1.0.4jboss"/>
+      </import>
+      <import componentref="apache-modeler">
+         <compatible version="1.1"/>
+      </import>
+      <import componentref="commons-el">
+         <compatible version="1.0"/>
+      </import>
+      <export>
+         <include input="catalina-manager.jar"/>
+         <include input="catalina-optional.jar"/>
+         <include input="catalina.jar"/>
+         <include input="jasper-compiler-jdt.jar"/>
+         <include input="jasper-compiler.jar"/>
+         <include input="jasper-runtime.jar"/>
+         <include input="naming-resources.jar"/>
+         <include input="servlets-default.jar"/>
+         <include input="servlets-invoker.jar"/>
+         <include input="servlets-webdav.jar"/>
+         <include input="tomcat-ajp.jar"/>
+         <include input="tomcat-coyote.jar"/>
+         <include input="tomcat-http.jar"/>
+         <include input="tomcat-util.jar"/>
+      </export>
+   </component>
+</project>
+

Added: apache-tomcat/5.5.9.patch05-brew/lib/catalina-manager.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/catalina-manager.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/catalina-optional.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/catalina-optional.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/catalina.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/catalina.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler-jdt.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler-jdt.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/jasper-compiler.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/jasper-runtime.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/jasper-runtime.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/naming-resources.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/naming-resources.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/servlets-default.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/servlets-default.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/servlets-invoker.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/servlets-invoker.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/servlets-webdav.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/servlets-webdav.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-ajp.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-ajp.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-coyote.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-coyote.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-http.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-http.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-util.jar
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/lib/tomcat-util.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/src/jakarta-tomcat-5.5.9-src.tar.gz
===================================================================
(Binary files differ)


Property changes on: apache-tomcat/5.5.9.patch05-brew/src/jakarta-tomcat-5.5.9-src.tar.gz
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5-CVE-2007-5461-webdav.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5-CVE-2007-5461-webdav.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5-CVE-2007-5461-webdav.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,72 @@
+--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties.orig	2007-03-05 10:27:45.000000000 -0500
++++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/LocalStrings.properties	2007-11-07 11:36:48.410682000 -0500
+@@ -10,6 +10,7 @@
+ invokerServlet.notNamed=Cannot call invoker servlet with a named dispatcher
+ invokerServlet.noWrapper=Container has not called setWrapper() for this servlet
+ webdavservlet.jaxpfailed=JAXP initialization failed
++webdavservlet.enternalEntityIgnored=The request included a reference to an external entity with PublicID {0} and SystemID {1} which was ignored
+ directory.filename=Filename
+ directory.lastModified=Last Modified
+ directory.parent=Up To {0}
+--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java.orig	2005-03-26 14:24:01.000000000 -0500
++++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/WebdavServlet.java	2007-11-07 15:36:17.146510000 -0500
+@@ -19,6 +19,7 @@
+ 
+ 
+ import java.io.IOException;
++import java.io.StringReader;
+ import java.io.StringWriter;
+ import java.io.Writer;
+ import java.security.MessageDigest;
+@@ -35,6 +36,7 @@
+ import javax.naming.NamingEnumeration;
+ import javax.naming.NamingException;
+ import javax.naming.directory.DirContext;
++import javax.servlet.ServletContext;
+ import javax.servlet.ServletException;
+ import javax.servlet.UnavailableException;
+ import javax.servlet.http.HttpServletRequest;
+@@ -55,6 +57,7 @@
+ import org.w3c.dom.Element;
+ import org.w3c.dom.Node;
+ import org.w3c.dom.NodeList;
++import org.xml.sax.EntityResolver;
+ import org.xml.sax.InputSource;
+ import org.xml.sax.SAXException;
+ 
+@@ -247,6 +250,8 @@
+             documentBuilderFactory = DocumentBuilderFactory.newInstance();
+             documentBuilderFactory.setNamespaceAware(true);
+             documentBuilder = documentBuilderFactory.newDocumentBuilder();
++            documentBuilder.setEntityResolver(
++                    new WebdavResolver(this.getServletContext()));
+         } catch(ParserConfigurationException e) {
+             throw new ServletException
+                 (sm.getString("webdavservlet.jaxpfailed"));
+@@ -2759,6 +2764,26 @@
+     }
+ 
+ 
++    // --------------------------------------------- WebdavResolver Inner Class
++    /**
++     * Work around for XML parsers that don't fully respect
++     * {@link DocumentBuilderFactory#setExpandEntityReferences(false)}. External
++     * references are filtered out for security reasons. See CVE-2007-5461.
++     */
++    private class WebdavResolver implements EntityResolver {
++        private ServletContext context;
++        
++        public WebdavResolver(ServletContext theContext) {
++            context = theContext;
++        }
++     
++        public InputSource resolveEntity (String publicId, String systemId) {
++            context.log(sm.getString("webdavservlet.enternalEntityIgnored",
++                    publicId, systemId));
++            return new InputSource(
++                    new StringReader("Ignored external entity"));
++        }
++    }
+ };
+ 
+ 

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-Bug36863-backport.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-Bug36863-backport.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-Bug36863-backport.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,13 @@
+--- jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2005/12/06 03:15:42	354266
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2005/12/06 03:15:59	354267
+@@ -247,9 +247,8 @@
+             int startValue=skipSpaces( bytes, pos, end);
+             int endValue=startValue;
+             
+-            // quote is valid only in version=1 cookies
+             cc=bytes[pos];
+-            if( ( version == 1 || isSpecial ) && ( cc== '\'' || cc=='"' ) ) {
++            if(  cc== '\'' || cc=='"' ) {
+                 startValue++;
+                 endValue=indexOf( bytes, startValue, end, cc );
+                 pos=endValue+1; // to skip to next cookie

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2005-2090.5.0.x.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2005-2090.5.0.x.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2005-2090.5.0.x.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,39 @@
+--- jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Request.java	(revision 531784)
++++ jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/Request.java	(working copy)
+@@ -308,7 +308,7 @@
+     public long getContentLengthLong() {
+         if( contentLength > -1 ) return contentLength;
+ 
+-        MessageBytes clB = headers.getValue("content-length");
++        MessageBytes clB = headers.getUniqueValue("content-length");
+         contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong();
+ 
+         return contentLength;
+--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java	(revision 531784)
++++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java	(working copy)
+@@ -286,6 +286,25 @@
+         return null;
+     }
+ 
++    /**
++     * Finds and returns a unique header field with the given name. If no such
++     * field exists, null is returned. If the specified header field is not
++     * unique then an {@link IllegalArgumentException} is thrown.
++     */
++    public MessageBytes getUniqueValue(String name) {
++        MessageBytes result = null;
++        for (int i = 0; i < count; i++) {
++            if (headers[i].getName().equalsIgnoreCase(name)) {
++                if (result == null) {
++                    result = headers[i].getValue();
++                } else {
++                    throw new IllegalArgumentException();
++                }
++            }
++        }
++        return result;
++    }
++
+     // bad shortcut - it'll convert to string ( too early probably,
+     // encoding is guessed very late )
+     public String getHeader(String name) {

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-3835.5.5.x.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-3835.5.5.x.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-3835.5.5.x.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,34 @@
+--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java	2005/11/09 19:43:12	332126
++++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/servlets/DefaultServlet.java	2005/11/09 19:50:47	332127
+@@ -94,7 +94,7 @@
+     /**
+      * Should we generate directory listings?
+      */
+-    protected boolean listings = true;
++    protected boolean listings = false;
+ 
+ 
+     /**
+--- jakarta-tomcat-catalina/catalina/src/conf/web.xml	2005/11/09 19:43:12	332126
++++ jakarta-tomcat-catalina/catalina/src/conf/web.xml	2005/11/09 19:50:47	332127
+@@ -34,7 +34,10 @@
+   <!--                       resources to be served.  [2048]                -->
+   <!--                                                                      -->
+   <!--   listings            Should directory listings be produced if there -->
+-  <!--                       is no welcome file in this directory?  [true]  -->
++  <!--                       is no welcome file in this directory?  [false] -->
++  <!--                       WARNING: Listings for directories with many    -->
++  <!--                       entries can be slow and may consume            -->
++  <!--                       significant proportions of server resources.   -->
+   <!--                                                                      -->
+   <!--   output              Output buffer size (in bytes) when writing     -->
+   <!--                       resources to be served.  [2048]                -->
+@@ -69,7 +72,7 @@
+         </init-param>
+         <init-param>
+             <param-name>listings</param-name>
+-            <param-value>true</param-value>
++            <param-value>false</param-value>
+         </init-param>
+         <load-on-startup>1</load-on-startup>
+     </servlet>

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7195.5.0.x.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7195.5.0.x.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7195.5.0.x.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,49 @@
+--- jakarta-tomcat-catalina/webapps/docs/appdev/sample/src/mypackage/Hello.java	(revision 467215)
++++ jakarta-tomcat-catalina/webapps/docs/appdev/sample/src/mypackage/Hello.java	(working copy)
+@@ -69,24 +69,11 @@
+ 	writer.println("<td>");
+ 	writer.println("<h1>Sample Application Servlet</h1>");
+ 	writer.println("This is the output of a servlet that is part of");
+-	writer.println("the Hello, World application.  It displays the");
+-	writer.println("request headers from the request we are currently");
+-	writer.println("processing.");
++	writer.println("the Hello, World application.");
+ 	writer.println("</td>");
+ 	writer.println("</tr>");
+ 	writer.println("</table>");
+ 
+-	writer.println("<table border=\"0\" width=\"100%\">");
+-	Enumeration names = request.getHeaderNames();
+-	while (names.hasMoreElements()) {
+-	    String name = (String) names.nextElement();
+-	    writer.println("<tr>");
+-	    writer.println("  <th align=\"right\">" + name + ":</th>");
+-	    writer.println("  <td>" + request.getHeader(name) + "</td>");
+-	    writer.println("</tr>");
+-	}
+-	writer.println("</table>");
+-
+ 	writer.println("</body>");
+ 	writer.println("</html>");
+ 
+--- jakarta-servletapi-5/jsr152/examples/jsp2/el/implicit-objects.jsp	(revision 267240)
++++ jakarta-servletapi-5/jsr152/examples/jsp2/el/implicit-objects.jsp	(revision 428048)
+@@ -71,15 +71,15 @@
+ 	  </tr>
+ 	  <tr>
+ 	    <td>\${header["host"]}</td>
+-	    <td>${header["host"]}</td>
++	    <td>${fn:escapeXml(header["host"])}&nbsp;</td>
+ 	  </tr>
+ 	  <tr>
+ 	    <td>\${header["accept"]}</td>
+-	    <td>${header["accept"]}</td>
++	    <td>${fn:escapeXml(header["accept"])}&nbsp;</td>
+ 	  </tr>
+ 	  <tr>
+ 	    <td>\${header["user-agent"]}</td>
+-	    <td>${header["user-agent"]}</td>
++	    <td>${fn:escapeXml(header["user-agent"])}&nbsp;</td>
+ 	  </tr>
+ 	</table>
+       </code>

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7196.5.x.y.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7196.5.x.y.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2006-7196.5.x.y.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,17 @@
+--- jakarta-servletapi-5/jsr152/examples/cal/cal2.jsp	(revision 267240)
++++ jakarta-servletapi-5/jsr152/examples/cal/cal2.jsp	(revision 369933)
+@@ -29,12 +29,12 @@
+ 
+ <FONT SIZE=5> Please add the following event:
+ <BR> <h3> Date <%= table.getDate() %>
+-<BR> Time <%= time %> </h3>
++<BR> Time <%= util.HTMLFilter.filter(time) %> </h3>
+ </FONT>
+ <FORM METHOD=POST ACTION=cal1.jsp>
+ <BR> 
+ <BR> <INPUT NAME="date" TYPE=HIDDEN VALUE="current">
+-<BR> <INPUT NAME="time" TYPE=HIDDEN VALUE=<%= time %>
++<BR> <INPUT NAME="time" TYPE=HIDDEN VALUE=<%= util.HTMLFilter.filter(time) %>
+ <BR> <h2> Description of the event <INPUT NAME="description" TYPE=TEXT SIZE=20> </h2>
+ <BR> <INPUT TYPE=SUBMIT VALUE="submit">
+ </FORM>

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-0450.5.5.9.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-0450.5.5.9.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-0450.5.5.9.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,132 @@
+--- jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java	(revision 466585)
++++ jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteAdapter.java	(revision 519369)
+@@ -51,6 +51,10 @@
+ final class CoyoteAdapter
+     implements Adapter {
+ 
++    protected static final boolean ALLOW_BACKSLASH = Boolean.valueOf(
++            System.getProperty(
++                    "org.apache.coyote.tomcat4.CoyoteAdapter.ALLOW_BACKSLASH",
++                    "false")).booleanValue();
+ 
+     // -------------------------------------------------------------- Constants
+ 
+@@ -440,8 +444,12 @@
+             return "/";
+ 
+         // Normalize the slashes and add leading slash if necessary
+-        if (normalized.indexOf('\\') >= 0)
+-            normalized = normalized.replace('\\', '/');
++        if (normalized.indexOf('\\') >= 0) {
++            if ( ALLOW_BACKSLASH )
++                normalized = normalized.replace('\\', '/');
++            else 
++                return null;
++        }
+         if (!normalized.startsWith("/"))
+             normalized = "/" + normalized;
+ 
+@@ -564,8 +572,12 @@
+         // Replace '\' with '/'
+         // Check for null byte
+         for (pos = start; pos < end; pos++) {
+-            if (b[pos] == (byte) '\\')
+-                b[pos] = (byte) '/';
++            if (b[pos] == (byte) '\\') {
++                if (ALLOW_BACKSLASH)
++                    b[pos] = (byte) '/';
++                else 
++                    return false;
++            }
+             if (b[pos] == (byte) 0)
+                 return false;
+         }
+--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java	(revision 466608)
++++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java	(revision 507117)
+@@ -50,6 +50,8 @@
+  {
+     private static Log log = LogFactory.getLog(CoyoteAdapter.class);
+ 
++    protected static final boolean ALLOW_BACKSLASH = 
++        Boolean.valueOf(System.getProperty("org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH", "false")).booleanValue();
+     // -------------------------------------------------------------- Constants
+ 
+ 
+@@ -226,8 +228,8 @@
+                 req.getURLDecoder().convert(decodedURI, false);
+             } catch (IOException ioe) {
+                 res.setStatus(400);
+-                res.setMessage("Invalid URI");
+-                throw ioe;
++                res.setMessage("Invalid URI: " + ioe.getMessage());
++                return false;
+             }
+             // Normalization
+             if (!normalize(req.decodedURI())) {
+@@ -515,8 +517,13 @@
+         // Replace '\' with '/'
+         // Check for null byte
+         for (pos = start; pos < end; pos++) {
+-            if (b[pos] == (byte) '\\')
+-                b[pos] = (byte) '/';
++            if (b[pos] == (byte) '\\') {
++                if (ALLOW_BACKSLASH) {
++                    b[pos] = (byte) '/';
++                } else {
++                    return false;
++                }
++            }
+             if (b[pos] == (byte) 0)
+                 return false;
+         }
+--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/buf/UDecoder.java	(revision 481614)
++++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/buf/UDecoder.java	(revision 507117)
+@@ -30,6 +30,9 @@
+  */
+ public final class UDecoder {
+     
++    protected static final boolean ALLOW_ENCODED_SLASH = 
++        Boolean.valueOf(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "false")).booleanValue();
++    
+     public UDecoder() 
+     {
+     }
+@@ -63,6 +66,8 @@
+ 	// idx will be the smallest positive inxes ( first % or + )
+ 	if( idx2 >= 0 && idx2 < idx ) idx=idx2;
+ 	if( idx < 0 ) idx=idx2;
++    
++	boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
+ 
+ 	for( int j=idx; j<end; j++, idx++ ) {
+ 	    if( buff[ j ] == '+' && query) {
+@@ -81,6 +86,9 @@
+ 		
+ 		j+=2;
+ 		int res=x2c( b1, b2 );
++                if (noSlash && (res == '/')) {
++                    throw new CharConversionException( "noSlash");
++                }
+ 		buff[idx]=(byte)res;
+ 	    }
+ 	}
+@@ -122,7 +130,8 @@
+ 	
+ 	if( idx2 >= 0 && idx2 < idx ) idx=idx2; 
+ 	if( idx < 0 ) idx=idx2;
+-
++    
++	boolean noSlash = !(ALLOW_ENCODED_SLASH || query);
+ 	for( int j=idx; j<cend; j++, idx++ ) {
+ 	    if( buff[ j ] == '+' && query ) {
+ 		buff[idx]=( ' ' );
+@@ -141,6 +150,9 @@
+ 		
+ 		j+=2;
+ 		int res=x2c( b1, b2 );
++		if (noSlash && (res == '/')) {
++		    throw new CharConversionException( "noSlash");
++            	}
+ 		buff[idx]=(char)res;
+ 	    }
+ 	}

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-1858.5.5.9.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-1858.5.5.9.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-1858.5.5.9.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,11 @@
+--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java	2006/03/18 07:25:35	386818
++++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java	2006/03/18 07:26:00	386819
+@@ -188,7 +188,7 @@
+                 vec.copyInto(enabledCiphers);
+             }
+         } else {
+-            enabledCiphers = supportedCiphers;
++            enabledCiphers = sslProxy.getDefaultCipherSuites();
+         }
+ 
+         return enabledCiphers;

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2449.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2449.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2449.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,104 @@
+Index: jakarta-servletapi-5/jsr152/examples/source.jsp
+===================================================================
+--- jakarta-servletapi-5/jsr152/examples/source.jsp	(revision 547082)
++++ jakarta-servletapi-5/jsr152/examples/source.jsp	(revision 547083)
+@@ -17,4 +17,4 @@
+ <%@ taglib uri="http://jakarta.apache.org/tomcat/examples-taglib"
+         prefix="eg" %>
+ 
+-<eg:ShowSource jspFile="<%= request.getQueryString() %>"/>
++<eg:ShowSource jspFile="<%= util.HTMLFilter.filter(request.getQueryString()) %>"/>
+Index: jakarta-servletapi-5/jsr152/examples/snp/snoop.html
+===================================================================
+--- jakarta-servletapi-5/jsr152/examples/snp/snoop.html	(revision 547082)
++++ jakarta-servletapi-5/jsr152/examples/snp/snoop.html	(revision 547083)
+@@ -24,8 +24,8 @@
+ <body bgcolor="#FFFFFF">
+ <p><font color="#0000FF"><a href="snoop.jsp"><img src="../images/execute.gif" align="right" border="0"></a><a href="../index.html"><img src="../images/return.gif" width="24" height="24" align="right" border="0"></a></font></p>
+ 
+-<h3><a href="snoop.jsp.html">Source Code for Request Parameters Example<font color="#0000FF"></a>
+-  </font> </h3>
++<h3><a href="snoop.jsp.html">Source Code for Request Parameters Example<font color="#0000FF">
++  </font></a></h3>
+ 
+ </body>
+ </html>
+Index: jakarta-servletapi-5/jsr152/examples/snp/snoop.jsp
+===================================================================
+--- jakarta-servletapi-5/jsr152/examples/snp/snoop.jsp	(revision 547082)
++++ jakarta-servletapi-5/jsr152/examples/snp/snoop.jsp	(revision 547083)
+@@ -19,37 +19,38 @@
+ <body bgcolor="white">
+ <h1> Request Information </h1>
+ <font size="4">
+-JSP Request Method: <% out.print(util.HTMLFilter.filter(request.getMethod())); %>
++JSP Request Method: <%= util.HTMLFilter.filter(request.getMethod()) %>
+ <br>
+-Request URI: <%= request.getRequestURI() %>
++Request URI: <%= util.HTMLFilter.filter(request.getRequestURI()) %>
+ <br>
+-Request Protocol: <%= request.getProtocol() %>
++Request Protocol: <%= util.HTMLFilter.filter(request.getProtocol()) %>
+ <br>
+-Servlet path: <%= request.getServletPath() %>
++Servlet path: <%= util.HTMLFilter.filter(request.getServletPath()) %>
+ <br>
+-Path info: <% out.print(util.HTMLFilter.filter(request.getPathInfo())); %>
++Path info: <%= util.HTMLFilter.filter(request.getPathInfo()) %>
+ <br>
+-Query string: <% out.print(util.HTMLFilter.filter(request.getQueryString())); %>
++Query string: <%= util.HTMLFilter.filter(request.getQueryString()) %>
+ <br>
+ Content length: <%= request.getContentLength() %>
+ <br>
+-Content type: <% out.print(util.HTMLFilter.filter(request.getContentType())); %>
++Content type: <%= util.HTMLFilter.filter(request.getContentType()) %>
+ <br>
+-Server name: <%= request.getServerName() %>
++Server name: <%= util.HTMLFilter.filter(request.getServerName()) %>
+ <br>
+ Server port: <%= request.getServerPort() %>
+ <br>
+-Remote user: <%= request.getRemoteUser() %>
++Remote user: <%= util.HTMLFilter.filter(request.getRemoteUser()) %>
+ <br>
+-Remote address: <%= request.getRemoteAddr() %>
++Remote address: <%= util.HTMLFilter.filter(request.getRemoteAddr()) %>
+ <br>
+-Remote host: <%= request.getRemoteHost() %>
++Remote host: <%= util.HTMLFilter.filter(request.getRemoteHost()) %>
+ <br>
+-Authorization scheme: <%= request.getAuthType() %> 
++Authorization scheme: <%= util.HTMLFilter.filter(request.getAuthType()) %> 
+ <br>
+ Locale: <%= request.getLocale() %>
+ <hr>
+-The browser you are using is <% out.print(util.HTMLFilter.filter(request.getHeader("User-Agent"))); %>
++The browser you are using is
++<%= util.HTMLFilter.filter(request.getHeader("User-Agent")) %>
+ <hr>
+ </font>
+ </body>
+Index: jakarta-servletapi-5/jsr152/examples/security/protected/index.jsp
+===================================================================
+--- jakarta-servletapi-5/jsr152/examples/security/protected/index.jsp	(revision 547082)
++++ jakarta-servletapi-5/jsr152/examples/security/protected/index.jsp	(revision 547083)
+@@ -27,14 +27,16 @@
+ </head>
+ <body bgcolor="white">
+ 
+-You are logged in as remote user <b><%= request.getRemoteUser() %></b>
++You are logged in as remote user
++<b><%= util.HTMLFilter.filter(request.getRemoteUser()) %></b>
+ in session <b><%= session.getId() %></b><br><br>
+ 
+ <%
+   if (request.getUserPrincipal() != null) {
+ %>
+     Your user principal name is
+-    <b><%= request.getUserPrincipal().getName() %></b><br><br>
++    <b><%= util.HTMLFilter.filter(request.getUserPrincipal().getName()) %></b>
++    <br><br>
+ <%
+   } else {
+ %>

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2450_CVE-2007-3386.5.0.x.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2450_CVE-2007-3386.5.0.x.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-2450_CVE-2007-3386.5.0.x.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,71 @@
+--- ./jakarta-tomcat-catalina/webapps/host-manager/WEB-INF/classes/org/apache/catalina/hostmanager/HTMLHostManagerServlet.java.org	2005-03-26 20:24:09.000000000 +0100
++++ ./jakarta-tomcat-catalina/webapps/host-manager/WEB-INF/classes/org/apache/catalina/hostmanager/HTMLHostManagerServlet.java	2007-08-27 16:58:55.000000000 +0200
+@@ -31,6 +31,7 @@
+ 
+ import org.apache.catalina.Container;
+ import org.apache.catalina.Host;
++import org.apache.catalina.util.RequestUtil;
+ import org.apache.catalina.util.ServerInfo;
+ 
+ /**
+@@ -194,7 +195,11 @@
+         // Message Section
+         args = new Object[3];
+         args[0] = sm.getString("htmlHostManagerServlet.messageLabel");
+-        args[1] = (message == null || message.length() == 0) ? "OK" : message;
++        if (message == null || message.length() == 0) {
++            args[1] = "OK";
++        } else {
++            args[1] = RequestUtil.filter(message);
++        }
+         writer.print(MessageFormat.format(Constants.MESSAGE_SECTION, args));
+ 
+         // Manager Section
+@@ -247,7 +252,7 @@
+ 
+             if (host != null ) {
+                 args = new Object[2];
+-                args[0] = hostName;
++                args[0] = RequestUtil.filter(hostName);
+                 String[] aliases = host.findAliases();
+                 StringBuffer buf = new StringBuffer();
+                 if (aliases.length > 0) {
+@@ -256,7 +261,12 @@
+                         buf.append(", ").append(aliases[j]);
+                     }
+                 }
+-                args[1] = buf.toString();
++                if (buf.length() == 0) {
++                    buf.append("&nbsp;");
++                    args[1] = buf.toString();
++                } else {
++                    args[1] = RequestUtil.filter(buf.toString());
++                }
+                 writer.print
+                     (MessageFormat.format(HOSTS_ROW_DETAILS_SECTION, args));
+ 
+--- ./jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/HTMLManagerServlet.java.org	2007-08-27 16:52:04.000000000 +0200
++++ ./jakarta-tomcat-catalina/webapps/manager/WEB-INF/classes/org/apache/catalina/manager/HTMLManagerServlet.java	2007-08-27 16:53:58.000000000 +0200
+@@ -106,8 +106,7 @@
+             message = stop(path);
+         } else {
+             message =
+-                sm.getString("managerServlet.unknownCommand",
+-                             RequestUtil.filter(command));
++                sm.getString("managerServlet.unknownCommand", command);
+         }
+ 
+         list(request, response, message);
+@@ -281,7 +280,11 @@
+         // Message Section
+         args = new Object[3];
+         args[0] = sm.getString("htmlManagerServlet.messageLabel");
+-        args[1] = (message == null || message.length() == 0) ? "OK" : message;
++        if (message == null || message.length() == 0) {
++            args[1] = "OK";
++        } else {
++            args[1] = RequestUtil.filter(message);
++        }
+         writer.print(MessageFormat.format(Constants.MESSAGE_SECTION, args));
+ 
+         // Manager Section

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-3382_CVE-2007-3385.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-3382_CVE-2007-3385.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-3382_CVE-2007-3385.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,135 @@
+--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/ServerCookie.java	2007-03-05 16:27:39.000000000 +0100
++++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/ServerCookie.java	2007-08-24 14:40:51.000000000 +0200
+@@ -129,6 +129,7 @@
+     //
+     // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
+     private static final String tspecials = ",; ";
++    private static final String tspecials2 = ",; \"";
+ 
+     /*
+      * Tests a string and returns true if the string counts as a
+@@ -153,6 +154,20 @@
+ 	return true;
+     }
+ 
++    public static boolean isToken2(String value) {
++        if( value==null) return true;
++        int len = value.length();
++
++        for (int i = 0; i < len; i++) {
++            char c = value.charAt(i);
++
++            if (c < 0x20 || c >= 0x7f || tspecials2.indexOf(c) != -1)
++                return false;
++        }
++        return true;
++    }
++
++
+     public static boolean checkName( String name ) {
+ 	if (!isToken(name)
+ 		|| name.equalsIgnoreCase("Comment")	// rfc2019
+@@ -212,7 +227,7 @@
+         // this part is the same for all cookies
+ 	buf.append( name );
+         buf.append("=");
+-        maybeQuote(version, buf, value);
++        maybeQuote2(version, buf, value);
+ 
+ 	// XXX Netscape cookie: "; "
+  	// add version 1 specific information
+@@ -283,6 +298,20 @@
+         }
+     }
+ 
++
++    public static void maybeQuote2 (int version, StringBuffer buf,
++            String value) {
++        // special case - a \n or \r  shouldn't happen in any case
++        if (isToken2(value)) {
++            buf.append(value);
++        } else {
++            buf.append('"');
++            buf.append(escapeDoubleQuotes(value));
++            buf.append('"');
++        }
++    }
++
++
+     // log
+     static final int dbg=1;
+     public static void log(String s ) {
+@@ -305,12 +334,14 @@
+         }
+ 
+         StringBuffer b = new StringBuffer();
++        char p = s.charAt(0);
+         for (int i = 0; i < s.length(); i++) {
+             char c = s.charAt(i);
+-            if (c == '"')
++            if (c == '"' && p != '\\')
+                 b.append('\\').append('"');
+             else
+                 b.append(c);
++            p = c;
+         }
+ 
+         return b.toString();
+--- ./jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2007-08-24 14:15:10.000000000 +0200
++++ ./jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2007-08-24 14:50:26.000000000 +0200
+@@ -249,9 +249,11 @@
+             int endValue=startValue;
+             
+             cc=bytes[pos];
+-            if(  cc== '\'' || cc=='"' ) {
+-                startValue++;
+-                endValue=indexOf( bytes, startValue, end, cc );
++            if(  cc=='"' ) {
++                endValue=findDelim3( bytes, startValue+1, end, cc );
++                if (endValue == -1) {
++                    endValue = findDelim2(bytes, startValue+1, end);
++                } else startValue++;
+                 pos=endValue+1; // to skip to next cookie
+              } else {
+                 endValue=findDelim2( bytes, startValue, end );
+@@ -335,28 +337,26 @@
+         return off;
+     }
+ 
+-    public static int indexOf( byte bytes[], int off, int end, byte qq )
++    /*
++     *  search for cc but skip \cc as required by rfc2616
++     *  (according to rfc2616 cc should be ")
++     */
++    public static int findDelim3( byte bytes[], int off, int end, byte cc )
+     {
+         while( off < end ) {
+             byte b=bytes[off];
+-            if( b==qq )
++            if (b=='\\') {
++                off++;
++                off++;
++                continue;
++            }
++            if( b==cc )
+                 return off;
+             off++;
+         }
+-        return off;
++        return -1;
+     }
+ 
+-    public static int indexOf( byte bytes[], int off, int end, char qq )
+-    {
+-        while( off < end ) {
+-            byte b=bytes[off];
+-            if( b==qq )
+-                return off;
+-            off++;
+-        }
+-        return off;
+-    }
+-    
+     // XXX will be refactored soon!
+     public static boolean equals( String s, byte b[], int start, int end) {
+         int blen = end-start;

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-5342.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-5342.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2007-5342.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,25 @@
+--- jakarta-tomcat-catalina/catalina/src/conf/catalina.policy	2007/09/02 21:16:25	572160
++++ jakarta-tomcat-catalina/catalina/src/conf/catalina.policy	2008/01/06 22:38:14	609451
+@@ -82,7 +82,19 @@
+ 
+ // These permissions apply to JULI
+ grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
+-        permission java.security.AllPermission;
++        permission java.util.PropertyPermission "java.util.logging.config.class", "read";
++        permission java.util.PropertyPermission "java.util.logging.config.file", "read";
++        permission java.lang.RuntimePermission "shutdownHooks";
++        permission java.io.FilePermission "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
++        permission java.util.PropertyPermission "catalina.base", "read";
++        permission java.util.logging.LoggingPermission "control";
++        permission java.io.FilePermission "${catalina.base}${file.separator}logs", "read, write";
++        permission java.io.FilePermission "${catalina.base}${file.separator}logs${file.separator}*", "read, write";
++        permission java.lang.RuntimePermission "getClassLoader";
++        // To enable per context logging configuration, permit read access to the appropriate file.
++        // Be sure that the logging configuration is secure before enabling such access
++        // eg for the examples web application:
++        // permission java.io.FilePermission "${catalina.base}${file.separator}webapps${file.separator}examples${file.separator}WEB-INF${file.separator}classes${file.separator}logging.properties", "read";
+ };
+ 
+ // These permissions apply to the servlet API classes
+
+

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2008-0128.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2008-0128.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-CVE-2008-0128.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,13 @@
+--- ./jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/AuthenticatorBase.java.orig	2008-04-10 11:29:31.000000000 -0400
++++ ./jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/AuthenticatorBase.java	2008-04-10 11:30:19.000000000 -0400
+@@ -699,6 +699,10 @@ public abstract class AuthenticatorBase
+             Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, ssoId);
+             cookie.setMaxAge(-1);
+             cookie.setPath("/");
++            // Bugzilla 41217
++            javax.servlet.ServletRequest r = (javax.servlet.ServletRequest) request;
++            cookie.setSecure(r.isSecure());
++
+             response.addCookie(cookie);
+ 
+             // Register this principal with our SSO valve

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-IT168408.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-IT168408.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-IT168408.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,29 @@
+--- jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Parameters.java	2008-03-31 10:25:46.000000000 +0200
++++ jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/Parameters.java	2008-03-31 14:30:26.000000000 +0200
+@@ -499,17 +499,13 @@
+     public void processParameters( MessageBytes data, String encoding ) {
+ 	if( data==null || data.isNull() || data.getLength() <= 0 ) return;
+ 
+-	if( data.getType() == MessageBytes.T_BYTES ) {
+-	    ByteChunk bc=data.getByteChunk();
+-	    processParameters( bc.getBytes(), bc.getOffset(),
+-			       bc.getLength(), encoding);
+-	} else {
+-	    if (data.getType()!= MessageBytes.T_CHARS ) 
+-		data.toChars();
+-	    CharChunk cc=data.getCharChunk();
+-	    processParameters( cc.getChars(), cc.getOffset(),
+-			       cc.getLength());
+-	}
++        if (data.getType() != MessageBytes.T_BYTES) {
++            data.toBytes();
++        }
++        ByteChunk bc=data.getByteChunk();
++        processParameters( bc.getBytes(), bc.getOffset(),
++                           bc.getLength(), encoding);
++
+     }
+ 
+     /** Debug purpose
+
+

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-jboss.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-jboss.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-jboss.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,5731 @@
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-servletapi-5/jakarta-servletapi-5.iml jakarta-tomcat-5.5.9-src/jakarta-servletapi-5/jakarta-servletapi-5.iml
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-servletapi-5/jakarta-servletapi-5.iml	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-servletapi-5/jakarta-servletapi-5.iml	2005-09-26 01:21:13.000000000 -0400
+@@ -0,0 +1,21 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<module version="4" relativePaths="true" type="JAVA_MODULE">
++  <component name="ModuleRootManager" />
++  <component name="NewModuleRootManager">
++    <output url="file://$MODULE_DIR$/classes" />
++    <exclude-output />
++    <content url="file://$MODULE_DIR$">
++      <sourceFolder url="file://$MODULE_DIR$/jsr152/examples/WEB-INF/classes" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr152/examples/WEB-INF/jsp/applet" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr152/examples/plugin/applet" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr152/src/ant" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr152/src/share" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr154/examples/WEB-INF/classes" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jsr154/src/share" isTestSource="false" />
++    </content>
++    <orderEntry type="inheritedJdk" />
++    <orderEntry type="sourceFolder" forTests="false" />
++    <orderEntryProperties />
++  </component>
++</module>
++
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/build.properties.default jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/build.properties.default
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/build.properties.default	2005-03-26 14:22:24.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/build.properties.default	2005-09-26 01:27:47.000000000 -0400
+@@ -42,8 +42,8 @@
+ cvsroot=":pserver:anoncvs at cvs.apache.org:/home/cvspublic"
+ 
+ # ----- Default Base Path for Dependent Packages -----
+-base.path=/usr/share/java
+-#base.path=C:/path/to/the/repository
++base.path=/usr/share/java
++#base.path=C:/tmp/share/java
+ #base.path=/usr/local
+ 
+ # ----- Jakarta files base location -----
+@@ -59,7 +59,7 @@
+ base-struts.loc=http://archive.apache.org/dist/struts
+ 
+ # ----- Sourceforge files base location -----
+-base-sf.loc=http://unc.dl.sourceforge.net/sourceforge
++base-sf.loc=http://easynews.dl.sourceforge.net/sourceforge
+ 
+ # --------------------------------------------------
+ #                REQUIRED LIBRARIES
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/jakarta-tomcat-5.iml jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/jakarta-tomcat-5.iml
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/jakarta-tomcat-5.iml	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-5/jakarta-tomcat-5.iml	2005-09-26 01:21:13.000000000 -0400
+@@ -0,0 +1,13 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<module version="4" relativePaths="true" type="JAVA_MODULE">
++  <component name="ModuleRootManager" />
++  <component name="NewModuleRootManager">
++    <output url="file://$MODULE_DIR$/classes" />
++    <exclude-output />
++    <content url="file://$MODULE_DIR$" />
++    <orderEntry type="inheritedJdk" />
++    <orderEntry type="sourceFolder" forTests="false" />
++    <orderEntryProperties />
++  </component>
++</module>
++
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java	2005-03-26 14:22:34.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java	2005-09-26 01:31:04.000000000 -0400
+@@ -5008,6 +5008,10 @@
+                 destroy();
+                 throw e;
+             }
++            // It's possible that addChild may have started us
++            if( initialized ) {
++                return;
++            }
+         }
+         super.init();
+         
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java-1.177.txt jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java-1.177.txt
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java-1.177.txt	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java-1.177.txt	2005-09-26 01:29:47.000000000 -0400
+@@ -0,0 +1,5372 @@
++/*
++ * Copyright 1999,2004-2005 The Apache Software Foundation.
++ * 
++ * 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.apache.catalina.core;
++
++import java.io.BufferedReader;
++import java.io.File;
++import java.io.FileInputStream;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.InputStreamReader;
++import java.io.ObjectOutputStream;
++import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.Hashtable;
++import java.util.Iterator;
++import java.util.Stack;
++import java.util.TreeMap;
++
++import javax.management.ListenerNotFoundException;
++import javax.management.MBeanNotificationInfo;
++import javax.management.MBeanRegistrationException;
++import javax.management.MBeanServer;
++import javax.management.MalformedObjectNameException;
++import javax.management.Notification;
++import javax.management.NotificationBroadcasterSupport;
++import javax.management.NotificationEmitter;
++import javax.management.NotificationFilter;
++import javax.management.NotificationListener;
++import javax.management.ObjectName;
++import javax.naming.NamingException;
++import javax.naming.directory.DirContext;
++import javax.servlet.FilterConfig;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletContextAttributeListener;
++import javax.servlet.ServletContextEvent;
++import javax.servlet.ServletContextListener;
++import javax.servlet.ServletException;
++import javax.servlet.ServletRequestAttributeListener;
++import javax.servlet.ServletRequestListener;
++import javax.servlet.http.HttpSessionAttributeListener;
++import javax.servlet.http.HttpSessionListener;
++
++import org.apache.catalina.Container;
++import org.apache.catalina.ContainerListener;
++import org.apache.catalina.Context;
++import org.apache.catalina.Engine;
++import org.apache.catalina.Globals;
++import org.apache.catalina.Host;
++import org.apache.catalina.InstanceListener;
++import org.apache.catalina.Lifecycle;
++import org.apache.catalina.LifecycleException;
++import org.apache.catalina.LifecycleListener;
++import org.apache.catalina.Loader;
++import org.apache.catalina.Wrapper;
++import org.apache.catalina.deploy.ApplicationParameter;
++import org.apache.catalina.deploy.ErrorPage;
++import org.apache.catalina.deploy.FilterDef;
++import org.apache.catalina.deploy.FilterMap;
++import org.apache.catalina.deploy.LoginConfig;
++import org.apache.catalina.deploy.MessageDestination;
++import org.apache.catalina.deploy.MessageDestinationRef;
++import org.apache.catalina.deploy.NamingResources;
++import org.apache.catalina.deploy.SecurityCollection;
++import org.apache.catalina.deploy.SecurityConstraint;
++import org.apache.catalina.loader.WebappLoader;
++import org.apache.catalina.startup.ContextConfig;
++import org.apache.catalina.startup.TldConfig;
++import org.apache.catalina.util.CharsetMapper;
++import org.apache.catalina.util.ExtensionValidator;
++import org.apache.catalina.util.RequestUtil;
++import org.apache.catalina.util.URLEncoder;
++import org.apache.commons.logging.Log;
++import org.apache.commons.logging.LogFactory;
++import org.apache.commons.modeler.Registry;
++import org.apache.naming.ContextBindings;
++import org.apache.naming.resources.BaseDirContext;
++import org.apache.naming.resources.DirContextURLStreamHandler;
++import org.apache.naming.resources.FileDirContext;
++import org.apache.naming.resources.ProxyDirContext;
++import org.apache.naming.resources.WARDirContext;
++import org.apache.tomcat.util.compat.JdkCompat;
++
++/**
++ * Standard implementation of the <b>Context</b> interface.  Each
++ * child container must be a Wrapper implementation to process the
++ * requests directed to a particular servlet.
++ *
++ * @author Craig R. McClanahan
++ * @author Remy Maucherat
++ * @version $Revision: 1.177 $ $Date: 2005/09/25 00:27:53 $
++ */
++
++public class StandardContext
++    extends ContainerBase
++    implements Context, Serializable, NotificationEmitter
++{
++    private static transient Log log = LogFactory.getLog(StandardContext.class);
++
++
++    // ----------------------------------------------------------- Constructors
++
++
++    /**
++     * Create a new StandardContext component with the default basic Valve.
++     */
++    public StandardContext() {
++
++        super();
++        pipeline.setBasic(new StandardContextValve());
++        broadcaster = new NotificationBroadcasterSupport();
++
++    }
++
++
++    // ----------------------------------------------------- Class Variables
++
++
++    /**
++     * The descriptive information string for this implementation.
++     */
++    private static final String info =
++        "org.apache.catalina.core.StandardContext/1.0";
++
++
++    /**
++     * JDK compatibility support
++     */
++    private static final JdkCompat jdkCompat = JdkCompat.getJdkCompat();
++
++
++    /**
++     * Array containing the safe characters set.
++     */
++    protected static URLEncoder urlEncoder;
++
++
++    /**
++     * GMT timezone - all HTTP dates are on GMT
++     */
++    static {
++        urlEncoder = new URLEncoder();
++        urlEncoder.addSafeCharacter('~');
++        urlEncoder.addSafeCharacter('-');
++        urlEncoder.addSafeCharacter('_');
++        urlEncoder.addSafeCharacter('.');
++        urlEncoder.addSafeCharacter('*');
++        urlEncoder.addSafeCharacter('/');
++    }
++
++
++    // ----------------------------------------------------- Instance Variables
++
++
++    /**
++     * The alternate deployment descriptor name.
++     */
++    private String altDDName = null;
++
++
++    /**
++     * Associated host name.
++     */
++    private String hostName;
++
++
++    /**
++     * The antiJARLocking flag for this Context.
++     */
++    private boolean antiJARLocking = false;
++
++    
++    /**
++     * The antiResourceLocking flag for this Context.
++     */
++    private boolean antiResourceLocking = false;
++
++    
++    /**
++     * The set of application listener class names configured for this
++     * application, in the order they were encountered in the web.xml file.
++     */
++    private String applicationListeners[] = new String[0];
++
++
++    /**
++     * The set of instantiated application event listener objects</code>.
++     */
++    private transient Object applicationEventListenersObjects[] = 
++        new Object[0];
++
++
++    /**
++     * The set of instantiated application lifecycle listener objects</code>.
++     */
++    private transient Object applicationLifecycleListenersObjects[] = 
++        new Object[0];
++
++
++    /**
++     * The set of application parameters defined for this application.
++     */
++    private ApplicationParameter applicationParameters[] =
++        new ApplicationParameter[0];
++
++
++    /**
++     * The application available flag for this Context.
++     */
++    private boolean available = false;
++    
++    /**
++     * The broadcaster that sends j2ee notifications. 
++     */
++    private NotificationBroadcasterSupport broadcaster = null;
++    
++    /**
++     * The Locale to character set mapper for this application.
++     */
++    private transient CharsetMapper charsetMapper = null;
++
++
++    /**
++     * The Java class name of the CharsetMapper class to be created.
++     */
++    private String charsetMapperClass =
++      "org.apache.catalina.util.CharsetMapper";
++
++
++    /**
++     * The path to a file to save this Context information.
++     */
++    private String configFile = null;
++
++
++    /**
++     * The "correctly configured" flag for this Context.
++     */
++    private boolean configured = false;
++
++
++    /**
++     * The security constraints for this web application.
++     */
++    private SecurityConstraint constraints[] = new SecurityConstraint[0];
++
++
++    /**
++     * The ServletContext implementation associated with this Context.
++     */
++    private transient ApplicationContext context = null;
++
++
++    /**
++     * Compiler classpath to use.
++     */
++    private String compilerClasspath = null;
++
++
++    /**
++     * Should we attempt to use cookies for session id communication?
++     */
++    private boolean cookies = true;
++
++
++    /**
++     * Should we allow the <code>ServletContext.getContext()</code> method
++     * to access the context of other web applications in this server?
++     */
++    private boolean crossContext = false;
++
++    
++    /**
++     * Encoded path.
++     */
++    private String encodedPath = null;
++    
++
++    /**
++     * The "follow standard delegation model" flag that will be used to
++     * configure our ClassLoader.
++     */
++    private boolean delegate = false;
++
++
++     /**
++     * The display name of this web application.
++     */
++    private String displayName = null;
++
++
++    /** 
++     * Override the default context xml location.
++     */
++    private String defaultContextXml;
++
++
++    /** 
++     * Override the default web xml location.
++     */
++    private String defaultWebXml;
++
++
++    /**
++     * The distributable flag for this web application.
++     */
++    private boolean distributable = false;
++
++
++    /**
++     * The document root for this web application.
++     */
++    private String docBase = null;
++
++
++    /**
++     * The exception pages for this web application, keyed by fully qualified
++     * class name of the Java exception.
++     */
++    private HashMap exceptionPages = new HashMap();
++
++
++    /**
++     * The set of filter configurations (and associated filter instances) we
++     * have initialized, keyed by filter name.
++     */
++    private HashMap filterConfigs = new HashMap();
++
++
++    /**
++     * The set of filter definitions for this application, keyed by
++     * filter name.
++     */
++    private HashMap filterDefs = new HashMap();
++
++
++    /**
++     * The set of filter mappings for this application, in the order
++     * they were defined in the deployment descriptor.
++     */
++    private FilterMap filterMaps[] = new FilterMap[0];
++
++
++    /**
++     * The set of classnames of InstanceListeners that will be added
++     * to each newly created Wrapper by <code>createWrapper()</code>.
++     */
++    private String instanceListeners[] = new String[0];
++
++
++    /**
++     * The login configuration descriptor for this web application.
++     */
++    private LoginConfig loginConfig = null;
++
++
++    /**
++     * The mapper associated with this context.
++     */
++    private org.apache.tomcat.util.http.mapper.Mapper mapper = 
++        new org.apache.tomcat.util.http.mapper.Mapper();
++
++
++    /**
++     * The naming context listener for this web application.
++     */
++    private transient NamingContextListener namingContextListener = null;
++
++
++    /**
++     * The naming resources for this web application.
++     */
++    private NamingResources namingResources = null;
++
++
++    /**
++     * The message destinations for this web application.
++     */
++    private HashMap messageDestinations = new HashMap();
++
++
++    /**
++     * The MIME mappings for this web application, keyed by extension.
++     */
++    private HashMap mimeMappings = new HashMap();
++
++
++     /**
++      * Special case: error page for status 200.
++      */
++     private ErrorPage okErrorPage = null;
++
++
++    /**
++     * The context initialization parameters for this web application,
++     * keyed by name.
++     */
++    private HashMap parameters = new HashMap();
++
++
++    /**
++     * The request processing pause flag (while reloading occurs)
++     */
++    private boolean paused = false;
++
++
++    /**
++     * The public identifier of the DTD for the web application deployment
++     * descriptor version we are currently parsing.  This is used to support
++     * relaxed validation rules when processing version 2.2 web.xml files.
++     */
++    private String publicId = null;
++
++
++    /**
++     * The reloadable flag for this web application.
++     */
++    private boolean reloadable = false;
++
++
++    /**
++     * Unpack WAR property.
++     */
++    private boolean unpackWAR = true;
++
++
++    /**
++     * The DefaultContext override flag for this web application.
++     */
++    private boolean override = false;
++
++
++    /**
++     * The privileged flag for this web application.
++     */
++    private boolean privileged = false;
++
++
++    /**
++     * Should the next call to <code>addWelcomeFile()</code> cause replacement
++     * of any existing welcome files?  This will be set before processing the
++     * web application's deployment descriptor, so that application specified
++     * choices <strong>replace</strong>, rather than append to, those defined
++     * in the global descriptor.
++     */
++    private boolean replaceWelcomeFiles = false;
++
++
++    /**
++     * The security role mappings for this application, keyed by role
++     * name (as used within the application).
++     */
++    private HashMap roleMappings = new HashMap();
++
++
++    /**
++     * The security roles for this application, keyed by role name.
++     */
++    private String securityRoles[] = new String[0];
++
++
++    /**
++     * The servlet mappings for this web application, keyed by
++     * matching pattern.
++     */
++    private HashMap servletMappings = new HashMap();
++
++
++    /**
++     * The session timeout (in minutes) for this web application.
++     */
++    private int sessionTimeout = 30;
++
++    /**
++     * The notification sequence number.
++     */
++    private long sequenceNumber = 0;
++    
++    /**
++     * The status code error pages for this web application, keyed by
++     * HTTP status code (as an Integer).
++     */
++    private HashMap statusPages = new HashMap();
++
++
++    /**
++     * Set flag to true to cause the system.out and system.err to be redirected
++     * to the logger when executing a servlet.
++     */
++    private boolean swallowOutput = false;
++
++
++    /**
++     * The JSP tag libraries for this web application, keyed by URI
++     */
++    private HashMap taglibs = new HashMap();
++
++
++    /**
++     * The watched resources for this application.
++     */
++    private String watchedResources[] = new String[0];
++
++
++    /**
++     * The welcome files for this application.
++     */
++    private String welcomeFiles[] = new String[0];
++
++
++    /**
++     * The set of classnames of LifecycleListeners that will be added
++     * to each newly created Wrapper by <code>createWrapper()</code>.
++     */
++    private String wrapperLifecycles[] = new String[0];
++
++
++    /**
++     * The set of classnames of ContainerListeners that will be added
++     * to each newly created Wrapper by <code>createWrapper()</code>.
++     */
++    private String wrapperListeners[] = new String[0];
++
++
++    /**
++     * The pathname to the work directory for this context (relative to
++     * the server's home if not absolute).
++     */
++    private String workDir = null;
++
++
++    /**
++     * Java class name of the Wrapper class implementation we use.
++     */
++    private String wrapperClassName = StandardWrapper.class.getName();
++    private Class wrapperClass = null;
++
++
++    /**
++     * JNDI use flag.
++     */
++    private boolean useNaming = true;
++
++
++    /**
++     * Filesystem based flag.
++     */
++    private boolean filesystemBased = false;
++
++
++    /**
++     * Name of the associated naming context.
++     */
++    private String namingContextName = null;
++
++
++    /**
++     * Caching allowed flag.
++     */
++    private boolean cachingAllowed = true;
++
++
++    /**
++     * Case sensitivity.
++     */
++    protected boolean caseSensitive = true;
++
++
++    /**
++     * Allow linking.
++     */
++    protected boolean allowLinking = false;
++
++
++    /**
++     * Cache max size in KB.
++     */
++    protected int cacheMaxSize = 10240; // 10 MB
++
++
++    /**
++     * Cache TTL in ms.
++     */
++    protected int cacheTTL = 5000;
++
++
++    private boolean lazy=true;
++
++    /**
++     * Non proxied resources.
++     */
++    private transient DirContext webappResources = null;
++
++    private long startupTime;
++    private long startTime;
++    private long tldScanTime;
++
++    /** 
++     * Name of the engine. If null, the domain is used.
++     */ 
++    private String engineName = null;
++    private String j2EEApplication="none";
++    private String j2EEServer="none";
++
++
++    /**
++     * Attribute value used to turn on/off XML validation
++     */
++     private boolean webXmlValidation = false;
++
++
++    /**
++     * Attribute value used to turn on/off XML namespace validation
++     */
++     private boolean webXmlNamespaceAware = false;
++
++    /**
++     * Attribute value used to turn on/off TLD processing
++     */
++    private boolean processTlds = true;
++
++    /**
++     * Attribute value used to turn on/off XML validation
++     */
++     private boolean tldValidation = false;
++
++
++    /**
++     * Attribute value used to turn on/off TLD XML namespace validation
++     */
++     private boolean tldNamespaceAware = false;
++
++
++    /**
++     * Should we save the configuration.
++     */
++    private boolean saveConfig = true;
++
++
++    // ----------------------------------------------------- Context Properties
++
++
++    public String getEncodedPath() {
++        return encodedPath;
++    }
++
++
++    public void setName( String name ) {
++        super.setName( name );
++        encodedPath = urlEncoder.encode(name);
++    }
++
++
++    /**
++     * Is caching allowed ?
++     */
++    public boolean isCachingAllowed() {
++        return cachingAllowed;
++    }
++
++
++    /**
++     * Set caching allowed flag.
++     */
++    public void setCachingAllowed(boolean cachingAllowed) {
++        this.cachingAllowed = cachingAllowed;
++    }
++
++
++    /**
++     * Set case sensitivity.
++     */
++    public void setCaseSensitive(boolean caseSensitive) {
++        this.caseSensitive = caseSensitive;
++    }
++
++
++    /**
++     * Is case sensitive ?
++     */
++    public boolean isCaseSensitive() {
++        return caseSensitive;
++    }
++
++
++    /**
++     * Set allow linking.
++     */
++    public void setAllowLinking(boolean allowLinking) {
++        this.allowLinking = allowLinking;
++    }
++
++
++    /**
++     * Is linking allowed.
++     */
++    public boolean isAllowLinking() {
++        return allowLinking;
++    }
++
++
++    /**
++     * Set cache TTL.
++     */
++    public void setCacheTTL(int cacheTTL) {
++        this.cacheTTL = cacheTTL;
++    }
++
++
++    /**
++     * Get cache TTL.
++     */
++    public int getCacheTTL() {
++        return cacheTTL;
++    }
++
++
++    /**
++     * Return the maximum size of the cache in KB.
++     */
++    public int getCacheMaxSize() {
++        return cacheMaxSize;
++    }
++
++
++    /**
++     * Set the maximum size of the cache in KB.
++     */
++    public void setCacheMaxSize(int cacheMaxSize) {
++        this.cacheMaxSize = cacheMaxSize;
++    }
++
++
++    /**
++     * Return the "follow standard delegation model" flag used to configure
++     * our ClassLoader.
++     */
++    public boolean getDelegate() {
++
++        return (this.delegate);
++
++    }
++
++
++    /**
++     * Set the "follow standard delegation model" flag used to configure
++     * our ClassLoader.
++     *
++     * @param delegate The new flag
++     */
++    public void setDelegate(boolean delegate) {
++
++        boolean oldDelegate = this.delegate;
++        this.delegate = delegate;
++        support.firePropertyChange("delegate", new Boolean(oldDelegate),
++                                   new Boolean(this.delegate));
++
++    }
++
++
++    /**
++     * Returns true if the internal naming support is used.
++     */
++    public boolean isUseNaming() {
++
++        return (useNaming);
++
++    }
++
++
++    /**
++     * Enables or disables naming.
++     */
++    public void setUseNaming(boolean useNaming) {
++        this.useNaming = useNaming;
++    }
++
++
++    /**
++     * Returns true if the resources associated with this context are
++     * filesystem based.
++     */
++    public boolean isFilesystemBased() {
++
++        return (filesystemBased);
++
++    }
++
++
++    /**
++     * Return the set of initialized application event listener objects,
++     * in the order they were specified in the web application deployment
++     * descriptor, for this application.
++     *
++     * @exception IllegalStateException if this method is called before
++     *  this application has started, or after it has been stopped
++     */
++    public Object[] getApplicationEventListeners() {
++        return (applicationEventListenersObjects);
++    }
++
++
++    /**
++     * Store the set of initialized application event listener objects,
++     * in the order they were specified in the web application deployment
++     * descriptor, for this application.
++     *
++     * @param listeners The set of instantiated listener objects.
++     */
++    public void setApplicationEventListeners(Object listeners[]) {
++        applicationEventListenersObjects = listeners;
++    }
++
++
++    /**
++     * Return the set of initialized application lifecycle listener objects,
++     * in the order they were specified in the web application deployment
++     * descriptor, for this application.
++     *
++     * @exception IllegalStateException if this method is called before
++     *  this application has started, or after it has been stopped
++     */
++    public Object[] getApplicationLifecycleListeners() {
++        return (applicationLifecycleListenersObjects);
++    }
++
++
++    /**
++     * Store the set of initialized application lifecycle listener objects,
++     * in the order they were specified in the web application deployment
++     * descriptor, for this application.
++     *
++     * @param listeners The set of instantiated listener objects.
++     */
++    public void setApplicationLifecycleListeners(Object listeners[]) {
++        applicationLifecycleListenersObjects = listeners;
++    }
++
++
++    /**
++     * Return the antiJARLocking flag for this Context.
++     */
++    public boolean getAntiJARLocking() {
++
++        return (this.antiJARLocking);
++
++    }
++
++
++    /**
++     * Return the antiResourceLocking flag for this Context.
++     */
++    public boolean getAntiResourceLocking() {
++
++        return (this.antiResourceLocking);
++
++    }
++
++
++    /**
++     * Set the antiJARLocking feature for this Context.
++     *
++     * @param antiJARLocking The new flag value
++     */
++    public void setAntiJARLocking(boolean antiJARLocking) {
++
++        boolean oldAntiJARLocking = this.antiJARLocking;
++        this.antiJARLocking = antiJARLocking;
++        support.firePropertyChange("antiJARLocking",
++                                   new Boolean(oldAntiJARLocking),
++                                   new Boolean(this.antiJARLocking));
++
++    }
++
++
++    /**
++     * Set the antiResourceLocking feature for this Context.
++     *
++     * @param antiResourceLocking The new flag value
++     */
++    public void setAntiResourceLocking(boolean antiResourceLocking) {
++
++        boolean oldAntiResourceLocking = this.antiResourceLocking;
++        this.antiResourceLocking = antiResourceLocking;
++        support.firePropertyChange("antiResourceLocking",
++                                   new Boolean(oldAntiResourceLocking),
++                                   new Boolean(this.antiResourceLocking));
++
++    }
++
++
++    /**
++     * Return the application available flag for this Context.
++     */
++    public boolean getAvailable() {
++
++        return (this.available);
++
++    }
++
++
++    /**
++     * Set the application available flag for this Context.
++     *
++     * @param available The new application available flag
++     */
++    public void setAvailable(boolean available) {
++
++        boolean oldAvailable = this.available;
++        this.available = available;
++        support.firePropertyChange("available",
++                                   new Boolean(oldAvailable),
++                                   new Boolean(this.available));
++
++    }
++
++
++    /**
++     * Return the Locale to character set mapper for this Context.
++     */
++    public CharsetMapper getCharsetMapper() {
++
++        // Create a mapper the first time it is requested
++        if (this.charsetMapper == null) {
++            try {
++                Class clazz = Class.forName(charsetMapperClass);
++                this.charsetMapper =
++                  (CharsetMapper) clazz.newInstance();
++            } catch (Throwable t) {
++                this.charsetMapper = new CharsetMapper();
++            }
++        }
++
++        return (this.charsetMapper);
++
++    }
++
++
++    /**
++     * Set the Locale to character set mapper for this Context.
++     *
++     * @param mapper The new mapper
++     */
++    public void setCharsetMapper(CharsetMapper mapper) {
++
++        CharsetMapper oldCharsetMapper = this.charsetMapper;
++        this.charsetMapper = mapper;
++        if( mapper != null )
++            this.charsetMapperClass= mapper.getClass().getName();
++        support.firePropertyChange("charsetMapper", oldCharsetMapper,
++                                   this.charsetMapper);
++
++    }
++
++    /**
++     * Return the path to a file to save this Context information.
++     */
++    public String getConfigFile() {
++
++        return (this.configFile);
++
++    }
++
++
++    /**
++     * Set the path to a file to save this Context information.
++     *
++     * @param configFile The path to a file to save this Context information.
++     */
++    public void setConfigFile(String configFile) {
++
++        this.configFile = configFile;
++    }
++
++
++    /**
++     * Return the "correctly configured" flag for this Context.
++     */
++    public boolean getConfigured() {
++
++        return (this.configured);
++
++    }
++
++
++    /**
++     * Set the "correctly configured" flag for this Context.  This can be
++     * set to false by startup listeners that detect a fatal configuration
++     * error to avoid the application from being made available.
++     *
++     * @param configured The new correctly configured flag
++     */
++    public void setConfigured(boolean configured) {
++
++        boolean oldConfigured = this.configured;
++        this.configured = configured;
++        support.firePropertyChange("configured",
++                                   new Boolean(oldConfigured),
++                                   new Boolean(this.configured));
++
++    }
++
++
++    /**
++     * Return the "use cookies for session ids" flag.
++     */
++    public boolean getCookies() {
++
++        return (this.cookies);
++
++    }
++
++
++    /**
++     * Set the "use cookies for session ids" flag.
++     *
++     * @param cookies The new flag
++     */
++    public void setCookies(boolean cookies) {
++
++        boolean oldCookies = this.cookies;
++        this.cookies = cookies;
++        support.firePropertyChange("cookies",
++                                   new Boolean(oldCookies),
++                                   new Boolean(this.cookies));
++
++    }
++
++
++    /**
++     * Return the "allow crossing servlet contexts" flag.
++     */
++    public boolean getCrossContext() {
++
++        return (this.crossContext);
++
++    }
++
++
++    /**
++     * Set the "allow crossing servlet contexts" flag.
++     *
++     * @param crossContext The new cross contexts flag
++     */
++    public void setCrossContext(boolean crossContext) {
++
++        boolean oldCrossContext = this.crossContext;
++        this.crossContext = crossContext;
++        support.firePropertyChange("crossContext",
++                                   new Boolean(oldCrossContext),
++                                   new Boolean(this.crossContext));
++
++    }
++
++    public String getDefaultContextXml() {
++        return defaultContextXml;
++    }
++
++    /** 
++     * Set the location of the default context xml that will be used.
++     * If not absolute, it'll be made relative to the engine's base dir
++     * ( which defaults to catalina.base system property ).
++     *
++     * @param defaultContextXml The default web xml 
++     */
++    public void setDefaultContextXml(String defaultContextXml) {
++        this.defaultContextXml = defaultContextXml;
++    }
++
++    public String getDefaultWebXml() {
++        return defaultWebXml;
++    }
++
++    /** 
++     * Set the location of the default web xml that will be used.
++     * If not absolute, it'll be made relative to the engine's base dir
++     * ( which defaults to catalina.base system property ).
++     *
++     * @param defaultWebXml The default web xml 
++     */
++    public void setDefaultWebXml(String defaultWebXml) {
++        this.defaultWebXml = defaultWebXml;
++    }
++
++    /**
++     * Gets the time (in milliseconds) it took to start this context.
++     *
++     * @return Time (in milliseconds) it took to start this context.
++     */
++    public long getStartupTime() {
++        return startupTime;
++    }
++
++    public void setStartupTime(long startupTime) {
++        this.startupTime = startupTime;
++    }
++
++    public long getTldScanTime() {
++        return tldScanTime;
++    }
++
++    public void setTldScanTime(long tldScanTime) {
++        this.tldScanTime = tldScanTime;
++    }
++
++    /**
++     * Return the display name of this web application.
++     */
++    public String getDisplayName() {
++
++        return (this.displayName);
++
++    }
++
++
++    /**
++     * Return the alternate Deployment Descriptor name.
++     */
++    public String getAltDDName(){
++        return altDDName;
++    }
++
++
++    /**
++     * Set an alternate Deployment Descriptor name.
++     */
++    public void setAltDDName(String altDDName) {
++        this.altDDName = altDDName;
++        if (context != null) {
++            context.setAttribute(Globals.ALT_DD_ATTR,altDDName);
++        }
++    }
++
++
++    /**
++     * Return the compiler classpath.
++     */
++    public String getCompilerClasspath(){
++        return compilerClasspath;
++    }
++
++
++    /**
++     * Set the compiler classpath.
++     */
++    public void setCompilerClasspath(String compilerClasspath) {
++        this.compilerClasspath = compilerClasspath;
++    }
++
++
++    /**
++     * Set the display name of this web application.
++     *
++     * @param displayName The new display name
++     */
++    public void setDisplayName(String displayName) {
++
++        String oldDisplayName = this.displayName;
++        this.displayName = displayName;
++        support.firePropertyChange("displayName", oldDisplayName,
++                                   this.displayName);
++    }
++
++
++    /**
++     * Return the distributable flag for this web application.
++     */
++    public boolean getDistributable() {
++
++        return (this.distributable);
++
++    }
++
++    /**
++     * Set the distributable flag for this web application.
++     *
++     * @param distributable The new distributable flag
++     */
++    public void setDistributable(boolean distributable) {
++        boolean oldDistributable = this.distributable;
++        this.distributable = distributable;
++        support.firePropertyChange("distributable",
++                                   new Boolean(oldDistributable),
++                                   new Boolean(this.distributable));
++
++        // Bugzilla 32866
++        if(getManager() != null) {
++            if(log.isDebugEnabled()) {
++                log.debug("Propagating distributable=" + distributable
++                          + " to manager");
++            }
++            getManager().setDistributable(distributable);
++        }
++    }
++
++
++    /**
++     * Return the document root for this Context.  This can be an absolute
++     * pathname, a relative pathname, or a URL.
++     */
++    public String getDocBase() {
++
++        return (this.docBase);
++
++    }
++
++
++    /**
++     * Set the document root for this Context.  This can be an absolute
++     * pathname, a relative pathname, or a URL.
++     *
++     * @param docBase The new document root
++     */
++    public void setDocBase(String docBase) {
++
++        this.docBase = docBase;
++
++    }
++
++    // experimental
++    public boolean isLazy() {
++        return lazy;
++    }
++
++    public void setLazy(boolean lazy) {
++        this.lazy = lazy;
++    }
++
++
++    /**
++     * Return descriptive information about this Container implementation and
++     * the corresponding version number, in the format
++     * <code>&lt;description&gt;/&lt;version&gt;</code>.
++     */
++    public String getInfo() {
++
++        return (info);
++
++    }
++
++    public String getEngineName() {
++        if( engineName != null ) return engineName;
++        return domain;
++    }
++
++    public void setEngineName(String engineName) {
++        this.engineName = engineName;
++    }
++
++    public String getJ2EEApplication() {
++        return j2EEApplication;
++    }
++
++    public void setJ2EEApplication(String j2EEApplication) {
++        this.j2EEApplication = j2EEApplication;
++    }
++
++    public String getJ2EEServer() {
++        return j2EEServer;
++    }
++
++    public void setJ2EEServer(String j2EEServer) {
++        this.j2EEServer = j2EEServer;
++    }
++
++
++    /**
++     * Set the Loader with which this Context is associated.
++     *
++     * @param loader The newly associated loader
++     */
++    public synchronized void setLoader(Loader loader) {
++
++        super.setLoader(loader);
++
++    }
++
++
++    /**
++     * Return the login configuration descriptor for this web application.
++     */
++    public LoginConfig getLoginConfig() {
++
++        return (this.loginConfig);
++
++    }
++
++
++    /**
++     * Set the login configuration descriptor for this web application.
++     *
++     * @param config The new login configuration
++     */
++    public void setLoginConfig(LoginConfig config) {
++
++        // Validate the incoming property value
++        if (config == null)
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.loginConfig.required"));
++        String loginPage = config.getLoginPage();
++        if ((loginPage != null) && !loginPage.startsWith("/")) {
++            if (isServlet22()) {
++                if(log.isDebugEnabled())
++                    log.debug(sm.getString("standardContext.loginConfig.loginWarning",
++                                 loginPage));
++                config.setLoginPage("/" + loginPage);
++            } else {
++                throw new IllegalArgumentException
++                    (sm.getString("standardContext.loginConfig.loginPage",
++                                  loginPage));
++            }
++        }
++        String errorPage = config.getErrorPage();
++        if ((errorPage != null) && !errorPage.startsWith("/")) {
++            if (isServlet22()) {
++                if(log.isDebugEnabled())
++                    log.debug(sm.getString("standardContext.loginConfig.errorWarning",
++                                 errorPage));
++                config.setErrorPage("/" + errorPage);
++            } else {
++                throw new IllegalArgumentException
++                    (sm.getString("standardContext.loginConfig.errorPage",
++                                  errorPage));
++            }
++        }
++
++        // Process the property setting change
++        LoginConfig oldLoginConfig = this.loginConfig;
++        this.loginConfig = config;
++        support.firePropertyChange("loginConfig",
++                                   oldLoginConfig, this.loginConfig);
++
++    }
++
++
++    /**
++     * Get the mapper associated with the context.
++     */
++    public org.apache.tomcat.util.http.mapper.Mapper getMapper() {
++        return (mapper);
++    }
++
++
++    /**
++     * Return the naming resources associated with this web application.
++     */
++    public NamingResources getNamingResources() {
++
++        if (namingResources == null) {
++            setNamingResources(new NamingResources());
++        }
++        return (namingResources);
++
++    }
++
++
++    /**
++     * Set the naming resources for this web application.
++     *
++     * @param namingResources The new naming resources
++     */
++    public void setNamingResources(NamingResources namingResources) {
++
++        // Process the property setting change
++        NamingResources oldNamingResources = this.namingResources;
++        this.namingResources = namingResources;
++        namingResources.setContainer(this);
++        support.firePropertyChange("namingResources",
++                                   oldNamingResources, this.namingResources);
++
++    }
++
++
++    /**
++     * Return the context path for this Context.
++     */
++    public String getPath() {
++
++        return (getName());
++
++    }
++
++    
++    /**
++     * Set the context path for this Context.
++     * <p>
++     * <b>IMPLEMENTATION NOTE</b>:  The context path is used as the "name" of
++     * a Context, because it must be unique.
++     *
++     * @param path The new context path
++     */
++    public void setPath(String path) {
++        // XXX Use host in name
++        setName(RequestUtil.URLDecode(path));
++
++    }
++
++
++    /**
++     * Return the public identifier of the deployment descriptor DTD that is
++     * currently being parsed.
++     */
++    public String getPublicId() {
++
++        return (this.publicId);
++
++    }
++
++
++    /**
++     * Set the public identifier of the deployment descriptor DTD that is
++     * currently being parsed.
++     *
++     * @param publicId The public identifier
++     */
++    public void setPublicId(String publicId) {
++
++        if (log.isDebugEnabled())
++            log.debug("Setting deployment descriptor public ID to '" +
++                publicId + "'");
++
++        String oldPublicId = this.publicId;
++        this.publicId = publicId;
++        support.firePropertyChange("publicId", oldPublicId, publicId);
++
++    }
++
++
++    /**
++     * Return the reloadable flag for this web application.
++     */
++    public boolean getReloadable() {
++
++        return (this.reloadable);
++
++    }
++
++
++    /**
++     * Return the DefaultContext override flag for this web application.
++     */
++    public boolean getOverride() {
++
++        return (this.override);
++
++    }
++
++
++    /**
++     * Return the privileged flag for this web application.
++     */
++    public boolean getPrivileged() {
++
++        return (this.privileged);
++
++    }
++
++
++    /**
++     * Set the privileged flag for this web application.
++     *
++     * @param privileged The new privileged flag
++     */
++    public void setPrivileged(boolean privileged) {
++
++        boolean oldPrivileged = this.privileged;
++        this.privileged = privileged;
++        support.firePropertyChange("privileged",
++                                   new Boolean(oldPrivileged),
++                                   new Boolean(this.privileged));
++
++    }
++
++
++    /**
++     * Set the reloadable flag for this web application.
++     *
++     * @param reloadable The new reloadable flag
++     */
++    public void setReloadable(boolean reloadable) {
++
++        boolean oldReloadable = this.reloadable;
++        this.reloadable = reloadable;
++        support.firePropertyChange("reloadable",
++                                   new Boolean(oldReloadable),
++                                   new Boolean(this.reloadable));
++
++    }
++
++
++    /**
++     * Set the DefaultContext override flag for this web application.
++     *
++     * @param override The new override flag
++     */
++    public void setOverride(boolean override) {
++
++        boolean oldOverride = this.override;
++        this.override = override;
++        support.firePropertyChange("override",
++                                   new Boolean(oldOverride),
++                                   new Boolean(this.override));
++
++    }
++
++
++    /**
++     * Return the "replace welcome files" property.
++     */
++    public boolean isReplaceWelcomeFiles() {
++
++        return (this.replaceWelcomeFiles);
++
++    }
++
++
++    /**
++     * Set the "replace welcome files" property.
++     *
++     * @param replaceWelcomeFiles The new property value
++     */
++    public void setReplaceWelcomeFiles(boolean replaceWelcomeFiles) {
++
++        boolean oldReplaceWelcomeFiles = this.replaceWelcomeFiles;
++        this.replaceWelcomeFiles = replaceWelcomeFiles;
++        support.firePropertyChange("replaceWelcomeFiles",
++                                   new Boolean(oldReplaceWelcomeFiles),
++                                   new Boolean(this.replaceWelcomeFiles));
++
++    }
++
++
++    /**
++     * Return the servlet context for which this Context is a facade.
++     */
++    public ServletContext getServletContext() {
++
++        if (context == null) {
++            context = new ApplicationContext(getBasePath(), this);
++            if (altDDName != null)
++                context.setAttribute(Globals.ALT_DD_ATTR,altDDName);
++        }
++        return (context.getFacade());
++
++    }
++
++
++    /**
++     * Return the default session timeout (in minutes) for this
++     * web application.
++     */
++    public int getSessionTimeout() {
++
++        return (this.sessionTimeout);
++
++    }
++
++
++    /**
++     * Set the default session timeout (in minutes) for this
++     * web application.
++     *
++     * @param timeout The new default session timeout
++     */
++    public void setSessionTimeout(int timeout) {
++
++        int oldSessionTimeout = this.sessionTimeout;
++        /*
++         * SRV.13.4 ("Deployment Descriptor"):
++         * If the timeout is 0 or less, the container ensures the default
++         * behaviour of sessions is never to time out.
++         */
++        this.sessionTimeout = (timeout == 0) ? -1 : timeout;
++        support.firePropertyChange("sessionTimeout",
++                                   new Integer(oldSessionTimeout),
++                                   new Integer(this.sessionTimeout));
++
++    }
++
++
++    /**
++     * Return the value of the swallowOutput flag.
++     */
++    public boolean getSwallowOutput() {
++
++        return (this.swallowOutput);
++
++    }
++
++
++    /**
++     * Set the value of the swallowOutput flag. If set to true, the system.out
++     * and system.err will be redirected to the logger during a servlet
++     * execution.
++     *
++     * @param swallowOutput The new value
++     */
++    public void setSwallowOutput(boolean swallowOutput) {
++
++        boolean oldSwallowOutput = this.swallowOutput;
++        this.swallowOutput = swallowOutput;
++        support.firePropertyChange("swallowOutput",
++                                   new Boolean(oldSwallowOutput),
++                                   new Boolean(this.swallowOutput));
++
++    }
++
++
++    /**
++     * Unpack WAR flag accessor.
++     */
++    public boolean getUnpackWAR() {
++
++        return (unpackWAR);
++
++    }
++
++
++    /**
++     * Unpack WAR flag mutator.
++     */
++    public void setUnpackWAR(boolean unpackWAR) {
++
++        this.unpackWAR = unpackWAR;
++
++    }
++
++    /**
++     * Return the Java class name of the Wrapper implementation used
++     * for servlets registered in this Context.
++     */
++    public String getWrapperClass() {
++
++        return (this.wrapperClassName);
++
++    }
++
++
++    /**
++     * Set the Java class name of the Wrapper implementation used
++     * for servlets registered in this Context.
++     *
++     * @param wrapperClassName The new wrapper class name
++     *
++     * @throws IllegalArgumentException if the specified wrapper class
++     * cannot be found or is not a subclass of StandardWrapper
++     */
++    public void setWrapperClass(String wrapperClassName) {
++
++        this.wrapperClassName = wrapperClassName;
++
++        try {
++            wrapperClass = Class.forName(wrapperClassName);         
++            if (!StandardWrapper.class.isAssignableFrom(wrapperClass)) {
++                throw new IllegalArgumentException(
++                    sm.getString("standardContext.invalidWrapperClass",
++                                 wrapperClassName));
++            }
++        } catch (ClassNotFoundException cnfe) {
++            throw new IllegalArgumentException(cnfe.getMessage());
++        }
++    }
++
++
++    /**
++     * Set the resources DirContext object with which this Container is
++     * associated.
++     *
++     * @param resources The newly associated DirContext
++     */
++    public synchronized void setResources(DirContext resources) {
++
++        if (started) {
++            throw new IllegalStateException
++                (sm.getString("standardContext.resources.started"));
++        }
++
++        DirContext oldResources = this.webappResources;
++        if (oldResources == resources)
++            return;
++
++        if (resources instanceof BaseDirContext) {
++            ((BaseDirContext) resources).setCached(isCachingAllowed());
++            ((BaseDirContext) resources).setCacheTTL(getCacheTTL());
++            ((BaseDirContext) resources).setCacheMaxSize(getCacheMaxSize());
++        }
++        if (resources instanceof FileDirContext) {
++            filesystemBased = true;
++            ((FileDirContext) resources).setCaseSensitive(isCaseSensitive());
++            ((FileDirContext) resources).setAllowLinking(isAllowLinking());
++        }
++        this.webappResources = resources;
++
++        // The proxied resources will be refreshed on start
++        this.resources = null;
++
++        support.firePropertyChange("resources", oldResources,
++                                   this.webappResources);
++
++    }
++
++
++    // ------------------------------------------------------ Public Properties
++
++
++    /**
++     * Return the Locale to character set mapper class for this Context.
++     */
++    public String getCharsetMapperClass() {
++
++        return (this.charsetMapperClass);
++
++    }
++
++
++    /**
++     * Set the Locale to character set mapper class for this Context.
++     *
++     * @param mapper The new mapper class
++     */
++    public void setCharsetMapperClass(String mapper) {
++
++        String oldCharsetMapperClass = this.charsetMapperClass;
++        this.charsetMapperClass = mapper;
++        support.firePropertyChange("charsetMapperClass",
++                                   oldCharsetMapperClass,
++                                   this.charsetMapperClass);
++
++    }
++
++
++    /** Get the absolute path to the work dir.
++     *  To avoid duplication.
++     * 
++     * @return The work path
++     */ 
++    public String getWorkPath() {
++        File workDir = new File(getWorkDir());
++        if (!workDir.isAbsolute()) {
++            File catalinaHome = engineBase();
++            String catalinaHomePath = null;
++            try {
++                catalinaHomePath = catalinaHome.getCanonicalPath();
++                workDir = new File(catalinaHomePath,
++                        getWorkDir());
++            } catch (IOException e) {
++                log.warn("Exception obtaining work path for " + getPath());
++            }
++        }
++        return workDir.getAbsolutePath();
++    }
++    
++    /**
++     * Return the work directory for this Context.
++     */
++    public String getWorkDir() {
++
++        return (this.workDir);
++
++    }
++
++
++    /**
++     * Set the work directory for this Context.
++     *
++     * @param workDir The new work directory
++     */
++    public void setWorkDir(String workDir) {
++
++        this.workDir = workDir;
++
++        if (started) {
++            postWorkDirectory();
++        }
++    }
++
++
++    /**
++     * Save config ?
++     */
++    public boolean isSaveConfig() {
++        return saveConfig;
++    }
++
++
++    /**
++     * Set save config flag.
++     */
++    public void setSaveConfig(boolean saveConfig) {
++        this.saveConfig = saveConfig;
++    }
++
++
++    // -------------------------------------------------------- Context Methods
++
++
++    /**
++     * Add a new Listener class name to the set of Listeners
++     * configured for this application.
++     *
++     * @param listener Java class name of a listener class
++     */
++    public void addApplicationListener(String listener) {
++
++        synchronized (applicationListeners) {
++            String results[] =new String[applicationListeners.length + 1];
++            for (int i = 0; i < applicationListeners.length; i++) {
++                if (listener.equals(applicationListeners[i]))
++                    return;
++                results[i] = applicationListeners[i];
++            }
++            results[applicationListeners.length] = listener;
++            applicationListeners = results;
++        }
++        fireContainerEvent("addApplicationListener", listener);
++
++        // FIXME - add instance if already started?
++
++    }
++
++
++    /**
++     * Add a new application parameter for this application.
++     *
++     * @param parameter The new application parameter
++     */
++    public void addApplicationParameter(ApplicationParameter parameter) {
++
++        synchronized (applicationParameters) {
++            String newName = parameter.getName();
++            for (int i = 0; i < applicationParameters.length; i++) {
++                if (newName.equals(applicationParameters[i].getName()) &&
++                    !applicationParameters[i].getOverride())
++                    return;
++            }
++            ApplicationParameter results[] =
++                new ApplicationParameter[applicationParameters.length + 1];
++            System.arraycopy(applicationParameters, 0, results, 0,
++                             applicationParameters.length);
++            results[applicationParameters.length] = parameter;
++            applicationParameters = results;
++        }
++        fireContainerEvent("addApplicationParameter", parameter);
++
++    }
++
++
++    /**
++     * Add a child Container, only if the proposed child is an implementation
++     * of Wrapper.
++     *
++     * @param child Child container to be added
++     *
++     * @exception IllegalArgumentException if the proposed container is
++     *  not an implementation of Wrapper
++     */
++    public void addChild(Container child) {
++
++        // Global JspServlet
++        Wrapper oldJspServlet = null;
++
++        if (!(child instanceof Wrapper)) {
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.notWrapper"));
++        }
++
++        Wrapper wrapper = (Wrapper) child;
++        boolean isJspServlet = "jsp".equals(child.getName());
++
++        // Allow webapp to override JspServlet inherited from global web.xml.
++        if (isJspServlet) {
++            oldJspServlet = (Wrapper) findChild("jsp");
++            if (oldJspServlet != null) {
++                removeChild(oldJspServlet);
++            }
++        }
++
++        String jspFile = wrapper.getJspFile();
++        if ((jspFile != null) && !jspFile.startsWith("/")) {
++            if (isServlet22()) {
++                if(log.isDebugEnabled())
++                    log.debug(sm.getString("standardContext.wrapper.warning", 
++                                       jspFile));
++                wrapper.setJspFile("/" + jspFile);
++            } else {
++                throw new IllegalArgumentException
++                    (sm.getString("standardContext.wrapper.error", jspFile));
++            }
++        }
++
++        super.addChild(child);
++
++        if (isJspServlet && oldJspServlet != null) {
++            /*
++             * The webapp-specific JspServlet inherits all the mappings
++             * specified in the global web.xml, and may add additional ones.
++             */
++            String[] jspMappings = oldJspServlet.findMappings();
++            for (int i=0; jspMappings!=null && i<jspMappings.length; i++) {
++                addServletMapping(jspMappings[i], child.getName());
++            }
++        }
++    }
++
++
++    /**
++     * Add a security constraint to the set for this web application.
++     */
++    public void addConstraint(SecurityConstraint constraint) {
++
++        // Validate the proposed constraint
++        SecurityCollection collections[] = constraint.findCollections();
++        for (int i = 0; i < collections.length; i++) {
++            String patterns[] = collections[i].findPatterns();
++            for (int j = 0; j < patterns.length; j++) {
++                patterns[j] = adjustURLPattern(patterns[j]);
++                if (!validateURLPattern(patterns[j]))
++                    throw new IllegalArgumentException
++                        (sm.getString
++                         ("standardContext.securityConstraint.pattern",
++                          patterns[j]));
++            }
++        }
++
++        // Add this constraint to the set for our web application
++        synchronized (constraints) {
++            SecurityConstraint results[] =
++                new SecurityConstraint[constraints.length + 1];
++            for (int i = 0; i < constraints.length; i++)
++                results[i] = constraints[i];
++            results[constraints.length] = constraint;
++            constraints = results;
++        }
++
++    }
++
++
++
++    /**
++     * Add an error page for the specified error or Java exception.
++     *
++     * @param errorPage The error page definition to be added
++     */
++    public void addErrorPage(ErrorPage errorPage) {
++        // Validate the input parameters
++        if (errorPage == null)
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.errorPage.required"));
++        String location = errorPage.getLocation();
++        if ((location != null) && !location.startsWith("/")) {
++            if (isServlet22()) {
++                if(log.isDebugEnabled())
++                    log.debug(sm.getString("standardContext.errorPage.warning",
++                                 location));
++                errorPage.setLocation("/" + location);
++            } else {
++                throw new IllegalArgumentException
++                    (sm.getString("standardContext.errorPage.error",
++                                  location));
++            }
++        }
++
++        // Add the specified error page to our internal collections
++        String exceptionType = errorPage.getExceptionType();
++        if (exceptionType != null) {
++            synchronized (exceptionPages) {
++                exceptionPages.put(exceptionType, errorPage);
++            }
++        } else {
++            synchronized (statusPages) {
++                if (errorPage.getErrorCode() == 200) {
++                    this.okErrorPage = errorPage;
++                }
++                statusPages.put(new Integer(errorPage.getErrorCode()),
++                                errorPage);
++            }
++        }
++        fireContainerEvent("addErrorPage", errorPage);
++
++    }
++
++
++    /**
++     * Add a filter definition to this Context.
++     *
++     * @param filterDef The filter definition to be added
++     */
++    public void addFilterDef(FilterDef filterDef) {
++
++        synchronized (filterDefs) {
++            filterDefs.put(filterDef.getFilterName(), filterDef);
++        }
++        fireContainerEvent("addFilterDef", filterDef);
++
++    }
++
++
++    /**
++     * Add a filter mapping to this Context.
++     *
++     * @param filterMap The filter mapping to be added
++     *
++     * @exception IllegalArgumentException if the specified filter name
++     *  does not match an existing filter definition, or the filter mapping
++     *  is malformed
++     */
++    public void addFilterMap(FilterMap filterMap) {
++
++        // Validate the proposed filter mapping
++        String filterName = filterMap.getFilterName();
++        String servletName = filterMap.getServletName();
++        String urlPattern = filterMap.getURLPattern();
++        if (findFilterDef(filterName) == null)
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.filterMap.name", filterName));
++        if ((servletName == null) && (urlPattern == null))
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.filterMap.either"));
++        if ((servletName != null) && (urlPattern != null))
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.filterMap.either"));
++        // Because filter-pattern is new in 2.3, no need to adjust
++        // for 2.2 backwards compatibility
++        if ((urlPattern != null) && !validateURLPattern(urlPattern))
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.filterMap.pattern",
++                              urlPattern));
++
++        // Add this filter mapping to our registered set
++        synchronized (filterMaps) {
++            FilterMap results[] =new FilterMap[filterMaps.length + 1];
++            System.arraycopy(filterMaps, 0, results, 0, filterMaps.length);
++            results[filterMaps.length] = filterMap;
++            filterMaps = results;
++        }
++        fireContainerEvent("addFilterMap", filterMap);
++
++    }
++
++
++    /**
++     * Add the classname of an InstanceListener to be added to each
++     * Wrapper appended to this Context.
++     *
++     * @param listener Java class name of an InstanceListener class
++     */
++    public void addInstanceListener(String listener) {
++
++        synchronized (instanceListeners) {
++            String results[] =new String[instanceListeners.length + 1];
++            for (int i = 0; i < instanceListeners.length; i++)
++                results[i] = instanceListeners[i];
++            results[instanceListeners.length] = listener;
++            instanceListeners = results;
++        }
++        fireContainerEvent("addInstanceListener", listener);
++
++    }
++
++    /**
++     * Add the given URL pattern as a jsp-property-group.  This maps
++     * resources that match the given pattern so they will be passed
++     * to the JSP container.  Though there are other elements in the
++     * property group, we only care about the URL pattern here.  The
++     * JSP container will parse the rest.
++     *
++     * @param pattern URL pattern to be mapped
++     */
++    public void addJspMapping(String pattern) {
++        String servletName = findServletMapping("*.jsp");
++        if (servletName == null) {
++            servletName = "jsp";
++        }
++
++        if( findChild(servletName) != null) {
++            addServletMapping(pattern, servletName, true);
++        } else {
++            if(log.isDebugEnabled())
++                log.debug("Skiping " + pattern + " , no servlet " + servletName);
++        }
++    }
++
++
++    /**
++     * Add a Locale Encoding Mapping (see Sec 5.4 of Servlet spec 2.4)
++     *
++     * @param locale locale to map an encoding for
++     * @param encoding encoding to be used for a give locale
++     */
++    public void addLocaleEncodingMappingParameter(String locale, String encoding){
++        getCharsetMapper().addCharsetMappingFromDeploymentDescriptor(locale, encoding);
++    }
++
++
++    /**
++     * Add a message destination for this web application.
++     *
++     * @param md New message destination
++     */
++    public void addMessageDestination(MessageDestination md) {
++
++        synchronized (messageDestinations) {
++            messageDestinations.put(md.getName(), md);
++        }
++        fireContainerEvent("addMessageDestination", md.getName());
++
++    }
++
++
++    /**
++     * Add a message destination reference for this web application.
++     *
++     * @param mdr New message destination reference
++     */
++    public void addMessageDestinationRef
++        (MessageDestinationRef mdr) {
++
++        namingResources.addMessageDestinationRef(mdr);
++        fireContainerEvent("addMessageDestinationRef", mdr.getName());
++
++    }
++
++
++    /**
++     * Add a new MIME mapping, replacing any existing mapping for
++     * the specified extension.
++     *
++     * @param extension Filename extension being mapped
++     * @param mimeType Corresponding MIME type
++     */
++    public void addMimeMapping(String extension, String mimeType) {
++
++        synchronized (mimeMappings) {
++            mimeMappings.put(extension, mimeType);
++        }
++        fireContainerEvent("addMimeMapping", extension);
++
++    }
++
++
++    /**
++     * Add a new context initialization parameter.
++     *
++     * @param name Name of the new parameter
++     * @param value Value of the new  parameter
++     *
++     * @exception IllegalArgumentException if the name or value is missing,
++     *  or if this context initialization parameter has already been
++     *  registered
++     */
++    public void addParameter(String name, String value) {
++        // Validate the proposed context initialization parameter
++        if ((name == null) || (value == null))
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.parameter.required"));
++        if (parameters.get(name) != null)
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.parameter.duplicate", name));
++
++        // Add this parameter to our defined set
++        synchronized (parameters) {
++            parameters.put(name, value);
++        }
++        fireContainerEvent("addParameter", name);
++
++    }
++
++
++    /**
++     * Add a security role reference for this web application.
++     *
++     * @param role Security role used in the application
++     * @param link Actual security role to check for
++     */
++    public void addRoleMapping(String role, String link) {
++
++        synchronized (roleMappings) {
++            roleMappings.put(role, link);
++        }
++        fireContainerEvent("addRoleMapping", role);
++
++    }
++
++
++    /**
++     * Add a new security role for this web application.
++     *
++     * @param role New security role
++     */
++    public void addSecurityRole(String role) {
++
++        synchronized (securityRoles) {
++            String results[] =new String[securityRoles.length + 1];
++            for (int i = 0; i < securityRoles.length; i++)
++                results[i] = securityRoles[i];
++            results[securityRoles.length] = role;
++            securityRoles = results;
++        }
++        fireContainerEvent("addSecurityRole", role);
++
++    }
++
++
++    /**
++     * Add a new servlet mapping, replacing any existing mapping for
++     * the specified pattern.
++     *
++     * @param pattern URL pattern to be mapped
++     * @param name Name of the corresponding servlet to execute
++     *
++     * @exception IllegalArgumentException if the specified servlet name
++     *  is not known to this Context
++     */
++    public void addServletMapping(String pattern, String name) {
++        addServletMapping(pattern, name, false);
++    }
++
++
++    /**
++     * Add a new servlet mapping, replacing any existing mapping for
++     * the specified pattern.
++     *
++     * @param pattern URL pattern to be mapped
++     * @param name Name of the corresponding servlet to execute
++     * @param jspWildCard true if name identifies the JspServlet
++     * and pattern contains a wildcard; false otherwise
++     *
++     * @exception IllegalArgumentException if the specified servlet name
++     *  is not known to this Context
++     */
++    public void addServletMapping(String pattern, String name,
++                                  boolean jspWildCard) {
++        // Validate the proposed mapping
++        if (findChild(name) == null)
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.servletMap.name", name));
++        pattern = adjustURLPattern(RequestUtil.URLDecode(pattern));
++        if (!validateURLPattern(pattern))
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.servletMap.pattern", pattern));
++
++        // Add this mapping to our registered set
++        synchronized (servletMappings) {
++            String name2 = (String) servletMappings.get(pattern);
++            if (name2 != null) {
++                // Don't allow more than one servlet on the same pattern
++                Wrapper wrapper = (Wrapper) findChild(name2);
++                wrapper.removeMapping(pattern);
++                mapper.removeWrapper(pattern);
++            }
++            servletMappings.put(pattern, name);
++        }
++        Wrapper wrapper = (Wrapper) findChild(name);
++        wrapper.addMapping(pattern);
++
++        // Update context mapper
++        mapper.addWrapper(pattern, wrapper, jspWildCard);
++
++        fireContainerEvent("addServletMapping", pattern);
++
++    }
++
++
++    /**
++     * Add a JSP tag library for the specified URI.
++     *
++     * @param uri URI, relative to the web.xml file, of this tag library
++     * @param location Location of the tag library descriptor
++     */
++    public void addTaglib(String uri, String location) {
++
++        synchronized (taglibs) {
++            taglibs.put(uri, location);
++        }
++        fireContainerEvent("addTaglib", uri);
++
++    }
++
++
++    /**
++     * Add a new watched resource to the set recognized by this Context.
++     *
++     * @param name New watched resource file name
++     */
++    public void addWatchedResource(String name) {
++
++        synchronized (watchedResources) {
++            String results[] = new String[watchedResources.length + 1];
++            for (int i = 0; i < watchedResources.length; i++)
++                results[i] = watchedResources[i];
++            results[watchedResources.length] = name;
++            watchedResources = results;
++        }
++        fireContainerEvent("addWatchedResource", name);
++
++    }
++
++
++    /**
++     * Add a new welcome file to the set recognized by this Context.
++     *
++     * @param name New welcome file name
++     */
++    public void addWelcomeFile(String name) {
++
++        synchronized (welcomeFiles) {
++            // Welcome files from the application deployment descriptor
++            // completely replace those from the default conf/web.xml file
++            if (replaceWelcomeFiles) {
++                welcomeFiles = new String[0];
++                setReplaceWelcomeFiles(false);
++            }
++            String results[] =new String[welcomeFiles.length + 1];
++            for (int i = 0; i < welcomeFiles.length; i++)
++                results[i] = welcomeFiles[i];
++            results[welcomeFiles.length] = name;
++            welcomeFiles = results;
++        }
++        postWelcomeFiles();
++        fireContainerEvent("addWelcomeFile", name);
++
++    }
++
++
++    /**
++     * Add the classname of a LifecycleListener to be added to each
++     * Wrapper appended to this Context.
++     *
++     * @param listener Java class name of a LifecycleListener class
++     */
++    public void addWrapperLifecycle(String listener) {
++
++        synchronized (wrapperLifecycles) {
++            String results[] =new String[wrapperLifecycles.length + 1];
++            for (int i = 0; i < wrapperLifecycles.length; i++)
++                results[i] = wrapperLifecycles[i];
++            results[wrapperLifecycles.length] = listener;
++            wrapperLifecycles = results;
++        }
++        fireContainerEvent("addWrapperLifecycle", listener);
++
++    }
++
++
++    /**
++     * Add the classname of a ContainerListener to be added to each
++     * Wrapper appended to this Context.
++     *
++     * @param listener Java class name of a ContainerListener class
++     */
++    public void addWrapperListener(String listener) {
++
++        synchronized (wrapperListeners) {
++            String results[] =new String[wrapperListeners.length + 1];
++            for (int i = 0; i < wrapperListeners.length; i++)
++                results[i] = wrapperListeners[i];
++            results[wrapperListeners.length] = listener;
++            wrapperListeners = results;
++        }
++        fireContainerEvent("addWrapperListener", listener);
++
++    }
++
++
++    /**
++     * Factory method to create and return a new Wrapper instance, of
++     * the Java implementation class appropriate for this Context
++     * implementation.  The constructor of the instantiated Wrapper
++     * will have been called, but no properties will have been set.
++     */
++    public Wrapper createWrapper() {
++
++        Wrapper wrapper = null;
++        if (wrapperClass != null) {
++            try {
++                wrapper = (Wrapper) wrapperClass.newInstance();
++            } catch (Throwable t) {
++                log.error("createWrapper", t);
++                return (null);
++            }
++        } else {
++            wrapper = new StandardWrapper();
++        }
++
++        synchronized (instanceListeners) {
++            for (int i = 0; i < instanceListeners.length; i++) {
++                try {
++                    Class clazz = Class.forName(instanceListeners[i]);
++                    InstanceListener listener =
++                      (InstanceListener) clazz.newInstance();
++                    wrapper.addInstanceListener(listener);
++                } catch (Throwable t) {
++                    log.error("createWrapper", t);
++                    return (null);
++                }
++            }
++        }
++
++        synchronized (wrapperLifecycles) {
++            for (int i = 0; i < wrapperLifecycles.length; i++) {
++                try {
++                    Class clazz = Class.forName(wrapperLifecycles[i]);
++                    LifecycleListener listener =
++                      (LifecycleListener) clazz.newInstance();
++                    if (wrapper instanceof Lifecycle)
++                        ((Lifecycle) wrapper).addLifecycleListener(listener);
++                } catch (Throwable t) {
++                    log.error("createWrapper", t);
++                    return (null);
++                }
++            }
++        }
++
++        synchronized (wrapperListeners) {
++            for (int i = 0; i < wrapperListeners.length; i++) {
++                try {
++                    Class clazz = Class.forName(wrapperListeners[i]);
++                    ContainerListener listener =
++                      (ContainerListener) clazz.newInstance();
++                    wrapper.addContainerListener(listener);
++                } catch (Throwable t) {
++                    log.error("createWrapper", t);
++                    return (null);
++                }
++            }
++        }
++
++        return (wrapper);
++
++    }
++
++
++    /**
++     * Return the set of application listener class names configured
++     * for this application.
++     */
++    public String[] findApplicationListeners() {
++
++        return (applicationListeners);
++
++    }
++
++
++    /**
++     * Return the set of application parameters for this application.
++     */
++    public ApplicationParameter[] findApplicationParameters() {
++
++        return (applicationParameters);
++
++    }
++
++
++    /**
++     * Return the security constraints for this web application.
++     * If there are none, a zero-length array is returned.
++     */
++    public SecurityConstraint[] findConstraints() {
++
++        return (constraints);
++
++    }
++
++
++    /**
++     * Return the error page entry for the specified HTTP error code,
++     * if any; otherwise return <code>null</code>.
++     *
++     * @param errorCode Error code to look up
++     */
++    public ErrorPage findErrorPage(int errorCode) {
++        if (errorCode == 200) {
++            return (okErrorPage);
++        } else {
++            return ((ErrorPage) statusPages.get(new Integer(errorCode)));
++        }
++
++    }
++
++
++    /**
++     * Return the error page entry for the specified Java exception type,
++     * if any; otherwise return <code>null</code>.
++     *
++     * @param exceptionType Exception type to look up
++     */
++    public ErrorPage findErrorPage(String exceptionType) {
++
++        synchronized (exceptionPages) {
++            return ((ErrorPage) exceptionPages.get(exceptionType));
++        }
++
++    }
++
++
++    /**
++     * Return the set of defined error pages for all specified error codes
++     * and exception types.
++     */
++    public ErrorPage[] findErrorPages() {
++
++        synchronized(exceptionPages) {
++            synchronized(statusPages) {
++                ErrorPage results1[] = new ErrorPage[exceptionPages.size()];
++                results1 =
++                    (ErrorPage[]) exceptionPages.values().toArray(results1);
++                ErrorPage results2[] = new ErrorPage[statusPages.size()];
++                results2 =
++                    (ErrorPage[]) statusPages.values().toArray(results2);
++                ErrorPage results[] =
++                    new ErrorPage[results1.length + results2.length];
++                for (int i = 0; i < results1.length; i++)
++                    results[i] = results1[i];
++                for (int i = results1.length; i < results.length; i++)
++                    results[i] = results2[i - results1.length];
++                return (results);
++            }
++        }
++
++    }
++
++
++    /**
++     * Return the filter definition for the specified filter name, if any;
++     * otherwise return <code>null</code>.
++     *
++     * @param filterName Filter name to look up
++     */
++    public FilterDef findFilterDef(String filterName) {
++
++        synchronized (filterDefs) {
++            return ((FilterDef) filterDefs.get(filterName));
++        }
++
++    }
++
++
++    /**
++     * Return the set of defined filters for this Context.
++     */
++    public FilterDef[] findFilterDefs() {
++
++        synchronized (filterDefs) {
++            FilterDef results[] = new FilterDef[filterDefs.size()];
++            return ((FilterDef[]) filterDefs.values().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * Return the set of filter mappings for this Context.
++     */
++    public FilterMap[] findFilterMaps() {
++
++        return (filterMaps);
++
++    }
++
++
++    /**
++     * Return the set of InstanceListener classes that will be added to
++     * newly created Wrappers automatically.
++     */
++    public String[] findInstanceListeners() {
++
++        return (instanceListeners);
++
++    }
++
++
++    /**
++     * FIXME: Fooling introspection ...
++     */
++    public Context findMappingObject() {
++        return (Context) getMappingObject();
++    }
++    
++    
++    /**
++     * Return the message destination with the specified name, if any;
++     * otherwise, return <code>null</code>.
++     *
++     * @param name Name of the desired message destination
++     */
++    public MessageDestination findMessageDestination(String name) {
++
++        synchronized (messageDestinations) {
++            return ((MessageDestination) messageDestinations.get(name));
++        }
++
++    }
++
++
++    /**
++     * Return the set of defined message destinations for this web
++     * application.  If none have been defined, a zero-length array
++     * is returned.
++     */
++    public MessageDestination[] findMessageDestinations() {
++
++        synchronized (messageDestinations) {
++            MessageDestination results[] =
++                new MessageDestination[messageDestinations.size()];
++            return ((MessageDestination[])
++                    messageDestinations.values().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * Return the message destination ref with the specified name, if any;
++     * otherwise, return <code>null</code>.
++     *
++     * @param name Name of the desired message destination ref
++     */
++    public MessageDestinationRef
++        findMessageDestinationRef(String name) {
++
++        return namingResources.findMessageDestinationRef(name);
++
++    }
++
++
++    /**
++     * Return the set of defined message destination refs for this web
++     * application.  If none have been defined, a zero-length array
++     * is returned.
++     */
++    public MessageDestinationRef[]
++        findMessageDestinationRefs() {
++
++        return namingResources.findMessageDestinationRefs();
++
++    }
++
++
++    /**
++     * Return the MIME type to which the specified extension is mapped,
++     * if any; otherwise return <code>null</code>.
++     *
++     * @param extension Extension to map to a MIME type
++     */
++    public String findMimeMapping(String extension) {
++
++        return ((String) mimeMappings.get(extension));
++
++    }
++
++
++    /**
++     * Return the extensions for which MIME mappings are defined.  If there
++     * are none, a zero-length array is returned.
++     */
++    public String[] findMimeMappings() {
++
++        synchronized (mimeMappings) {
++            String results[] = new String[mimeMappings.size()];
++            return
++                ((String[]) mimeMappings.keySet().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * Return the value for the specified context initialization
++     * parameter name, if any; otherwise return <code>null</code>.
++     *
++     * @param name Name of the parameter to return
++     */
++    public String findParameter(String name) {
++
++        synchronized (parameters) {
++            return ((String) parameters.get(name));
++        }
++
++    }
++
++
++    /**
++     * Return the names of all defined context initialization parameters
++     * for this Context.  If no parameters are defined, a zero-length
++     * array is returned.
++     */
++    public String[] findParameters() {
++
++        synchronized (parameters) {
++            String results[] = new String[parameters.size()];
++            return ((String[]) parameters.keySet().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * For the given security role (as used by an application), return the
++     * corresponding role name (as defined by the underlying Realm) if there
++     * is one.  Otherwise, return the specified role unchanged.
++     *
++     * @param role Security role to map
++     */
++    public String findRoleMapping(String role) {
++
++        String realRole = null;
++        synchronized (roleMappings) {
++            realRole = (String) roleMappings.get(role);
++        }
++        if (realRole != null)
++            return (realRole);
++        else
++            return (role);
++
++    }
++
++
++    /**
++     * Return <code>true</code> if the specified security role is defined
++     * for this application; otherwise return <code>false</code>.
++     *
++     * @param role Security role to verify
++     */
++    public boolean findSecurityRole(String role) {
++
++        synchronized (securityRoles) {
++            for (int i = 0; i < securityRoles.length; i++) {
++                if (role.equals(securityRoles[i]))
++                    return (true);
++            }
++        }
++        return (false);
++
++    }
++
++
++    /**
++     * Return the security roles defined for this application.  If none
++     * have been defined, a zero-length array is returned.
++     */
++    public String[] findSecurityRoles() {
++
++        return (securityRoles);
++
++    }
++
++
++    /**
++     * Return the servlet name mapped by the specified pattern (if any);
++     * otherwise return <code>null</code>.
++     *
++     * @param pattern Pattern for which a mapping is requested
++     */
++    public String findServletMapping(String pattern) {
++
++        synchronized (servletMappings) {
++            return ((String) servletMappings.get(pattern));
++        }
++
++    }
++
++
++    /**
++     * Return the patterns of all defined servlet mappings for this
++     * Context.  If no mappings are defined, a zero-length array is returned.
++     */
++    public String[] findServletMappings() {
++
++        synchronized (servletMappings) {
++            String results[] = new String[servletMappings.size()];
++            return
++               ((String[]) servletMappings.keySet().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * Return the context-relative URI of the error page for the specified
++     * HTTP status code, if any; otherwise return <code>null</code>.
++     *
++     * @param status HTTP status code to look up
++     */
++    public String findStatusPage(int status) {
++
++        return ((String) statusPages.get(new Integer(status)));
++
++    }
++
++
++    /**
++     * Return the set of HTTP status codes for which error pages have
++     * been specified.  If none are specified, a zero-length array
++     * is returned.
++     */
++    public int[] findStatusPages() {
++
++        synchronized (statusPages) {
++            int results[] = new int[statusPages.size()];
++            Iterator elements = statusPages.keySet().iterator();
++            int i = 0;
++            while (elements.hasNext())
++                results[i++] = ((Integer) elements.next()).intValue();
++            return (results);
++        }
++
++    }
++
++
++    /**
++     * Return the tag library descriptor location for the specified taglib
++     * URI, if any; otherwise, return <code>null</code>.
++     *
++     * @param uri URI, relative to the web.xml file
++     */
++    public String findTaglib(String uri) {
++
++        synchronized (taglibs) {
++            return ((String) taglibs.get(uri));
++        }
++
++    }
++
++
++    /**
++     * Return the URIs of all tag libraries for which a tag library
++     * descriptor location has been specified.  If none are specified,
++     * a zero-length array is returned.
++     */
++    public String[] findTaglibs() {
++
++        synchronized (taglibs) {
++            String results[] = new String[taglibs.size()];
++            return ((String[]) taglibs.keySet().toArray(results));
++        }
++
++    }
++
++
++    /**
++     * Return <code>true</code> if the specified welcome file is defined
++     * for this Context; otherwise return <code>false</code>.
++     *
++     * @param name Welcome file to verify
++     */
++    public boolean findWelcomeFile(String name) {
++
++        synchronized (welcomeFiles) {
++            for (int i = 0; i < welcomeFiles.length; i++) {
++                if (name.equals(welcomeFiles[i]))
++                    return (true);
++            }
++        }
++        return (false);
++
++    }
++
++
++    /**
++     * Return the set of watched resources for this Context. If none are 
++     * defined, a zero length array will be returned.
++     */
++    public String[] findWatchedResources() {
++        return watchedResources;
++    }
++    
++    
++    /**
++     * Return the set of welcome files defined for this Context.  If none are
++     * defined, a zero-length array is returned.
++     */
++    public String[] findWelcomeFiles() {
++
++        return (welcomeFiles);
++
++    }
++
++
++    /**
++     * Return the set of LifecycleListener classes that will be added to
++     * newly created Wrappers automatically.
++     */
++    public String[] findWrapperLifecycles() {
++
++        return (wrapperLifecycles);
++
++    }
++
++
++    /**
++     * Return the set of ContainerListener classes that will be added to
++     * newly created Wrappers automatically.
++     */
++    public String[] findWrapperListeners() {
++
++        return (wrapperListeners);
++
++    }
++
++
++    /**
++     * Reload this web application, if reloading is supported.
++     * <p>
++     * <b>IMPLEMENTATION NOTE</b>:  This method is designed to deal with
++     * reloads required by changes to classes in the underlying repositories
++     * of our class loader.  It does not handle changes to the web application
++     * deployment descriptor.  If that has occurred, you should stop this
++     * Context and create (and start) a new Context instance instead.
++     *
++     * @exception IllegalStateException if the <code>reloadable</code>
++     *  property is set to <code>false</code>.
++     */
++    public synchronized void reload() {
++
++        // Validate our current component state
++        if (!started)
++            throw new IllegalStateException
++                (sm.getString("containerBase.notStarted", logName()));
++
++        // Make sure reloading is enabled
++        //      if (!reloadable)
++        //          throw new IllegalStateException
++        //              (sm.getString("standardContext.notReloadable"));
++        if(log.isInfoEnabled())
++            log.info(sm.getString("standardContext.reloadingStarted"));
++
++        // Stop accepting requests temporarily
++        setPaused(true);
++
++        try {
++            stop();
++        } catch (LifecycleException e) {
++            log.error(sm.getString("standardContext.stoppingContext"), e);
++        }
++
++        try {
++            start();
++        } catch (LifecycleException e) {
++            log.error(sm.getString("standardContext.startingContext"), e);
++        }
++
++        setPaused(false);
++
++    }
++
++
++    /**
++     * Remove the specified application listener class from the set of
++     * listeners for this application.
++     *
++     * @param listener Java class name of the listener to be removed
++     */
++    public void removeApplicationListener(String listener) {
++
++        synchronized (applicationListeners) {
++
++            // Make sure this welcome file is currently present
++            int n = -1;
++            for (int i = 0; i < applicationListeners.length; i++) {
++                if (applicationListeners[i].equals(listener)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            String results[] = new String[applicationListeners.length - 1];
++            for (int i = 0; i < applicationListeners.length; i++) {
++                if (i != n)
++                    results[j++] = applicationListeners[i];
++            }
++            applicationListeners = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeApplicationListener", listener);
++
++        // FIXME - behavior if already started?
++
++    }
++
++
++    /**
++     * Remove the application parameter with the specified name from
++     * the set for this application.
++     *
++     * @param name Name of the application parameter to remove
++     */
++    public void removeApplicationParameter(String name) {
++
++        synchronized (applicationParameters) {
++
++            // Make sure this parameter is currently present
++            int n = -1;
++            for (int i = 0; i < applicationParameters.length; i++) {
++                if (name.equals(applicationParameters[i].getName())) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified parameter
++            int j = 0;
++            ApplicationParameter results[] =
++                new ApplicationParameter[applicationParameters.length - 1];
++            for (int i = 0; i < applicationParameters.length; i++) {
++                if (i != n)
++                    results[j++] = applicationParameters[i];
++            }
++            applicationParameters = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeApplicationParameter", name);
++
++    }
++
++
++    /**
++     * Add a child Container, only if the proposed child is an implementation
++     * of Wrapper.
++     *
++     * @param child Child container to be added
++     *
++     * @exception IllegalArgumentException if the proposed container is
++     *  not an implementation of Wrapper
++     */
++    public void removeChild(Container child) {
++
++        if (!(child instanceof Wrapper)) {
++            throw new IllegalArgumentException
++                (sm.getString("standardContext.notWrapper"));
++        }
++
++        super.removeChild(child);
++
++    }
++
++
++    /**
++     * Remove the specified security constraint from this web application.
++     *
++     * @param constraint Constraint to be removed
++     */
++    public void removeConstraint(SecurityConstraint constraint) {
++
++        synchronized (constraints) {
++
++            // Make sure this constraint is currently present
++            int n = -1;
++            for (int i = 0; i < constraints.length; i++) {
++                if (constraints[i].equals(constraint)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            SecurityConstraint results[] =
++                new SecurityConstraint[constraints.length - 1];
++            for (int i = 0; i < constraints.length; i++) {
++                if (i != n)
++                    results[j++] = constraints[i];
++            }
++            constraints = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeConstraint", constraint);
++
++    }
++
++
++    /**
++     * Remove the error page for the specified error code or
++     * Java language exception, if it exists; otherwise, no action is taken.
++     *
++     * @param errorPage The error page definition to be removed
++     */
++    public void removeErrorPage(ErrorPage errorPage) {
++
++        String exceptionType = errorPage.getExceptionType();
++        if (exceptionType != null) {
++            synchronized (exceptionPages) {
++                exceptionPages.remove(exceptionType);
++            }
++        } else {
++            synchronized (statusPages) {
++                if (errorPage.getErrorCode() == 200) {
++                    this.okErrorPage = null;
++                }
++                statusPages.remove(new Integer(errorPage.getErrorCode()));
++            }
++        }
++        fireContainerEvent("removeErrorPage", errorPage);
++
++    }
++
++
++    /**
++     * Remove the specified filter definition from this Context, if it exists;
++     * otherwise, no action is taken.
++     *
++     * @param filterDef Filter definition to be removed
++     */
++    public void removeFilterDef(FilterDef filterDef) {
++
++        synchronized (filterDefs) {
++            filterDefs.remove(filterDef.getFilterName());
++        }
++        fireContainerEvent("removeFilterDef", filterDef);
++
++    }
++
++
++    /**
++     * Remove a filter mapping from this Context.
++     *
++     * @param filterMap The filter mapping to be removed
++     */
++    public void removeFilterMap(FilterMap filterMap) {
++
++        synchronized (filterMaps) {
++
++            // Make sure this filter mapping is currently present
++            int n = -1;
++            for (int i = 0; i < filterMaps.length; i++) {
++                if (filterMaps[i] == filterMap) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified filter mapping
++            FilterMap results[] = new FilterMap[filterMaps.length - 1];
++            System.arraycopy(filterMaps, 0, results, 0, n);
++            System.arraycopy(filterMaps, n + 1, results, n,
++                             (filterMaps.length - 1) - n);
++            filterMaps = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeFilterMap", filterMap);
++
++    }
++
++
++    /**
++     * Remove a class name from the set of InstanceListener classes that
++     * will be added to newly created Wrappers.
++     *
++     * @param listener Class name of an InstanceListener class to be removed
++     */
++    public void removeInstanceListener(String listener) {
++
++        synchronized (instanceListeners) {
++
++            // Make sure this welcome file is currently present
++            int n = -1;
++            for (int i = 0; i < instanceListeners.length; i++) {
++                if (instanceListeners[i].equals(listener)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            String results[] = new String[instanceListeners.length - 1];
++            for (int i = 0; i < instanceListeners.length; i++) {
++                if (i != n)
++                    results[j++] = instanceListeners[i];
++            }
++            instanceListeners = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeInstanceListener", listener);
++
++    }
++
++
++    /**
++     * Remove any message destination with the specified name.
++     *
++     * @param name Name of the message destination to remove
++     */
++    public void removeMessageDestination(String name) {
++
++        synchronized (messageDestinations) {
++            messageDestinations.remove(name);
++        }
++        fireContainerEvent("removeMessageDestination", name);
++
++    }
++
++
++    /**
++     * Remove any message destination ref with the specified name.
++     *
++     * @param name Name of the message destination ref to remove
++     */
++    public void removeMessageDestinationRef(String name) {
++
++        namingResources.removeMessageDestinationRef(name);
++        fireContainerEvent("removeMessageDestinationRef", name);
++
++    }
++
++
++    /**
++     * Remove the MIME mapping for the specified extension, if it exists;
++     * otherwise, no action is taken.
++     *
++     * @param extension Extension to remove the mapping for
++     */
++    public void removeMimeMapping(String extension) {
++
++        synchronized (mimeMappings) {
++            mimeMappings.remove(extension);
++        }
++        fireContainerEvent("removeMimeMapping", extension);
++
++    }
++
++
++    /**
++     * Remove the context initialization parameter with the specified
++     * name, if it exists; otherwise, no action is taken.
++     *
++     * @param name Name of the parameter to remove
++     */
++    public void removeParameter(String name) {
++
++        synchronized (parameters) {
++            parameters.remove(name);
++        }
++        fireContainerEvent("removeParameter", name);
++
++    }
++
++
++    /**
++     * Remove any security role reference for the specified name
++     *
++     * @param role Security role (as used in the application) to remove
++     */
++    public void removeRoleMapping(String role) {
++
++        synchronized (roleMappings) {
++            roleMappings.remove(role);
++        }
++        fireContainerEvent("removeRoleMapping", role);
++
++    }
++
++
++    /**
++     * Remove any security role with the specified name.
++     *
++     * @param role Security role to remove
++     */
++    public void removeSecurityRole(String role) {
++
++        synchronized (securityRoles) {
++
++            // Make sure this security role is currently present
++            int n = -1;
++            for (int i = 0; i < securityRoles.length; i++) {
++                if (role.equals(securityRoles[i])) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified security role
++            int j = 0;
++            String results[] = new String[securityRoles.length - 1];
++            for (int i = 0; i < securityRoles.length; i++) {
++                if (i != n)
++                    results[j++] = securityRoles[i];
++            }
++            securityRoles = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeSecurityRole", role);
++
++    }
++
++
++    /**
++     * Remove any servlet mapping for the specified pattern, if it exists;
++     * otherwise, no action is taken.
++     *
++     * @param pattern URL pattern of the mapping to remove
++     */
++    public void removeServletMapping(String pattern) {
++
++        String name = null;
++        synchronized (servletMappings) {
++            name = (String) servletMappings.remove(pattern);
++        }
++        Wrapper wrapper = (Wrapper) findChild(name);
++        if( wrapper != null ) {
++            wrapper.removeMapping(pattern);
++        }
++        mapper.removeWrapper(pattern);
++        fireContainerEvent("removeServletMapping", pattern);
++
++    }
++
++
++    /**
++     * Remove the tag library location forthe specified tag library URI.
++     *
++     * @param uri URI, relative to the web.xml file
++     */
++    public void removeTaglib(String uri) {
++
++        synchronized (taglibs) {
++            taglibs.remove(uri);
++        }
++        fireContainerEvent("removeTaglib", uri);
++    }
++
++
++    /**
++     * Remove the specified watched resource name from the list associated
++     * with this Context.
++     * 
++     * @param name Name of the watched resource to be removed
++     */
++    public void removeWatchedResource(String name) {
++        
++        synchronized (watchedResources) {
++
++            // Make sure this watched resource is currently present
++            int n = -1;
++            for (int i = 0; i < watchedResources.length; i++) {
++                if (watchedResources[i].equals(name)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified watched resource
++            int j = 0;
++            String results[] = new String[watchedResources.length - 1];
++            for (int i = 0; i < watchedResources.length; i++) {
++                if (i != n)
++                    results[j++] = watchedResources[i];
++            }
++            watchedResources = results;
++
++        }
++
++        fireContainerEvent("removeWatchedResource", name);
++
++    }
++    
++    
++    /**
++     * Remove the specified welcome file name from the list recognized
++     * by this Context.
++     *
++     * @param name Name of the welcome file to be removed
++     */
++    public void removeWelcomeFile(String name) {
++
++        synchronized (welcomeFiles) {
++
++            // Make sure this welcome file is currently present
++            int n = -1;
++            for (int i = 0; i < welcomeFiles.length; i++) {
++                if (welcomeFiles[i].equals(name)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            String results[] = new String[welcomeFiles.length - 1];
++            for (int i = 0; i < welcomeFiles.length; i++) {
++                if (i != n)
++                    results[j++] = welcomeFiles[i];
++            }
++            welcomeFiles = results;
++
++        }
++
++        // Inform interested listeners
++        postWelcomeFiles();
++        fireContainerEvent("removeWelcomeFile", name);
++
++    }
++
++
++    /**
++     * Remove a class name from the set of LifecycleListener classes that
++     * will be added to newly created Wrappers.
++     *
++     * @param listener Class name of a LifecycleListener class to be removed
++     */
++    public void removeWrapperLifecycle(String listener) {
++
++
++        synchronized (wrapperLifecycles) {
++
++            // Make sure this welcome file is currently present
++            int n = -1;
++            for (int i = 0; i < wrapperLifecycles.length; i++) {
++                if (wrapperLifecycles[i].equals(listener)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            String results[] = new String[wrapperLifecycles.length - 1];
++            for (int i = 0; i < wrapperLifecycles.length; i++) {
++                if (i != n)
++                    results[j++] = wrapperLifecycles[i];
++            }
++            wrapperLifecycles = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeWrapperLifecycle", listener);
++
++    }
++
++
++    /**
++     * Remove a class name from the set of ContainerListener classes that
++     * will be added to newly created Wrappers.
++     *
++     * @param listener Class name of a ContainerListener class to be removed
++     */
++    public void removeWrapperListener(String listener) {
++
++
++        synchronized (wrapperListeners) {
++
++            // Make sure this welcome file is currently present
++            int n = -1;
++            for (int i = 0; i < wrapperListeners.length; i++) {
++                if (wrapperListeners[i].equals(listener)) {
++                    n = i;
++                    break;
++                }
++            }
++            if (n < 0)
++                return;
++
++            // Remove the specified constraint
++            int j = 0;
++            String results[] = new String[wrapperListeners.length - 1];
++            for (int i = 0; i < wrapperListeners.length; i++) {
++                if (i != n)
++                    results[j++] = wrapperListeners[i];
++            }
++            wrapperListeners = results;
++
++        }
++
++        // Inform interested listeners
++        fireContainerEvent("removeWrapperListener", listener);
++
++    }
++
++
++    /**
++     * Gets the cumulative processing times of all servlets in this
++     * StandardContext.
++     *
++     * @return Cumulative processing times of all servlets in this
++     * StandardContext
++     */
++    public long getProcessingTime() {
++        
++        long result = 0;
++
++        Container[] children = findChildren();
++        if (children != null) {
++            for( int i=0; i< children.length; i++ ) {
++                result += ((StandardWrapper)children[i]).getProcessingTime();
++            }
++        }
++
++        return result;
++    }
++
++
++    // --------------------------------------------------------- Public Methods
++
++
++    /**
++     * Configure and initialize the set of filters for this Context.
++     * Return <code>true</code> if all filter initialization completed
++     * successfully, or <code>false</code> otherwise.
++     */
++    public boolean filterStart() {
++
++        if (getLogger().isDebugEnabled())
++            getLogger().debug("Starting filters");
++        // Instantiate and record a FilterConfig for each defined filter
++        boolean ok = true;
++        synchronized (filterConfigs) {
++            filterConfigs.clear();
++            Iterator names = filterDefs.keySet().iterator();
++            while (names.hasNext()) {
++                String name = (String) names.next();
++                if (getLogger().isDebugEnabled())
++                    getLogger().debug(" Starting filter '" + name + "'");
++                ApplicationFilterConfig filterConfig = null;
++                try {
++                    filterConfig = new ApplicationFilterConfig
++                      (this, (FilterDef) filterDefs.get(name));
++                    filterConfigs.put(name, filterConfig);
++                } catch (Throwable t) {
++                    getLogger().error
++                        (sm.getString("standardContext.filterStart", name), t);
++                    ok = false;
++                }
++            }
++        }
++
++        return (ok);
++
++    }
++
++
++    /**
++     * Finalize and release the set of filters for this Context.
++     * Return <code>true</code> if all filter finalization completed
++     * successfully, or <code>false</code> otherwise.
++     */
++    public boolean filterStop() {
++
++        if (getLogger().isDebugEnabled())
++            getLogger().debug("Stopping filters");
++
++        // Release all Filter and FilterConfig instances
++        synchronized (filterConfigs) {
++            Iterator names = filterConfigs.keySet().iterator();
++            while (names.hasNext()) {
++                String name = (String) names.next();
++                if (getLogger().isDebugEnabled())
++                    getLogger().debug(" Stopping filter '" + name + "'");
++                ApplicationFilterConfig filterConfig =
++                  (ApplicationFilterConfig) filterConfigs.get(name);
++                filterConfig.release();
++            }
++            filterConfigs.clear();
++        }
++        return (true);
++
++    }
++
++
++    /**
++     * Find and return the initialized <code>FilterConfig</code> for the
++     * specified filter name, if any; otherwise return <code>null</code>.
++     *
++     * @param name Name of the desired filter
++     */
++    public FilterConfig findFilterConfig(String name) {
++
++        return ((FilterConfig) filterConfigs.get(name));
++
++    }
++
++
++    /**
++     * Configure the set of instantiated application event listeners
++     * for this Context.  Return <code>true</code> if all listeners wre
++     * initialized successfully, or <code>false</code> otherwise.
++     */
++    public boolean listenerStart() {
++
++        if (log.isDebugEnabled())
++            log.debug("Configuring application event listeners");
++
++        // Instantiate the required listeners
++        ClassLoader loader = getLoader().getClassLoader();
++        String listeners[] = findApplicationListeners();
++        Object results[] = new Object[listeners.length];
++        boolean ok = true;
++        for (int i = 0; i < results.length; i++) {
++            if (getLogger().isDebugEnabled())
++                getLogger().debug(" Configuring event listener class '" +
++                    listeners[i] + "'");
++            try {
++                Class clazz = loader.loadClass(listeners[i]);
++                results[i] = clazz.newInstance();
++            } catch (Throwable t) {
++                getLogger().error
++                    (sm.getString("standardContext.applicationListener",
++                                  listeners[i]), t);
++                ok = false;
++            }
++        }
++        if (!ok) {
++            getLogger().error(sm.getString("standardContext.applicationSkipped"));
++            return (false);
++        }
++
++        // Sort listeners in two arrays
++        ArrayList eventListeners = new ArrayList();
++        ArrayList lifecycleListeners = new ArrayList();
++        for (int i = 0; i < results.length; i++) {
++            if ((results[i] instanceof ServletContextAttributeListener)
++                || (results[i] instanceof ServletRequestAttributeListener)
++                || (results[i] instanceof ServletRequestListener)
++                || (results[i] instanceof HttpSessionAttributeListener)) {
++                eventListeners.add(results[i]);
++            }
++            if ((results[i] instanceof ServletContextListener)
++                || (results[i] instanceof HttpSessionListener)) {
++                lifecycleListeners.add(results[i]);
++            }
++        }
++
++        setApplicationEventListeners(eventListeners.toArray());
++        setApplicationLifecycleListeners(lifecycleListeners.toArray());
++
++        // Send application start events
++
++        if (getLogger().isDebugEnabled())
++            getLogger().debug("Sending application start events");
++
++        Object instances[] = getApplicationLifecycleListeners();
++        if (instances == null)
++            return (ok);
++        ServletContextEvent event =
++          new ServletContextEvent(getServletContext());
++        for (int i = 0; i < instances.length; i++) {
++            if (instances[i] == null)
++                continue;
++            if (!(instances[i] instanceof ServletContextListener))
++                continue;
++            ServletContextListener listener =
++                (ServletContextListener) instances[i];
++            try {
++                fireContainerEvent("beforeContextInitialized", listener);
++                listener.contextInitialized(event);
++                fireContainerEvent("afterContextInitialized", listener);
++            } catch (Throwable t) {
++                fireContainerEvent("afterContextInitialized", listener);
++                getLogger().error
++                    (sm.getString("standardContext.listenerStart",
++                                  instances[i].getClass().getName()), t);
++                ok = false;
++            }
++        }
++        return (ok);
++
++    }
++
++
++    /**
++     * Send an application stop event to all interested listeners.
++     * Return <code>true</code> if all events were sent successfully,
++     * or <code>false</code> otherwise.
++     */
++    public boolean listenerStop() {
++
++        if (log.isDebugEnabled())
++            log.debug("Sending application stop events");
++
++        boolean ok = true;
++        Object listeners[] = getApplicationLifecycleListeners();
++        if (listeners == null)
++            return (ok);
++        ServletContextEvent event =
++          new ServletContextEvent(getServletContext());
++        for (int i = 0; i < listeners.length; i++) {
++            int j = (listeners.length - 1) - i;
++            if (listeners[j] == null)
++                continue;
++            if (!(listeners[j] instanceof ServletContextListener))
++                continue;
++            ServletContextListener listener =
++                (ServletContextListener) listeners[j];
++            try {
++                fireContainerEvent("beforeContextDestroyed", listener);
++                listener.contextDestroyed(event);
++                fireContainerEvent("afterContextDestroyed", listener);
++            } catch (Throwable t) {
++                fireContainerEvent("afterContextDestroyed", listener);
++                getLogger().error
++                    (sm.getString("standardContext.listenerStop",
++                                  listeners[j].getClass().getName()), t);
++                ok = false;
++            }
++        }
++
++        setApplicationEventListeners(null);
++        setApplicationLifecycleListeners(null);
++
++        return (ok);
++
++    }
++
++
++    /**
++     * Allocate resources, including proxy.
++     * Return <code>true</code> if initialization was successfull,
++     * or <code>false</code> otherwise.
++     */
++    public boolean resourcesStart() {
++
++        boolean ok = true;
++
++        Hashtable env = new Hashtable();
++        if (getParent() != null)
++            env.put(ProxyDirContext.HOST, getParent().getName());
++        env.put(ProxyDirContext.CONTEXT, getName());
++
++        try {
++            ProxyDirContext proxyDirContext =
++                new ProxyDirContext(env, webappResources);
++            if (webappResources instanceof FileDirContext) {
++                filesystemBased = true;
++                ((FileDirContext) webappResources).setCaseSensitive
++                    (isCaseSensitive());
++                ((FileDirContext) webappResources).setAllowLinking
++                    (isAllowLinking());
++            }
++            if (webappResources instanceof BaseDirContext) {
++                ((BaseDirContext) webappResources).setDocBase(getBasePath());
++                ((BaseDirContext) webappResources).setCached
++                    (isCachingAllowed());
++                ((BaseDirContext) webappResources).setCacheTTL(getCacheTTL());
++                ((BaseDirContext) webappResources).setCacheMaxSize
++                    (getCacheMaxSize());
++                ((BaseDirContext) webappResources).allocate();
++            }
++            // Register the cache in JMX
++            if (isCachingAllowed()) {
++                ObjectName resourcesName = 
++                    new ObjectName(this.getDomain() + ":type=Cache,host=" 
++                                   + getHostname() + ",path=" 
++                                   + (("".equals(getPath()))?"/":getPath()));
++                Registry.getRegistry(null, null).registerComponent
++                    (proxyDirContext.getCache(), resourcesName, null);
++            }
++            this.resources = proxyDirContext;
++        } catch (Throwable t) {
++            log.error(sm.getString("standardContext.resourcesStart"), t);
++            ok = false;
++        }
++
++        return (ok);
++
++    }
++
++
++    /**
++     * Deallocate resources and destroy proxy.
++     */
++    public boolean resourcesStop() {
++
++        boolean ok = true;
++
++        try {
++            if (resources != null) {
++                if (resources instanceof Lifecycle) {
++                    ((Lifecycle) resources).stop();
++                }
++                if (webappResources instanceof BaseDirContext) {
++                    ((BaseDirContext) webappResources).release();
++                }
++                // Unregister the cache in JMX
++                if (isCachingAllowed()) {
++                    ObjectName resourcesName = 
++                        new ObjectName(this.getDomain()
++                                       + ":type=Cache,host=" 
++                                       + getHostname() + ",path=" 
++                                       + (("".equals(getPath()))?"/"
++                                          :getPath()));
++                    Registry.getRegistry(null, null)
++                        .unregisterComponent(resourcesName);
++                }
++            }
++        } catch (Throwable t) {
++            log.error(sm.getString("standardContext.resourcesStop"), t);
++            ok = false;
++        }
++
++        this.resources = null;
++
++        return (ok);
++
++    }
++
++
++    /**
++     * Load and initialize all servlets marked "load on startup" in the
++     * web application deployment descriptor.
++     *
++     * @param children Array of wrappers for all currently defined
++     *  servlets (including those not declared load on startup)
++     */
++    public void loadOnStartup(Container children[]) {
++
++        // Collect "load on startup" servlets that need to be initialized
++        TreeMap map = new TreeMap();
++        for (int i = 0; i < children.length; i++) {
++            Wrapper wrapper = (Wrapper) children[i];
++            int loadOnStartup = wrapper.getLoadOnStartup();
++            if (loadOnStartup < 0)
++                continue;
++            if (loadOnStartup == 0)     // Arbitrarily put them last
++                loadOnStartup = Integer.MAX_VALUE;
++            Integer key = new Integer(loadOnStartup);
++            ArrayList list = (ArrayList) map.get(key);
++            if (list == null) {
++                list = new ArrayList();
++                map.put(key, list);
++            }
++            list.add(wrapper);
++        }
++
++        // Load the collected "load on startup" servlets
++        Iterator keys = map.keySet().iterator();
++        while (keys.hasNext()) {
++            Integer key = (Integer) keys.next();
++            ArrayList list = (ArrayList) map.get(key);
++            Iterator wrappers = list.iterator();
++            while (wrappers.hasNext()) {
++                Wrapper wrapper = (Wrapper) wrappers.next();
++                try {
++                    wrapper.load();
++                } catch (ServletException e) {
++                    getLogger().error(sm.getString("standardWrapper.loadException",
++                                      getName()), StandardWrapper.getRootCause(e));
++                    // NOTE: load errors (including a servlet that throws
++                    // UnavailableException from tht init() method) are NOT
++                    // fatal to application startup
++                }
++            }
++        }
++
++    }
++
++
++    /**
++     * Start this Context component.
++     *
++     * @exception LifecycleException if a startup error occurs
++     */
++    public synchronized void start() throws LifecycleException {
++        //if (lazy ) return;
++        if (started) {
++            if(log.isInfoEnabled())
++                log.info(sm.getString("containerBase.alreadyStarted", logName()));
++            return;
++        }
++        if( !initialized ) { 
++            try {
++                init();
++            } catch( Exception ex ) {
++                throw new LifecycleException("Error initializaing ", ex);
++            }
++        }
++        if(log.isDebugEnabled())
++            log.debug("Starting " + ("".equals(getName()) ? "ROOT" : getName()));
++
++        // Set JMX object name for proper pipeline registration
++        preRegisterJMX();
++
++        if ((oname != null) && 
++            (Registry.getRegistry(null, null).getMBeanServer().isRegistered(oname))) {
++            // As things depend on the JMX registration, the context
++            // must be reregistered again once properly initialized
++            Registry.getRegistry(null, null).unregisterComponent(oname);
++        }
++
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
++
++        setAvailable(false);
++        setConfigured(false);
++        boolean ok = true;
++
++        // Add missing components as necessary
++        if (webappResources == null) {   // (1) Required by Loader
++            if (log.isDebugEnabled())
++                log.debug("Configuring default Resources");
++            try {
++                if ((docBase != null) && (docBase.endsWith(".war")) && (!(new File(getBasePath())).isDirectory()))
++                    setResources(new WARDirContext());
++                else
++                    setResources(new FileDirContext());
++            } catch (IllegalArgumentException e) {
++                log.error("Error initializing resources: " + e.getMessage());
++                ok = false;
++            }
++        }
++        if (ok) {
++            if (!resourcesStart()) {
++                log.error( "Error in resourceStart()");
++                ok = false;
++            }
++        }
++
++        // Look for a realm - that may have been configured earlier. 
++        // If the realm is added after context - it'll set itself.
++        if( realm == null && mserver != null ) {
++            ObjectName realmName=null;
++            try {
++                realmName=new ObjectName( getEngineName() + ":type=Realm,host=" + 
++                        getHostname() + ",path=" + getPath());
++                if( mserver.isRegistered(realmName ) ) {
++                    mserver.invoke(realmName, "init", 
++                            new Object[] {},
++                            new String[] {}
++                    );            
++                }
++            } catch( Throwable t ) {
++                if(log.isDebugEnabled())
++                    log.debug("No realm for this host " + realmName);
++            }
++        }
++        
++        if (getLoader() == null) {
++            ClassLoader parent = null;
++            if (getPrivileged()) {
++                if (log.isDebugEnabled())
++                    log.debug("Configuring privileged default Loader");
++                parent = this.getClass().getClassLoader();
++            } else {
++                if (log.isDebugEnabled())
++                    log.debug("Configuring non-privileged default Loader");
++                parent = getParentClassLoader();
++            }
++            WebappLoader webappLoader = new WebappLoader(parent);
++            webappLoader.setDelegate(getDelegate());
++            setLoader(webappLoader);
++        }
++
++        // Initialize character set mapper
++        getCharsetMapper();
++
++        // Post work directory
++        postWorkDirectory();
++
++        // Validate required extensions
++        boolean dependencyCheck = true;
++        try {
++            dependencyCheck = ExtensionValidator.validateApplication
++                (getResources(), this);
++        } catch (IOException ioe) {
++            log.error("Error in dependencyCheck", ioe);
++            dependencyCheck = false;
++        }
++
++        if (!dependencyCheck) {
++            // do not make application available if depency check fails
++            ok = false;
++        }
++
++        // Reading the "catalina.useNaming" environment variable
++        String useNamingProperty = System.getProperty("catalina.useNaming");
++        if ((useNamingProperty != null)
++            && (useNamingProperty.equals("false"))) {
++            useNaming = false;
++        }
++
++        if (ok && isUseNaming()) {
++            if (namingContextListener == null) {
++                namingContextListener = new NamingContextListener();
++                namingContextListener.setName(getNamingContextName());
++                addLifecycleListener(namingContextListener);
++            }
++        }
++
++        // Binding thread
++        ClassLoader oldCCL = bindThread();
++
++        // Standard container startup
++        if (log.isDebugEnabled())
++            log.debug("Processing standard container startup");
++
++        if (ok) {
++
++            boolean mainOk = false;
++            try {
++
++                started = true;
++
++                // Start our subordinate components, if any
++                if ((loader != null) && (loader instanceof Lifecycle))
++                    ((Lifecycle) loader).start();
++
++                // Unbinding thread
++                unbindThread(oldCCL);
++
++                // Binding thread
++                oldCCL = bindThread();
++
++                if ((logger != null) && (logger instanceof Lifecycle))
++                    ((Lifecycle) logger).start();
++                if ((cluster != null) && (cluster instanceof Lifecycle))
++                    ((Lifecycle) cluster).start();
++                if ((realm != null) && (realm instanceof Lifecycle))
++                    ((Lifecycle) realm).start();
++                if ((resources != null) && (resources instanceof Lifecycle))
++                    ((Lifecycle) resources).start();
++
++                // Start our child containers, if any
++                Container children[] = findChildren();
++                for (int i = 0; i < children.length; i++) {
++                    if (children[i] instanceof Lifecycle)
++                        ((Lifecycle) children[i]).start();
++                }
++
++                // Start the Valves in our pipeline (including the basic),
++                // if any
++                if (pipeline instanceof Lifecycle) {
++                    ((Lifecycle) pipeline).start();
++                }
++                
++                if(getProcessTlds()) {
++                    processTlds();
++                }
++                
++                // Notify our interested LifecycleListeners
++                lifecycle.fireLifecycleEvent(START_EVENT, null);
++
++                // Start manager
++                if ((manager != null) && (manager instanceof Lifecycle)) {
++                    ((Lifecycle) getManager()).start();
++                }
++
++                // Start ContainerBackgroundProcessor thread
++                super.threadStart();
++
++                mainOk = true;
++
++            } finally {
++                // Unbinding thread
++                unbindThread(oldCCL);
++                if (!mainOk) {
++                    // An exception occurred
++                    // Register with JMX anyway, to allow management
++                    registerJMX();
++                }
++            }
++
++        }
++        if (!getConfigured()) {
++            log.error( "Error getConfigured");
++            ok = false;
++        }
++
++        // We put the resources into the servlet context
++        if (ok)
++            getServletContext().setAttribute
++                (Globals.RESOURCES_ATTR, getResources());
++
++        // Initialize associated mapper
++        mapper.setContext(getPath(), welcomeFiles, resources);
++
++        // Binding thread
++        oldCCL = bindThread();
++
++        // Create context attributes that will be required
++        if (ok) {
++            postWelcomeFiles();
++        }
++
++        if (ok) {
++            // Notify our interested LifecycleListeners
++            lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
++        }
++
++        // Configure and call application event listeners and filters
++        if (ok) {
++            if (!listenerStart()) {
++                log.error( "Error listenerStart");
++                ok = false;
++            }
++        }
++        if (ok) {
++            if (!filterStart()) {
++                log.error( "Error filterStart");
++                ok = false;
++            }
++        }
++
++        // Load and initialize all "load on startup" servlets
++        if (ok) {
++            loadOnStartup(findChildren());
++        }
++
++        // Unbinding thread
++        unbindThread(oldCCL);
++
++        // Set available status depending upon startup success
++        if (ok) {
++            if (log.isDebugEnabled())
++                log.debug("Starting completed");
++            setAvailable(true);
++        } else {
++            log.error(sm.getString("standardContext.startFailed", getName()));
++            try {
++                stop();
++            } catch (Throwable t) {
++                log.error(sm.getString("standardContext.startCleanup"), t);
++            }
++            setAvailable(false);
++        }
++
++        // JMX registration
++        registerJMX();
++
++        startTime=System.currentTimeMillis();
++        
++        // Send j2ee.state.running notification 
++        if (ok && (this.getObjectName() != null)) {
++            Notification notification = 
++                new Notification("j2ee.state.running", this.getObjectName(), 
++                                sequenceNumber++);
++            broadcaster.sendNotification(notification);
++        }
++
++        // Close all JARs right away to avoid always opening a peak number 
++        // of files on startup
++        if (getLoader() instanceof WebappLoader) {
++            ((WebappLoader) getLoader()).closeJARs(true);
++        }
++
++        // Reinitializing if something went wrong
++        if (!ok && started) {
++            stop();
++        }
++
++        //cacheContext();
++    }
++
++    /**
++     * Processes TLDs.
++     *
++     * @throws LifecycleException If an error occurs
++     */
++     protected void processTlds() throws LifecycleException {
++       TldConfig tldConfig = new TldConfig();
++       tldConfig.setContext(this);
++
++       // (1)  check if the attribute has been defined
++       //      on the context element.
++       tldConfig.setTldValidation(tldValidation);
++       tldConfig.setTldNamespaceAware(tldNamespaceAware);
++
++       // (2) if the attribute wasn't defined on the context
++       //     try the host.
++       if (!tldValidation) {
++         tldConfig.setTldValidation
++           (((StandardHost) getParent()).getXmlValidation());
++       }
++
++       if (!tldNamespaceAware) {
++         tldConfig.setTldNamespaceAware
++           (((StandardHost) getParent()).getXmlNamespaceAware());
++       }
++                    
++       try {
++         tldConfig.execute();
++       } catch (Exception ex) {
++         log.error("Error reading tld listeners " 
++                    + ex.toString(), ex); 
++       }
++     }
++    
++    private void cacheContext() {
++        try {
++            File workDir=new File( getWorkPath() );
++            
++            File ctxSer=new File( workDir, "_tomcat_context.ser");
++            FileOutputStream fos=new FileOutputStream( ctxSer );
++            ObjectOutputStream oos=new ObjectOutputStream( fos );
++            oos.writeObject(this);
++            oos.close();
++            fos.close();
++        } catch( Throwable t ) {
++            if(log.isInfoEnabled())
++                log.info("Error saving context.ser ", t);
++        }
++    }
++
++    
++    /**
++     * Stop this Context component.
++     *
++     * @exception LifecycleException if a shutdown error occurs
++     */
++    public synchronized void stop() throws LifecycleException {
++
++        // Validate and update our current component state
++        if (!started) {
++            if(log.isInfoEnabled())
++                log.info(sm.getString("containerBase.notStarted", logName()));
++            return;
++        }
++
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
++        
++        // Send j2ee.state.stopping notification 
++        if (this.getObjectName() != null) {
++            Notification notification = 
++                new Notification("j2ee.state.stopping", this.getObjectName(), 
++                                sequenceNumber++);
++            broadcaster.sendNotification(notification);
++        }
++        
++        // Mark this application as unavailable while we shut down
++        setAvailable(false);
++
++        // Binding thread
++        ClassLoader oldCCL = bindThread();
++
++        // Stop our filters
++        filterStop();
++
++        // Stop ContainerBackgroundProcessor thread
++        super.threadStop();
++
++        if ((manager != null) && (manager instanceof Lifecycle)) {
++            ((Lifecycle) manager).stop();
++        }
++
++        // Finalize our character set mapper
++        setCharsetMapper(null);
++
++        // Normal container shutdown processing
++        if (log.isDebugEnabled())
++            log.debug("Processing standard container shutdown");
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
++        started = false;
++
++        try {
++
++            // Stop the Valves in our pipeline (including the basic), if any
++            if (pipeline instanceof Lifecycle) {
++                ((Lifecycle) pipeline).stop();
++            }
++
++            // Stop our child containers, if any
++            Container[] children = findChildren();
++            for (int i = 0; i < children.length; i++) {
++                if (children[i] instanceof Lifecycle)
++                    ((Lifecycle) children[i]).stop();
++            }
++
++            // Stop our application listeners
++            listenerStop();
++
++            // Clear all application-originated servlet context attributes
++            if (context != null)
++                context.clearAttributes();
++
++            // Stop resources
++            resourcesStop();
++
++            if ((realm != null) && (realm instanceof Lifecycle)) {
++                ((Lifecycle) realm).stop();
++            }
++            if ((cluster != null) && (cluster instanceof Lifecycle)) {
++                ((Lifecycle) cluster).stop();
++            }
++            if ((logger != null) && (logger instanceof Lifecycle)) {
++                ((Lifecycle) logger).stop();
++            }
++            if ((loader != null) && (loader instanceof Lifecycle)) {
++                ((Lifecycle) loader).stop();
++            }
++
++        } finally {
++
++            // Unbinding thread
++            unbindThread(oldCCL);
++
++        }
++
++        // Send j2ee.state.stopped notification 
++        if (this.getObjectName() != null) {
++            Notification notification = 
++                new Notification("j2ee.state.stopped", this.getObjectName(), 
++                                sequenceNumber++);
++            broadcaster.sendNotification(notification);
++        }
++        
++        // Reset application context
++        context = null;
++
++        // This object will no longer be visible or used. 
++        try {
++            resetContext();
++        } catch( Exception ex ) {
++            log.error( "Error reseting context " + this + " " + ex, ex );
++        }
++        
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
++
++        if (log.isDebugEnabled())
++            log.debug("Stopping complete");
++
++    }
++
++    /** Destroy needs to clean up the context completely.
++     * 
++     * The problem is that undoing all the config in start() and restoring 
++     * a 'fresh' state is impossible. After stop()/destroy()/init()/start()
++     * we should have the same state as if a fresh start was done - i.e
++     * read modified web.xml, etc. This can only be done by completely 
++     * removing the context object and remapping a new one, or by cleaning
++     * up everything.
++     * 
++     * XXX Should this be done in stop() ?
++     * 
++     */ 
++    public void destroy() throws Exception {
++        if( oname != null ) { 
++            // Send j2ee.object.deleted notification 
++            Notification notification = 
++                new Notification("j2ee.object.deleted", this.getObjectName(), 
++                                sequenceNumber++);
++            broadcaster.sendNotification(notification);
++        } 
++        super.destroy();
++
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(DESTROY_EVENT, null);
++
++        instanceListeners = new String[0];
++        applicationListeners = new String[0];
++    }
++    
++    private void resetContext() throws Exception, MBeanRegistrationException {
++        // Restore the original state ( pre reading web.xml in start )
++        // If you extend this - override this method and make sure to clean up
++        children=new HashMap();
++        startupTime = 0;
++        startTime = 0;
++        tldScanTime = 0;
++
++        // Bugzilla 32867
++        distributable = false;
++
++        if(log.isDebugEnabled())
++            log.debug("resetContext " + oname + " " + mserver);
++    }
++
++    /**
++     * Return a String representation of this component.
++     */
++    public String toString() {
++
++        StringBuffer sb = new StringBuffer();
++        if (getParent() != null) {
++            sb.append(getParent().toString());
++            sb.append(".");
++        }
++        sb.append("StandardContext[");
++        sb.append(getName());
++        sb.append("]");
++        return (sb.toString());
++
++    }
++
++
++    // ------------------------------------------------------ Protected Methods
++
++
++    /**
++     * Adjust the URL pattern to begin with a leading slash, if appropriate
++     * (i.e. we are running a servlet 2.2 application).  Otherwise, return
++     * the specified URL pattern unchanged.
++     *
++     * @param urlPattern The URL pattern to be adjusted (if needed)
++     *  and returned
++     */
++    protected String adjustURLPattern(String urlPattern) {
++
++        if (urlPattern == null)
++            return (urlPattern);
++        if (urlPattern.startsWith("/") || urlPattern.startsWith("*."))
++            return (urlPattern);
++        if (!isServlet22())
++            return (urlPattern);
++        if(log.isDebugEnabled())
++            log.debug(sm.getString("standardContext.urlPattern.patternWarning",
++                         urlPattern));
++        return ("/" + urlPattern);
++
++    }
++
++
++    /**
++     * Are we processing a version 2.2 deployment descriptor?
++     */
++    protected boolean isServlet22() {
++
++        if (this.publicId == null)
++            return (false);
++        if (this.publicId.equals
++            (org.apache.catalina.startup.Constants.WebDtdPublicId_22))
++            return (true);
++        else
++            return (false);
++
++    }
++
++
++    /**
++     * Return a File object representing the base directory for the
++     * entire servlet container (i.e. the Engine container if present).
++     */
++    protected File engineBase() {
++        String base=System.getProperty("catalina.base");
++        if( base == null ) {
++            StandardEngine eng=(StandardEngine)this.getParent().getParent();
++            base=eng.getBaseDir();
++        }
++        return (new File(base));
++    }
++
++
++    // -------------------------------------------------------- Private Methods
++
++
++    /**
++     * Bind current thread, both for CL purposes and for JNDI ENC support
++     * during : startup, shutdown and realoading of the context.
++     *
++     * @return the previous context class loader
++     */
++    private ClassLoader bindThread() {
++
++        ClassLoader oldContextClassLoader =
++            Thread.currentThread().getContextClassLoader();
++
++        if (getResources() == null)
++            return oldContextClassLoader;
++
++        if (getLoader().getClassLoader() != null) {
++            Thread.currentThread().setContextClassLoader
++                (getLoader().getClassLoader());
++        }
++
++        DirContextURLStreamHandler.bind(getResources());
++
++        if (isUseNaming()) {
++            try {
++                ContextBindings.bindThread(this, this);
++            } catch (NamingException e) {
++                // Silent catch, as this is a normal case during the early
++                // startup stages
++            }
++        }
++
++        return oldContextClassLoader;
++
++    }
++
++
++    /**
++     * Unbind thread.
++     */
++    private void unbindThread(ClassLoader oldContextClassLoader) {
++
++        Thread.currentThread().setContextClassLoader(oldContextClassLoader);
++
++        oldContextClassLoader = null;
++
++        if (isUseNaming()) {
++            ContextBindings.unbindThread(this, this);
++        }
++
++        DirContextURLStreamHandler.unbind();
++
++    }
++
++
++
++    /**
++     * Get base path.
++     */
++    private String getBasePath() {
++        String docBase = null;
++        Container container = this;
++        while (container != null) {
++            if (container instanceof Host)
++                break;
++            container = container.getParent();
++        }
++        File file = new File(getDocBase());
++        if (!file.isAbsolute()) {
++            if (container == null) {
++                docBase = (new File(engineBase(), getDocBase())).getPath();
++            } else {
++                // Use the "appBase" property of this container
++                String appBase = ((Host) container).getAppBase();
++                file = new File(appBase);
++                if (!file.isAbsolute())
++                    file = new File(engineBase(), appBase);
++                docBase = (new File(file, getDocBase())).getPath();
++            }
++        } else {
++            docBase = file.getPath();
++        }
++        return docBase;
++    }
++
++
++    /**
++     * Get app base.
++     */
++    private String getAppBase() {
++        String appBase = null;
++        Container container = this;
++        while (container != null) {
++            if (container instanceof Host)
++                break;
++            container = container.getParent();
++        }
++        if (container != null) {
++            appBase = ((Host) container).getAppBase();
++        }
++        return appBase;
++    }
++
++
++    /**
++     * Get config base.
++     */
++    public File getConfigBase() {
++        File configBase = 
++            new File(System.getProperty("catalina.base"), "conf");
++        if (!configBase.exists()) {
++            return null;
++        }
++        Container container = this;
++        Container host = null;
++        Container engine = null;
++        while (container != null) {
++            if (container instanceof Host)
++                host = container;
++            if (container instanceof Engine)
++                engine = container;
++            container = container.getParent();
++        }
++        if (engine != null) {
++            configBase = new File(configBase, engine.getName());
++        }
++        if (host != null) {
++            configBase = new File(configBase, host.getName());
++        }
++        if (saveConfig) {
++            configBase.mkdirs();
++        }
++        return configBase;
++    }
++
++
++    /**
++     * Given a context path, get the config file name.
++     */
++    protected String getDefaultConfigFile() {
++        String basename = null;
++        String path = getPath();
++        if (path.equals("")) {
++            basename = "ROOT";
++        } else {
++            basename = path.substring(1).replace('/', '#');
++        }
++        return (basename + ".xml");
++    }
++
++
++    /**
++     * Copy a file.
++     */
++    private boolean copy(File src, File dest) {
++        FileInputStream is = null;
++        FileOutputStream os = null;
++        try {
++            is = new FileInputStream(src);
++            os = new FileOutputStream(dest);
++            byte[] buf = new byte[4096];
++            while (true) {
++                int len = is.read(buf);
++                if (len < 0)
++                    break;
++                os.write(buf, 0, len);
++            }
++            is.close();
++            os.close();
++        } catch (IOException e) {
++            return false;
++        } finally {
++            try {
++                if (is != null) {
++                    is.close();
++                }
++            } catch (Exception e) {
++                // Ignore
++            }
++            try {
++                if (os != null) {
++                    os.close();
++                }
++            } catch (Exception e) {
++                // Ignore
++            }
++        }
++        return true;
++    }
++
++
++    /**
++     * Get naming context full name.
++     */
++    private String getNamingContextName() {
++    if (namingContextName == null) {
++        Container parent = getParent();
++        if (parent == null) {
++        namingContextName = getName();
++        } else {
++        Stack stk = new Stack();
++        StringBuffer buff = new StringBuffer();
++        while (parent != null) {
++            stk.push(parent.getName());
++            parent = parent.getParent();
++        }
++        while (!stk.empty()) {
++            buff.append("/" + stk.pop());
++        }
++        buff.append(getName());
++        namingContextName = buff.toString();
++        }
++    }
++    return namingContextName;
++    }
++
++
++    /**
++     * Return the request processing paused flag for this Context.
++     */
++    public boolean getPaused() {
++
++        return (this.paused);
++
++    }
++
++
++    /**
++     * Post a copy of our web application resources as a servlet context
++     * attribute.
++     */
++    private void postResources() {
++
++        getServletContext().setAttribute
++            (Globals.RESOURCES_ATTR, getResources());
++
++    }
++
++
++    /**
++     * Post a copy of our current list of welcome files as a servlet context
++     * attribute, so that the default servlet can find them.
++     */
++    private void postWelcomeFiles() {
++
++        getServletContext().setAttribute("org.apache.catalina.WELCOME_FILES",
++                                         welcomeFiles);
++
++    }
++
++    public String getHostname() {
++        Container parentHost = getParent();
++        if (parentHost != null) {
++            hostName = parentHost.getName();
++        }
++        if ((hostName == null) || (hostName.length() < 1))
++            hostName = "_";
++        return hostName;
++    }
++
++    /**
++     * Set the appropriate context attribute for our work directory.
++     */
++    private void postWorkDirectory() {
++
++        // Acquire (or calculate) the work directory path
++        String workDir = getWorkDir();
++        if (workDir == null) {
++
++            // Retrieve our parent (normally a host) name
++            String hostName = null;
++            String engineName = null;
++            String hostWorkDir = null;
++            Container parentHost = getParent();
++            if (parentHost != null) {
++                hostName = parentHost.getName();
++                if (parentHost instanceof StandardHost) {
++                    hostWorkDir = ((StandardHost)parentHost).getWorkDir();
++                }
++                Container parentEngine = parentHost.getParent();
++                if (parentEngine != null) {
++                   engineName = parentEngine.getName();
++                }
++            }
++            if ((hostName == null) || (hostName.length() < 1))
++                hostName = "_";
++            if ((engineName == null) || (engineName.length() < 1))
++                engineName = "_";
++
++            String temp = getPath();
++            if (temp.startsWith("/"))
++                temp = temp.substring(1);
++            temp = temp.replace('/', '_');
++            temp = temp.replace('\\', '_');
++            if (temp.length() < 1)
++                temp = "_";
++            if (hostWorkDir != null ) {
++                workDir = hostWorkDir + File.separator + temp;
++            } else {
++                workDir = "work" + File.separator + engineName +
++                    File.separator + hostName + File.separator + temp;
++            }
++            setWorkDir(workDir);
++        }
++
++        // Create this directory if necessary
++        File dir = new File(workDir);
++        if (!dir.isAbsolute()) {
++            File catalinaHome = engineBase();
++            String catalinaHomePath = null;
++            try {
++                catalinaHomePath = catalinaHome.getCanonicalPath();
++                dir = new File(catalinaHomePath, workDir);
++            } catch (IOException e) {
++            }
++        }
++        dir.mkdirs();
++
++        // Set the appropriate servlet context attribute
++        getServletContext().setAttribute(Globals.WORK_DIR_ATTR, dir);
++        if (getServletContext() instanceof ApplicationContext)
++            ((ApplicationContext) getServletContext()).setAttributeReadOnly
++                (Globals.WORK_DIR_ATTR);
++
++    }
++
++
++    /**
++     * Set the request processing paused flag for this Context.
++     *
++     * @param paused The new request processing paused flag
++     */
++    private void setPaused(boolean paused) {
++
++        this.paused = paused;
++
++    }
++
++
++    /**
++     * Validate the syntax of a proposed <code>&lt;url-pattern&gt;</code>
++     * for conformance with specification requirements.
++     *
++     * @param urlPattern URL pattern to be validated
++     */
++    private boolean validateURLPattern(String urlPattern) {
++
++        if (urlPattern == null)
++            return (false);
++        if (urlPattern.indexOf('\n') >= 0 || urlPattern.indexOf('\r') >= 0) {
++            getLogger().warn(sm.getString("standardContext.crlfinurl",urlPattern));
++        }
++        if (urlPattern.startsWith("*.")) {
++            if (urlPattern.indexOf('/') < 0)
++                return (true);
++            else
++                return (false);
++        }
++        if ( (urlPattern.startsWith("/")) &&
++                (urlPattern.indexOf("*.") < 0))
++            return (true);
++        else
++            return (false);
++
++    }
++
++
++    // ------------------------------------------------------------- Operations
++
++
++    /**
++     * JSR77 deploymentDescriptor attribute
++     *
++     * @return string deployment descriptor 
++     */
++    public String getDeploymentDescriptor() {
++    
++        InputStream stream = null;
++        ServletContext servletContext = getServletContext();
++        if (servletContext != null) {
++            stream = servletContext.getResourceAsStream(
++                org.apache.catalina.startup.Constants.ApplicationWebXml);
++        }
++        if (stream == null) {
++            return "";
++        }
++        BufferedReader br = new BufferedReader(
++                                new InputStreamReader(stream));
++        StringBuffer sb = new StringBuffer();
++        String strRead = "";
++        try {
++            while (strRead != null) {
++                sb.append(strRead);
++                strRead = br.readLine();
++            }
++        } catch (IOException e) {
++            return "";
++        }
++
++        return sb.toString(); 
++    
++    }
++    
++    
++    /**
++     * JSR77 servlets attribute
++     *
++     * @return list of all servlets ( we know about )
++     */
++    public String[] getServlets() {
++        
++        String[] result = null;
++
++        Container[] children = findChildren();
++        if (children != null) {
++            result = new String[children.length];
++            for( int i=0; i< children.length; i++ ) {
++                result[i] = ((StandardWrapper)children[i]).getObjectName();
++            }
++        }
++
++        return result;
++    }
++    
++
++    public ObjectName createObjectName(String hostDomain, ObjectName parentName)
++            throws MalformedObjectNameException
++    {
++        String onameStr;
++        StandardHost hst=(StandardHost)getParent();
++        
++        String pathName=getName();
++        String hostName=getParent().getName();
++        String name= "//" + ((hostName==null)? "DEFAULT" : hostName) +
++                (("".equals(pathName))?"/":pathName );
++
++        String suffix=",J2EEApplication=" +
++                getJ2EEApplication() + ",J2EEServer=" +
++                getJ2EEServer();
++
++        onameStr="j2eeType=WebModule,name=" + name + suffix;
++        if( log.isDebugEnabled())
++            log.debug("Registering " + onameStr + " for " + oname);
++        
++        // default case - no domain explictely set.
++        if( getDomain() == null ) domain=hst.getDomain();
++
++        ObjectName oname=new ObjectName(getDomain() + ":" + onameStr);
++        return oname;        
++    }    
++    
++    private void preRegisterJMX() {
++        try {
++            StandardHost host = (StandardHost) getParent();
++            if ((oname == null) 
++                || (oname.getKeyProperty("j2eeType") == null)) {
++                oname = createObjectName(host.getDomain(), host.getJmxName());
++                controller = oname;
++            }
++        } catch(Exception ex) {
++            if(log.isInfoEnabled())
++                log.info("Error registering ctx with jmx " + this + " " +
++                     oname + " " + ex.toString(), ex );
++        }
++    }
++
++    private void registerJMX() {
++        try {
++            if (log.isDebugEnabled()) {
++                log.debug("Checking for " + oname );
++            }
++            if(! Registry.getRegistry(null, null)
++                .getMBeanServer().isRegistered(oname)) {
++                controller = oname;
++                Registry.getRegistry(null, null)
++                    .registerComponent(this, oname, null);
++                
++                // Send j2ee.object.created notification 
++                if (this.getObjectName() != null) {
++                    Notification notification = new Notification(
++                                                        "j2ee.object.created", 
++                                                        this.getObjectName(), 
++                                                        sequenceNumber++);
++                    broadcaster.sendNotification(notification);
++                }
++            }
++            Container children[] = findChildren();
++            for (int i=0; children!=null && i<children.length; i++) {
++                ((StandardWrapper)children[i]).registerJMX( this );
++            }
++        } catch (Exception ex) {
++            if(log.isInfoEnabled())
++                log.info("Error registering wrapper with jmx " + this + " " +
++                    oname + " " + ex.toString(), ex );
++        }
++    }
++
++    /** There are 2 cases:
++     *   1.The context is created and registered by internal APIS
++     *   2. The context is created by JMX, and it'll self-register.
++     *
++     * @param server The server
++     * @param name The object name
++     * @return ObjectName The name of the object
++     * @throws Exception If an error occurs
++     */
++    public ObjectName preRegister(MBeanServer server,
++                                  ObjectName name)
++            throws Exception
++    {
++        if( oname != null ) {
++            //log.info( "Already registered " + oname + " " + name);
++            // Temporary - /admin uses the old names
++            return name;
++        }
++        ObjectName result=super.preRegister(server,name);
++        return name;
++    }
++
++    public void preDeregister() throws Exception {
++        if( started ) {
++            try {
++                stop();
++            } catch( Exception ex ) {
++                log.error( "error stopping ", ex);
++            }
++        }
++    }
++
++    public void init() throws Exception {
++
++        if( this.getParent() == null ) {
++            ObjectName parentName=getParentName();
++            
++            if( ! mserver.isRegistered(parentName)) {
++                if(log.isDebugEnabled())
++                    log.debug("No host, creating one " + parentName);
++                StandardHost host=new StandardHost();
++                host.setName(hostName);
++                host.setAutoDeploy(false);
++                Registry.getRegistry(null, null)
++                    .registerComponent(host, parentName, null);
++                mserver.invoke(parentName, "init", new Object[] {}, new String[] {} );
++            }
++            ContextConfig config = new ContextConfig();
++            this.addLifecycleListener(config);
++
++            if(log.isDebugEnabled())
++                 log.debug( "AddChild " + parentName + " " + this);
++            try {
++                mserver.invoke(parentName, "addChild", new Object[] { this },
++                               new String[] {"org.apache.catalina.Container"});
++            } catch (Exception e) {
++                destroy();
++                throw e;
++            }
++            // It's possible that addChild may have started us
++            if( initialized ) {
++                return;
++            }
++        }
++        super.init();
++        
++        // Notify our interested LifecycleListeners
++        lifecycle.fireLifecycleEvent(INIT_EVENT, null);
++
++        // Send j2ee.state.starting notification 
++        if (this.getObjectName() != null) {
++            Notification notification = new Notification("j2ee.state.starting", 
++                                                        this.getObjectName(), 
++                                                        sequenceNumber++);
++            broadcaster.sendNotification(notification);
++        }
++        
++    }
++
++    public ObjectName getParentName() throws MalformedObjectNameException {
++        // "Life" update
++        String path=oname.getKeyProperty("name");
++        if( path == null ) {
++            log.error( "No name attribute " +name );
++            return null;
++        }
++        if( ! path.startsWith( "//")) {
++            log.error("Invalid name " + name);
++        }
++        path=path.substring(2);
++        int delim=path.indexOf( "/" );
++        hostName="localhost"; // Should be default...
++        if( delim > 0 ) {
++            hostName=path.substring(0, delim);
++            path = path.substring(delim);
++            if (path.equals("/")) {
++                this.setName("");
++            } else {
++                this.setName(path);
++            }
++        } else {
++            if(log.isDebugEnabled())
++                log.debug("Setting path " +  path );
++            this.setName( path );
++        }
++        // XXX The service and domain should be the same.
++        String parentDomain=getEngineName();
++        if( parentDomain == null ) parentDomain=domain;
++        ObjectName parentName=new ObjectName( parentDomain + ":" +
++                "type=Host,host=" + hostName);
++        return parentName;
++    }
++    
++    public void create() throws Exception{
++        init();
++    }
++
++    /* Remove a JMX notficationListener 
++     * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
++     */
++    public void removeNotificationListener(NotificationListener listener, 
++            NotificationFilter filter, Object object) throws ListenerNotFoundException {
++    	broadcaster.removeNotificationListener(listener,filter,object);
++    	
++    }
++    
++    private MBeanNotificationInfo[] notificationInfo;
++    
++    /* Get JMX Broadcaster Info
++     * @TODO use StringManager for international support!
++     * @TODO This two events we not send j2ee.state.failed and j2ee.attribute.changed!
++     * @see javax.management.NotificationBroadcaster#getNotificationInfo()
++     */
++    public MBeanNotificationInfo[] getNotificationInfo() {
++    	// FIXME: i18n
++    	if(notificationInfo == null) {
++    		notificationInfo = new MBeanNotificationInfo[]{
++    				new MBeanNotificationInfo(new String[] {
++    				"j2ee.object.created"},
++					Notification.class.getName(),
++					"web application is created"
++    				), 
++					new MBeanNotificationInfo(new String[] {
++					"j2ee.state.starting"},
++					Notification.class.getName(),
++					"change web application is starting"
++					),
++					new MBeanNotificationInfo(new String[] {
++					"j2ee.state.running"},
++					Notification.class.getName(),
++					"web application is running"
++					),
++					new MBeanNotificationInfo(new String[] {
++					"j2ee.state.stopped"},
++					Notification.class.getName(),
++					"web application start to stopped"
++					),
++					new MBeanNotificationInfo(new String[] {
++					"j2ee.object.stopped"},
++					Notification.class.getName(),
++					"web application is stopped"
++					),
++					new MBeanNotificationInfo(new String[] {
++					"j2ee.object.deleted"},
++					Notification.class.getName(),
++					"web application is deleted"
++					)
++    		};
++    		
++    	}
++    	
++    	return notificationInfo;
++    }
++    
++    
++    /* Add a JMX-NotificationListener
++     * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
++     */
++    public void addNotificationListener(NotificationListener listener, 
++            NotificationFilter filter, Object object) throws IllegalArgumentException {
++    	broadcaster.addNotificationListener(listener,filter,object);
++    	
++    }
++    
++    
++    /**
++     * Remove a JMX-NotificationListener 
++     * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
++     */
++    public void removeNotificationListener(NotificationListener listener) 
++    throws ListenerNotFoundException {
++    	broadcaster.removeNotificationListener(listener);
++    	
++    }
++    
++    
++    // ------------------------------------------------------------- Attributes
++
++
++    /**
++     * Return the naming resources associated with this web application.
++     */
++    public javax.naming.directory.DirContext getStaticResources() {
++
++        return getResources();
++
++    }
++
++
++    /**
++     * Return the naming resources associated with this web application.
++     * FIXME: Fooling introspection ... 
++     */
++    public javax.naming.directory.DirContext findStaticResources() {
++
++        return getResources();
++
++    }
++
++
++    /**
++     * Return the naming resources associated with this web application.
++     */
++    public String[] getWelcomeFiles() {
++
++        return findWelcomeFiles();
++
++    }
++
++     /**
++     * Set the validation feature of the XML parser used when
++     * parsing xml instances.
++     * @param webXmlValidation true to enable xml instance validation
++     */
++    public void setXmlValidation(boolean webXmlValidation){
++        
++        this.webXmlValidation = webXmlValidation;
++
++    }
++
++    /**
++     * Get the server.xml <context> attribute's xmlValidation.
++     * @return true if validation is enabled.
++     *
++     */
++    public boolean getXmlValidation(){
++        return webXmlValidation;
++    }
++
++
++    /**
++     * Get the server.xml <context> attribute's xmlNamespaceAware.
++     * @return true if namespace awarenes is enabled.
++     */
++    public boolean getXmlNamespaceAware(){
++        return webXmlNamespaceAware;
++    }
++
++
++    /**
++     * Set the namespace aware feature of the XML parser used when
++     * parsing xml instances.
++     * @param webXmlNamespaceAware true to enable namespace awareness
++     */
++    public void setXmlNamespaceAware(boolean webXmlNamespaceAware){
++        this.webXmlNamespaceAware= webXmlNamespaceAware;
++    }    
++
++
++    /**
++     * Set the validation feature of the XML parser used when
++     * parsing tlds files. 
++     * @param tldValidation true to enable xml instance validation
++     */
++    public void setTldValidation(boolean tldValidation){
++        
++        this.tldValidation = tldValidation;
++
++    }
++
++    /**
++     * Get the server.xml <context> attribute's webXmlValidation.
++     * @return true if validation is enabled.
++     *
++     */
++    public boolean getTldValidation(){
++        return tldValidation;
++    }
++
++    /**
++     * Sets the process TLDs attribute.
++     *
++     * @param newProcessTlds The new value
++     */
++    public void setProcessTlds(boolean newProcessTlds) {
++	processTlds = newProcessTlds;
++    }
++
++    /**
++     * Returns the processTlds attribute value.
++     */
++    public boolean getProcessTlds() {
++	return processTlds;
++    }
++
++    /**
++     * Get the server.xml <host> attribute's xmlNamespaceAware.
++     * @return true if namespace awarenes is enabled.
++     */
++    public boolean getTldNamespaceAware(){
++        return tldNamespaceAware;
++    }
++
++
++    /**
++     * Set the namespace aware feature of the XML parser used when
++     * parsing xml instances.
++     * @param tldNamespaceAware true to enable namespace awareness
++     */
++    public void setTldNamespaceAware(boolean tldNamespaceAware){
++        this.tldNamespaceAware= tldNamespaceAware;
++    }    
++
++
++    /** 
++     * Support for "stateManageable" JSR77 
++     */
++    public boolean isStateManageable() {
++        return true;
++    }
++    
++    public void startRecursive() throws LifecycleException {
++        // nothing to start recursive, the servlets will be started by load-on-startup
++        start();
++    }
++    
++    public int getState() {
++        if( started ) {
++            return 1; // RUNNING
++        }
++        if( initialized ) {
++            return 0; // starting ? 
++        }
++        if( ! available ) { 
++            return 4; //FAILED
++        }
++        // 2 - STOPPING
++        return 3; // STOPPED
++    }
++    
++    /**
++     * The J2EE Server ObjectName this module is deployed on.
++     */     
++    private String server = null;
++    
++    /**
++     * The Java virtual machines on which this module is running.
++     */       
++    private String[] javaVMs = null;
++    
++    public String getServer() {
++        return server;
++    }
++        
++    public String setServer(String server) {
++        return this.server=server;
++    }
++        
++    public String[] getJavaVMs() {
++        return javaVMs;
++    }
++        
++    public String[] setJavaVMs(String[] javaVMs) {
++        return this.javaVMs = javaVMs;
++    }
++    
++    /**
++     * Gets the time this context was started.
++     *
++     * @return Time (in milliseconds since January 1, 1970, 00:00:00) when this
++     * context was started 
++     */
++    public long getStartTime() {
++        return startTime;
++    }
++    
++    public boolean isEventProvider() {
++        return false;
++    }
++    
++    public boolean isStatisticsProvider() {
++        return false;
++    }
++    
++}
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/jakarta-tomcat-catalina.iml jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/jakarta-tomcat-catalina.iml
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/jakarta-tomcat-catalina.iml	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-catalina/jakarta-tomcat-catalina.iml	2005-09-26 01:21:13.000000000 -0400
+@@ -0,0 +1,16 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<module version="4" relativePaths="true" type="JAVA_MODULE">
++  <component name="ModuleRootManager" />
++  <component name="NewModuleRootManager">
++    <output url="file://$MODULE_DIR$/classes" />
++    <exclude-output />
++    <content url="file://$MODULE_DIR$">
++      <sourceFolder url="file://$MODULE_DIR$/catalina/src/share" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/catalina/src/test" isTestSource="false" />
++    </content>
++    <orderEntry type="inheritedJdk" />
++    <orderEntry type="sourceFolder" forTests="false" />
++    <orderEntryProperties />
++  </component>
++</module>
++
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/jakarta-tomcat-connectors.iml jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/jakarta-tomcat-connectors.iml
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/jakarta-tomcat-connectors.iml	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/jakarta-tomcat-connectors.iml	2005-09-26 01:21:13.000000000 -0400
+@@ -0,0 +1,28 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<module version="4" relativePaths="true" type="JAVA_MODULE">
++  <component name="ModuleRootManager" />
++  <component name="NewModuleRootManager">
++    <output url="file://$MODULE_DIR$/classes" />
++    <exclude-output />
++    <content url="file://$MODULE_DIR$">
++      <sourceFolder url="file://$MODULE_DIR$/coyote/src/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/coyote/src/test" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/http11/src/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/http11/src/test/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jk/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jk/jkant/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jk/test" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jni/examples" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jni/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/jni/test" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/juli/src/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/naming/src" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/util/java" isTestSource="false" />
++      <sourceFolder url="file://$MODULE_DIR$/util/loader" isTestSource="false" />
++    </content>
++    <orderEntry type="inheritedJdk" />
++    <orderEntry type="sourceFolder" forTests="false" />
++    <orderEntryProperties />
++  </component>
++</module>
++
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jakarta-tomcat-jasper.iml jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jakarta-tomcat-jasper.iml
+--- upstream/jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jakarta-tomcat-jasper.iml	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jakarta-tomcat-jasper.iml	2005-09-26 00:02:02.000000000 -0400
+@@ -0,0 +1,15 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<module version="4" relativePaths="true" type="JAVA_MODULE">
++  <component name="ModuleRootManager" />
++  <component name="NewModuleRootManager">
++    <output url="file://$MODULE_DIR$/classes" />
++    <exclude-output />
++    <content url="file://$MODULE_DIR$">
++      <sourceFolder url="file://$MODULE_DIR$/jasper2/src/share" isTestSource="false" />
++    </content>
++    <orderEntry type="inheritedJdk" />
++    <orderEntry type="sourceFolder" forTests="false" />
++    <orderEntryProperties />
++  </component>
++</module>
++
+diff -Nru upstream/jakarta-tomcat-5.5.9-src/LICENSE jakarta-tomcat-5.5.9-src/LICENSE
+--- upstream/jakarta-tomcat-5.5.9-src/LICENSE	1969-12-31 19:00:00.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/LICENSE	2005-09-26 00:05:01.000000000 -0400
+@@ -0,0 +1,201 @@
++                                 Apache License
++                           Version 2.0, January 2004
++                        http://www.apache.org/licenses/
++
++   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
++
++   1. Definitions.
++
++      "License" shall mean the terms and conditions for use, reproduction,
++      and distribution as defined by Sections 1 through 9 of this document.
++
++      "Licensor" shall mean the copyright owner or entity authorized by
++      the copyright owner that is granting the License.
++
++      "Legal Entity" shall mean the union of the acting entity and all
++      other entities that control, are controlled by, or are under common
++      control with that entity. For the purposes of this definition,
++      "control" means (i) the power, direct or indirect, to cause the
++      direction or management of such entity, whether by contract or
++      otherwise, or (ii) ownership of fifty percent (50%) or more of the
++      outstanding shares, or (iii) beneficial ownership of such entity.
++
++      "You" (or "Your") shall mean an individual or Legal Entity
++      exercising permissions granted by this License.
++
++      "Source" form shall mean the preferred form for making modifications,
++      including but not limited to software source code, documentation
++      source, and configuration files.
++
++      "Object" form shall mean any form resulting from mechanical
++      transformation or translation of a Source form, including but
++      not limited to compiled object code, generated documentation,
++      and conversions to other media types.
++
++      "Work" shall mean the work of authorship, whether in Source or
++      Object form, made available under the License, as indicated by a
++      copyright notice that is included in or attached to the work
++      (an example is provided in the Appendix below).
++
++      "Derivative Works" shall mean any work, whether in Source or Object
++      form, that is based on (or derived from) the Work and for which the
++      editorial revisions, annotations, elaborations, or other modifications
++      represent, as a whole, an original work of authorship. For the purposes
++      of this License, Derivative Works shall not include works that remain
++      separable from, or merely link (or bind by name) to the interfaces of,
++      the Work and Derivative Works thereof.
++
++      "Contribution" shall mean any work of authorship, including
++      the original version of the Work and any modifications or additions
++      to that Work or Derivative Works thereof, that is intentionally
++      submitted to Licensor for inclusion in the Work by the copyright owner
++      or by an individual or Legal Entity authorized to submit on behalf of
++      the copyright owner. For the purposes of this definition, "submitted"
++      means any form of electronic, verbal, or written communication sent
++      to the Licensor or its representatives, including but not limited to
++      communication on electronic mailing lists, source code control systems,
++      and issue tracking systems that are managed by, or on behalf of, the
++      Licensor for the purpose of discussing and improving the Work, but
++      excluding communication that is conspicuously marked or otherwise
++      designated in writing by the copyright owner as "Not a Contribution."
++
++      "Contributor" shall mean Licensor and any individual or Legal Entity
++      on behalf of whom a Contribution has been received by Licensor and
++      subsequently incorporated within the Work.
++
++   2. Grant of Copyright License. Subject to the terms and conditions of
++      this License, each Contributor hereby grants to You a perpetual,
++      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
++      copyright license to reproduce, prepare Derivative Works of,
++      publicly display, publicly perform, sublicense, and distribute the
++      Work and such Derivative Works in Source or Object form.
++
++   3. Grant of Patent License. Subject to the terms and conditions of
++      this License, each Contributor hereby grants to You a perpetual,
++      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
++      (except as stated in this section) patent license to make, have made,
++      use, offer to sell, sell, import, and otherwise transfer the Work,
++      where such license applies only to those patent claims licensable
++      by such Contributor that are necessarily infringed by their
++      Contribution(s) alone or by combination of their Contribution(s)
++      with the Work to which such Contribution(s) was submitted. If You
++      institute patent litigation against any entity (including a
++      cross-claim or counterclaim in a lawsuit) alleging that the Work
++      or a Contribution incorporated within the Work constitutes direct
++      or contributory patent infringement, then any patent licenses
++      granted to You under this License for that Work shall terminate
++      as of the date such litigation is filed.
++
++   4. Redistribution. You may reproduce and distribute copies of the
++      Work or Derivative Works thereof in any medium, with or without
++      modifications, and in Source or Object form, provided that You
++      meet the following conditions:
++
++      (a) You must give any other recipients of the Work or
++          Derivative Works a copy of this License; and
++
++      (b) You must cause any modified files to carry prominent notices
++          stating that You changed the files; and
++
++      (c) You must retain, in the Source form of any Derivative Works
++          that You distribute, all copyright, patent, trademark, and
++          attribution notices from the Source form of the Work,
++          excluding those notices that do not pertain to any part of
++          the Derivative Works; and
++
++      (d) If the Work includes a "NOTICE" text file as part of its
++          distribution, then any Derivative Works that You distribute must
++          include a readable copy of the attribution notices contained
++          within such NOTICE file, excluding those notices that do not
++          pertain to any part of the Derivative Works, in at least one
++          of the following places: within a NOTICE text file distributed
++          as part of the Derivative Works; within the Source form or
++          documentation, if provided along with the Derivative Works; or,
++          within a display generated by the Derivative Works, if and
++          wherever such third-party notices normally appear. The contents
++          of the NOTICE file are for informational purposes only and
++          do not modify the License. You may add Your own attribution
++          notices within Derivative Works that You distribute, alongside
++          or as an addendum to the NOTICE text from the Work, provided
++          that such additional attribution notices cannot be construed
++          as modifying the License.
++
++      You may add Your own copyright statement to Your modifications and
++      may provide additional or different license terms and conditions
++      for use, reproduction, or distribution of Your modifications, or
++      for any such Derivative Works as a whole, provided Your use,
++      reproduction, and distribution of the Work otherwise complies with
++      the conditions stated in this License.
++
++   5. Submission of Contributions. Unless You explicitly state otherwise,
++      any Contribution intentionally submitted for inclusion in the Work
++      by You to the Licensor shall be under the terms and conditions of
++      this License, without any additional terms or conditions.
++      Notwithstanding the above, nothing herein shall supersede or modify
++      the terms of any separate license agreement you may have executed
++      with Licensor regarding such Contributions.
++
++   6. Trademarks. This License does not grant permission to use the trade
++      names, trademarks, service marks, or product names of the Licensor,
++      except as required for reasonable and customary use in describing the
++      origin of the Work and reproducing the content of the NOTICE file.
++
++   7. Disclaimer of Warranty. Unless required by applicable law or
++      agreed to in writing, Licensor provides the Work (and each
++      Contributor provides its Contributions) on an "AS IS" BASIS,
++      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
++      implied, including, without limitation, any warranties or conditions
++      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
++      PARTICULAR PURPOSE. You are solely responsible for determining the
++      appropriateness of using or redistributing the Work and assume any
++      risks associated with Your exercise of permissions under this License.
++
++   8. Limitation of Liability. In no event and under no legal theory,
++      whether in tort (including negligence), contract, or otherwise,
++      unless required by applicable law (such as deliberate and grossly
++      negligent acts) or agreed to in writing, shall any Contributor be
++      liable to You for damages, including any direct, indirect, special,
++      incidental, or consequential damages of any character arising as a
++      result of this License or out of the use or inability to use the
++      Work (including but not limited to damages for loss of goodwill,
++      work stoppage, computer failure or malfunction, or any and all
++      other commercial damages or losses), even if such Contributor
++      has been advised of the possibility of such damages.
++
++   9. Accepting Warranty or Additional Liability. While redistributing
++      the Work or Derivative Works thereof, You may choose to offer,
++      and charge a fee for, acceptance of support, warranty, indemnity,
++      or other liability obligations and/or rights consistent with this
++      License. However, in accepting such obligations, You may act only
++      on Your own behalf and on Your sole responsibility, not on behalf
++      of any other Contributor, and only if You agree to indemnify,
++      defend, and hold each Contributor harmless for any liability
++      incurred by, or claims asserted against, such Contributor by reason
++      of your accepting any such warranty or additional liability.
++
++   END OF TERMS AND CONDITIONS
++
++   APPENDIX: How to apply the Apache License to your work.
++
++      To apply the Apache License to your work, attach the following
++      boilerplate notice, with the fields enclosed by brackets "[]"
++      replaced with your own identifying information. (Don't include
++      the brackets!)  The text should be enclosed in the appropriate
++      comment syntax for the file format. We also recommend that a
++      file or class name and description of purpose be included on the
++      same "printed page" as the copyright notice for easier
++      identification within third-party archives.
++
++   Copyright [yyyy] [name of copyright owner]
++
++   Licensed under the Apache License, Version 2.0 (the "License");
++   you may not use this file except in compliance with the License.
++   You may obtain a copy of the License at
++
++       http://www.apache.org/licenses/LICENSE-2.0
++
++   Unless required by applicable law or agreed to in writing, software
++   distributed under the License is distributed on an "AS IS" BASIS,
++   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++   See the License for the specific language governing permissions and
++   limitations under the License.

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-removeJSSEfor13.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-removeJSSEfor13.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9-removeJSSEfor13.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,234 @@
+--- jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13Factory.java	2005-03-26 14:24:17.000000000 -0500
++++ /dev/null	2006-08-15 16:32:17.991678056 -0400
+@@ -1,43 +0,0 @@
+-/*
+- *  Copyright 1999-2004 The Apache Software Foundation
+- *
+- *  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.apache.tomcat.util.net.jsse;
+-
+-import java.net.Socket;
+-import javax.net.ssl.SSLSocket;
+-import org.apache.tomcat.util.net.SSLSupport;
+-import org.apache.tomcat.util.net.ServerSocketFactory;
+-
+-/**
+- * Implementation class for JSSEFactory for JSSE 1.0.x (that is an extension
+- * to the 1.3 JVM).
+- *
+- * @author Bill Barker
+- */
+-
+-class JSSE13Factory implements JSSEFactory {
+-
+-    JSSE13Factory() {
+-    }
+-
+-    public ServerSocketFactory getSocketFactory() {
+-        return new JSSE13SocketFactory();
+-    }
+-
+-    public SSLSupport getSSLSupport(Socket socket) {
+-        return new JSSESupport((SSLSocket)socket);
+-    }
+-}
+--- jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java	2005-03-26 14:24:17.000000000 -0500
++++ /dev/null	2006-08-15 16:32:17.991678056 -0400
+@@ -1,156 +0,0 @@
+-/*
+- *  Copyright 1999-2004 The Apache Software Foundation
+- *
+- *  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.apache.tomcat.util.net.jsse;
+-
+-import java.io.IOException;
+-import java.security.KeyStore;
+-import java.security.SecureRandom;
+-import java.security.Security;
+-import java.security.Provider;
+-
+-import javax.net.ssl.SSLServerSocket;
+-import javax.net.ssl.SSLSocket;
+-
+-/*
+-  1. Make the JSSE's jars available, either as an installed
+-     extension (copy them into jre/lib/ext) or by adding
+-     them to the Tomcat classpath.
+-  2. keytool -genkey -alias tomcat -keyalg RSA
+-     Use "changeit" as password ( this is the default we use )
+- */
+-
+-/**
+- * SSL server socket factory. It _requires_ a valid RSA key and
+- * JSSE. 
+- *
+- * @author Harish Prabandham
+- * @author Costin Manolache
+- * @author Stefan Freyr Stefansson
+- * @author EKR -- renamed to JSSESocketFactory
+- * @author Bill Barker
+- */
+-public class JSSE13SocketFactory extends JSSESocketFactory
+-{
+-    /**
+-     * Flag for client authentication
+-     */
+-    protected boolean clientAuth = false;
+-
+-    public JSSE13SocketFactory () {
+-        super();
+-    }
+-
+-    /**
+-     * Reads the keystore and initializes the SSL socket factory.
+-     *
+-     * NOTE: This method is identical in functionality to the method of the
+-     * same name in JSSE14SocketFactory, except that this method is used with
+-     * JSSE 1.0.x (which is an extension to the 1.3 JVM), whereas the other is
+-     * used with JSSE 1.1.x (which ships with the 1.4 JVM). Therefore, this
+-     * method uses classes in com.sun.net.ssl, which have since moved to
+-     * javax.net.ssl, and explicitly registers the required security providers,
+-     * which come standard in a 1.4 JVM.
+-     */
+-     void init() throws IOException {
+-        try {
+-            try {
+-                Class ssps = Class.forName("sun.security.provider.Sun");
+-                Security.addProvider ((Provider)ssps.newInstance());
+-            }catch(Exception cnfe) {
+-                //Ignore, since this is a non-Sun JVM
+-            }
+-            Security.addProvider (new com.sun.net.ssl.internal.ssl.Provider());
+-
+-            String clientAuthStr = (String)attributes.get("clientauth");
+-            if("true".equalsIgnoreCase(clientAuthStr) || 
+-               "yes".equalsIgnoreCase(clientAuthStr)  ||
+-               "want".equalsIgnoreCase(clientAuthStr)) {
+-                clientAuth = true;
+-            }
+-            
+-            // SSL protocol variant (e.g., TLS, SSL v3, etc.)
+-            String protocol = (String)attributes.get("protocol");
+-            if (protocol == null) protocol = defaultProtocol;
+-            
+-            // Certificate encoding algorithm (e.g., SunX509)
+-            String algorithm = (String)attributes.get("algorithm");
+-            if (algorithm == null) algorithm = defaultAlgorithm;
+-
+-            // Set up KeyManager, which will extract server key
+-            com.sun.net.ssl.KeyManagerFactory kmf = 
+-                com.sun.net.ssl.KeyManagerFactory.getInstance(algorithm);
+-            String keystoreType = (String)attributes.get("keystoreType");
+-            if (keystoreType == null) {
+-                keystoreType = defaultKeystoreType;
+-            }
+-            String keystorePass = getKeystorePassword();
+-            kmf.init(getKeystore(keystoreType, keystorePass),
+-                     keystorePass.toCharArray());
+-
+-            // Set up TrustManager
+-            com.sun.net.ssl.TrustManager[] tm = null;
+-            String truststoreType = (String)attributes.get("truststoreType");
+-            if(truststoreType == null) {
+-                truststoreType = keystoreType;
+-            }
+-            KeyStore trustStore = getTrustStore(truststoreType);
+-            if (trustStore != null) {
+-                com.sun.net.ssl.TrustManagerFactory tmf =
+-                    com.sun.net.ssl.TrustManagerFactory.getInstance("SunX509");
+-                tmf.init(trustStore);
+-                tm = tmf.getTrustManagers();
+-            }
+-
+-            // Create and init SSLContext
+-            com.sun.net.ssl.SSLContext context = 
+-                com.sun.net.ssl.SSLContext.getInstance(protocol); 
+-            context.init(kmf.getKeyManagers(), tm, new SecureRandom());
+-
+-            // Create proxy
+-            sslProxy = context.getServerSocketFactory();
+-
+-            // Determine which cipher suites to enable
+-            String requestedCiphers = (String)attributes.get("ciphers");
+-            enabledCiphers = getEnabledCiphers(requestedCiphers,
+-                     sslProxy.getSupportedCipherSuites());
+-
+-        } catch(Exception e) {
+-            if( e instanceof IOException )
+-                throw (IOException)e;
+-            throw new IOException(e.getMessage());
+-        }
+-    }
+-    protected String[] getEnabledProtocols(SSLServerSocket socket,
+-                                           String requestedProtocols){
+-        return null;
+-    }
+-    protected void setEnabledProtocols(SSLServerSocket socket, 
+-                                             String [] protocols){
+-    }
+-
+-    protected void configureClientAuth(SSLServerSocket socket){
+-        socket.setNeedClientAuth(clientAuth);
+-    }
+-
+-    protected void configureClientAuth(SSLSocket socket){
+-        // In JSSE 1.0.2 docs it does not explicitly
+-        // state whether SSLSockets returned from 
+-        // SSLServerSocket.accept() inherit this setting.
+-        socket.setNeedClientAuth(clientAuth);
+-    }
+-
+-}
+--- jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java.original	2006-10-25 16:33:35.000000000 -0400
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java	2006-10-25 16:58:14.000000000 -0400
+@@ -46,18 +46,21 @@
+     public JSSEImplementation() throws ClassNotFoundException {
+         // Check to see if JSSE is floating around somewhere
+         Class.forName(SSLSocketClass);
+-	if( JdkCompat.isJava14() ) {
++	if( JdkCompat.isJava14() || JdkCompat.isJava15() ) {
+ 	    try {
+ 		Class factcl = Class.forName(JSSE14Factory);
+ 		factory = (JSSEFactory)factcl.newInstance();
+ 	    } catch(Exception ex) {
+-		factory = new JSSE13Factory();
+-		if(logger.isDebugEnabled()) {
+-		    logger.debug("Error getting factory: " + JSSE14Factory, ex);
++		if(logger.isErrorEnabled()) {
++		    logger.error("Error getting factory: " + JSSE14Factory, ex);
+ 		}
++		throw (ClassNotFoundException) new ClassNotFoundException("error initializing JSSE factory").initCause(ex);
+ 	    }
+ 	} else {
+-	    factory = new JSSE13Factory();
++		if(logger.isErrorEnabled()) {
++		    logger.error("SSL is not supported for Java 1.3 and lower");
++		}
++		throw new IllegalStateException("SSL not supported for Java 1.3 and lower");
+ 	}
+     }
+ 

Added: apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9.patch01-JspServlet-5.15.17-backport.patch
===================================================================
--- apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9.patch01-JspServlet-5.15.17-backport.patch	                        (rev 0)
+++ apache-tomcat/5.5.9.patch05-brew/src/tomcat5-5.5.9.patch01-JspServlet-5.15.17-backport.patch	2008-04-11 19:39:17 UTC (rev 4505)
@@ -0,0 +1,41 @@
+--- jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServlet.java.old	2005-03-26 17:22:44.000000000 -0500
++++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServlet.java	2006-12-12 15:21:50.000000000 -0500
+@@ -17,6 +17,7 @@
+ package org.apache.jasper.servlet;
+ 
+ import java.io.IOException;
++import java.lang.reflect.Constructor;
+ import java.util.Enumeration;
+ 
+ import javax.servlet.ServletConfig;
+@@ -72,7 +73,29 @@
+ 	this.context = config.getServletContext();
+ 
+         // Initialize the JSP Runtime Context
+-        options = new EmbeddedServletOptions(config, context);
++        // Check for a custom Options implementation
++        String engineOptionsName = 
++            config.getInitParameter("engineOptionsClass");
++        if (engineOptionsName != null) {
++            // Instantiate the indicated Options implementation
++            try {
++                ClassLoader loader = Thread.currentThread()
++                        .getContextClassLoader();
++                Class engineOptionsClass = loader.loadClass(engineOptionsName);
++                Class[] ctorSig = { ServletConfig.class, ServletContext.class };
++                Constructor ctor = engineOptionsClass.getConstructor(ctorSig);
++                Object[] args = { config, context };
++                options = (Options) ctor.newInstance(args);
++            } catch (Throwable e) {
++                // Need to localize this.
++                log.warn("Failed to load engineOptionsClass", e);
++                // Use the default Options implementation
++                options = new EmbeddedServletOptions(config, context);
++            }
++        } else {
++            // Use the default Options implementation
++            options = new EmbeddedServletOptions(config, context);
++        }
+         rctxt = new JspRuntimeContext(context,options);
+ 
+ 	if (log.isDebugEnabled()) {




More information about the jboss-cvs-commits mailing list