diff --git a/javax.servlet/src/main/java/javax/servlet/GenericServlet.java b/javax.servlet/src/main/java/javax/servlet/GenericServlet.java
new file mode 100644
index 0000000..487b256
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/GenericServlet.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+/**
+ *
+ * Defines a generic, protocol-independent
+ * servlet. To write an HTTP servlet for use on the
+ * Web, extend {@link javax.servlet.http.HttpServlet} instead.
+ *
+ * <p><code>GenericServlet</code> implements the <code>Servlet</code>
+ * and <code>ServletConfig</code> interfaces. <code>GenericServlet</code>
+ * may be directly extended by a servlet, although it's more common to extend
+ * a protocol-specific subclass such as <code>HttpServlet</code>.
+ *
+ * <p><code>GenericServlet</code> makes writing servlets
+ * easier. It provides simple versions of the lifecycle methods 
+ * <code>init</code> and <code>destroy</code> and of the methods 
+ * in the <code>ServletConfig</code> interface. <code>GenericServlet</code>
+ * also implements the <code>log</code> method, declared in the
+ * <code>ServletContext</code> interface. 
+ *
+ * <p>To write a generic servlet, you need only
+ * override the abstract <code>service</code> method. 
+ *
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ *
+ *
+ */
+
+ 
+public abstract class GenericServlet 
+    implements Servlet, ServletConfig, java.io.Serializable
+{
+
+    private transient ServletConfig config;
+    
+
+    /**
+     *
+     * Does nothing. All of the servlet initialization
+     * is done by one of the <code>init</code> methods.
+     *
+     */
+
+    public GenericServlet() { }
+    
+    
+    
+   /**
+     * Called by the servlet container to indicate to a servlet that the
+     * servlet is being taken out of service.  See {@link Servlet#destroy}.
+     *
+     * 
+     */
+
+    public void destroy() {
+    }
+    
+    
+    
+    /**
+     * Returns a <code>String</code> containing the value of the named
+     * initialization parameter, or <code>null</code> if the parameter does
+     * not exist.  See {@link ServletConfig#getInitParameter}.
+     *
+     * <p>This method is supplied for convenience. It gets the 
+     * value of the named parameter from the servlet's 
+     * <code>ServletConfig</code> object.
+     *
+     * @param name 		a <code>String</code> specifying the name 
+     *				of the initialization parameter
+     *
+     * @return String 		a <code>String</code> containing the value
+     *				of the initalization parameter
+     *
+     */ 
+
+    public String getInitParameter(String name) {
+	return getServletConfig().getInitParameter(name);
+    }
+    
+    
+
+   /**
+    * Returns the names of the servlet's initialization parameters 
+    * as an <code>Enumeration</code> of <code>String</code> objects,
+    * or an empty <code>Enumeration</code> if the servlet has no
+    * initialization parameters.  See {@link
+    * ServletConfig#getInitParameterNames}.
+    *
+    * <p>This method is supplied for convenience. It gets the 
+    * parameter names from the servlet's <code>ServletConfig</code> object. 
+    *
+    *
+    * @return Enumeration 	an enumeration of <code>String</code>
+    *				objects containing the names of 
+    *				the servlet's initialization parameters
+    *
+    */
+
+    public Enumeration getInitParameterNames() {
+	return getServletConfig().getInitParameterNames();
+    }   
+    
+     
+ 
+     
+
+    /**
+     * Returns this servlet's {@link ServletConfig} object.
+     *
+     * @return ServletConfig 	the <code>ServletConfig</code> object
+     *				that initialized this servlet
+     *
+     */
+    
+    public ServletConfig getServletConfig() {
+	return config;
+    }
+    
+    
+ 
+    
+    /**
+     * Returns a reference to the {@link ServletContext} in which this servlet
+     * is running.  See {@link ServletConfig#getServletContext}.
+     *
+     * <p>This method is supplied for convenience. It gets the 
+     * context from the servlet's <code>ServletConfig</code> object.
+     *
+     *
+     * @return ServletContext 	the <code>ServletContext</code> object
+     *				passed to this servlet by the <code>init</code>
+     *				method
+     *
+     */
+
+    public ServletContext getServletContext() {
+	return getServletConfig().getServletContext();
+    }
+
+
+
+ 
+
+    /**
+     * Returns information about the servlet, such as 
+     * author, version, and copyright. 
+     * By default, this method returns an empty string.  Override this method
+     * to have it return a meaningful value.  See {@link
+     * Servlet#getServletInfo}.
+     *
+     *
+     * @return String 		information about this servlet, by default an
+     * 				empty string
+     *
+     */
+    
+    public String getServletInfo() {
+	return "";
+    }
+
+
+
+
+    /**
+     *
+     * Called by the servlet container to indicate to a servlet that the
+     * servlet is being placed into service.  See {@link Servlet#init}.
+     *
+     * <p>This implementation stores the {@link ServletConfig}
+     * object it receives from the servlet container for later use.
+     * When overriding this form of the method, call 
+     * <code>super.init(config)</code>.
+     *
+     * @param config 			the <code>ServletConfig</code> object
+     *					that contains configutation
+     *					information for this servlet
+     *
+     * @exception ServletException 	if an exception occurs that
+     *					interrupts the servlet's normal
+     *					operation
+     *
+     * 
+     * @see 				UnavailableException
+     *
+     */
+
+    public void init(ServletConfig config) throws ServletException {
+	this.config = config;
+	this.init();
+    }
+
+
+
+
+
+    /**
+     *
+     * A convenience method which can be overridden so that there's no need
+     * to call <code>super.init(config)</code>.
+     *
+     * <p>Instead of overriding {@link #init(ServletConfig)}, simply override
+     * this method and it will be called by
+     * <code>GenericServlet.init(ServletConfig config)</code>.
+     * The <code>ServletConfig</code> object can still be retrieved via {@link
+     * #getServletConfig}. 
+     *
+     * @exception ServletException 	if an exception occurs that
+     *					interrupts the servlet's
+     *					normal operation
+     *
+     */
+    
+    public void init() throws ServletException {
+
+    }
+    
+
+
+
+    /**
+     * 
+     * Writes the specified message to a servlet log file, prepended by the
+     * servlet's name.  See {@link ServletContext#log(String)}.
+     *
+     * @param msg 	a <code>String</code> specifying
+     *			the message to be written to the log file
+     *
+     */
+     
+    public void log(String msg) {
+	getServletContext().log(getClass().getName() + ": "+ msg);
+    }
+   
+   
+   
+   
+    /**
+     * Writes an explanatory message and a stack trace
+     * for a given <code>Throwable</code> exception
+     * to the servlet log file, prepended by the servlet's name.
+     * See {@link ServletContext#log(String, Throwable)}.
+     *
+     *
+     * @param message 		a <code>String</code> that describes
+     *				the error or exception
+     *
+     * @param t			the <code>java.lang.Throwable</code> error
+     * 				or exception
+     *
+     *
+     */
+   
+    public void log(String message, Throwable t) {
+	getServletContext().log(getClass().getName() + ": " + message, t);
+    }
+    
+    
+    
+    /**
+     * Called by the servlet container to allow the servlet to respond to
+     * a request.  See {@link Servlet#service}.
+     * 
+     * <p>This method is declared abstract so subclasses, such as 
+     * <code>HttpServlet</code>, must override it.
+     *
+     *
+     *
+     * @param req 	the <code>ServletRequest</code> object
+     *			that contains the client's request
+     *
+     * @param res 	the <code>ServletResponse</code> object
+     *			that will contain the servlet's response
+     *
+     * @exception ServletException 	if an exception occurs that
+     *					interferes with the servlet's
+     *					normal operation occurred
+     *
+     * @exception IOException 		if an input or output
+     *					exception occurs
+     *
+     */
+
+    public abstract void service(ServletRequest req, ServletResponse res)
+	throws ServletException, IOException;
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/LocalStrings.properties b/javax.servlet/src/main/java/javax/servlet/LocalStrings.properties
new file mode 100644
index 0000000..7ac4863
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/LocalStrings.properties
@@ -0,0 +1,6 @@
+# Default localized string information
+# Localized for Locale en_US
+
+err.not_iso8859_1=Not an ISO 8859-1 character: {0}
+value.true=true
+value.false=false
diff --git a/javax.servlet/src/main/java/javax/servlet/RequestDispatcher.java b/javax.servlet/src/main/java/javax/servlet/RequestDispatcher.java
new file mode 100644
index 0000000..73687a1
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/RequestDispatcher.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.IOException;
+
+
+/**
+ * Defines an object that receives requests from the client
+ * and sends them to any resource (such as a servlet,
+ * HTML file, or JSP file) on the server. The servlet
+ * container creates the <code>RequestDispatcher</code> object,
+ * which is used as a wrapper around a server resource located
+ * at a particular path or given by a particular name.
+ *
+ * <p>This interface is intended to wrap servlets,
+ * but a servlet container can create <code>RequestDispatcher</code>
+ * objects to wrap any type of resource.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see 	ServletContext#getRequestDispatcher(java.lang.String)
+ *
+ */
+
+public interface RequestDispatcher {
+
+
+
+
+
+/**
+ * Forwards a request from
+ * a servlet to another resource (servlet, JSP file, or
+ * HTML file) on the server. This method allows
+ * one servlet to do preliminary processing of
+ * a request and another resource to generate
+ * the response.
+ *
+ * <p>For a <code>RequestDispatcher</code> obtained via
+ * <code>getRequestDispatcher()</code>, the <code>ServletRequest</code>
+ * object has its path elements and parameters adjusted to match
+ * the path of the target resource.
+ *
+ * <p><code>forward</code> should be called before the response has been
+ * committed to the client (before response body output has been flushed).
+ * If the response already has been committed, this method throws
+ * an <code>IllegalStateException</code>.
+ * Uncommitted output in the response buffer is automatically cleared
+ * before the forward.
+ *
+ * <p>The request and response parameters must be the same
+ * objects as were passed to the calling servlet's service method.
+ *
+ *
+ * @param request		a {@link ServletRequest} object
+ *				that represents the request the client
+ * 				makes of the servlet
+ *
+ * @param response		a {@link ServletResponse} object
+ *				that represents the response the servlet
+ *				returns to the client
+ *
+ * @exception ServletException	if the target resource throws this exception
+ *
+ * @exception IOException	if the target resource throws this exception
+ *
+ * @exception IllegalStateException	if the response was already committed
+ *
+ */
+
+    public void forward(ServletRequest request, ServletResponse response)
+	throws ServletException, IOException;
+
+
+
+
+    /**
+     *
+     * Includes the content of a resource (servlet, JSP page,
+     * HTML file) in the response. In essence, this method enables
+     * programmatic server-side includes.
+     *
+     * <p>The {@link ServletResponse} object has its path elements
+     * and parameters remain unchanged from the caller's. The included
+     * servlet cannot change the response status code or set headers;
+     * any attempt to make a change is ignored.
+     *
+     * <p>The request and response parameters must be the same
+     * objects as were passed to the calling servlet's service method.
+     *
+     *
+     * @param request 			a {@link ServletRequest} object
+     *					that contains the client's request
+     *
+     * @param response 			a {@link ServletResponse} object
+     * 					that contains the servlet's response
+     *
+     * @exception ServletException 	if the included resource throws this exception
+     *
+     * @exception IOException 		if the included resource throws this exception
+     *
+     *
+     */
+
+    public void include(ServletRequest request, ServletResponse response)
+	throws ServletException, IOException;
+}
+
+
+
+
+
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/Servlet.java b/javax.servlet/src/main/java/javax/servlet/Servlet.java
new file mode 100644
index 0000000..1d267a7
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/Servlet.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.IOException;
+
+
+/**
+ * Defines methods that all servlets must implement.
+ *
+ * <p>A servlet is a small Java program that runs within a Web server.
+ * Servlets receive and respond to requests from Web clients,
+ * usually across HTTP, the HyperText Transfer Protocol. 
+ *
+ * <p>To implement this interface, you can write a generic servlet
+ * that extends
+ * <code>javax.servlet.GenericServlet</code> or an HTTP servlet that
+ * extends <code>javax.servlet.http.HttpServlet</code>.
+ *
+ * <p>This interface defines methods to initialize a servlet,
+ * to service requests, and to remove a servlet from the server.
+ * These are known as life-cycle methods and are called in the
+ * following sequence:
+ * <ol>
+ * <li>The servlet is constructed, then initialized with the <code>init</code> method.
+ * <li>Any calls from clients to the <code>service</code> method are handled.
+ * <li>The servlet is taken out of service, then destroyed with the 
+ * <code>destroy</code> method, then garbage collected and finalized.
+ * </ol>
+ *
+ * <p>In addition to the life-cycle methods, this interface
+ * provides the <code>getServletConfig</code> method, which the servlet 
+ * can use to get any startup information, and the <code>getServletInfo</code>
+ * method, which allows the servlet to return basic information about itself,
+ * such as author, version, and copyright.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see 	GenericServlet
+ * @see 	javax.servlet.http.HttpServlet
+ *
+ */
+
+
+public interface Servlet {
+
+    /**
+     * Called by the servlet container to indicate to a servlet that the 
+     * servlet is being placed into service.
+     *
+     * <p>The servlet container calls the <code>init</code>
+     * method exactly once after instantiating the servlet.
+     * The <code>init</code> method must complete successfully
+     * before the servlet can receive any requests.
+     *
+     * <p>The servlet container cannot place the servlet into service
+     * if the <code>init</code> method
+     * <ol>
+     * <li>Throws a <code>ServletException</code>
+     * <li>Does not return within a time period defined by the Web server
+     * </ol>
+     *
+     *
+     * @param config			a <code>ServletConfig</code> object 
+     *					containing the servlet's
+     * 					configuration and initialization parameters
+     *
+     * @exception ServletException 	if an exception has occurred that
+     *					interferes with the servlet's normal
+     *					operation
+     *
+     * @see 				UnavailableException
+     * @see 				#getServletConfig
+     *
+     */
+
+    public void init(ServletConfig config) throws ServletException;
+    
+    
+
+    /**
+     *
+     * Returns a {@link ServletConfig} object, which contains
+     * initialization and startup parameters for this servlet.
+     * The <code>ServletConfig</code> object returned is the one 
+     * passed to the <code>init</code> method. 
+     *
+     * <p>Implementations of this interface are responsible for storing the 
+     * <code>ServletConfig</code> object so that this 
+     * method can return it. The {@link GenericServlet}
+     * class, which implements this interface, already does this.
+     *
+     * @return		the <code>ServletConfig</code> object
+     *			that initializes this servlet
+     *
+     * @see 		#init
+     *
+     */
+
+    public ServletConfig getServletConfig();
+    
+    
+
+    /**
+     * Called by the servlet container to allow the servlet to respond to 
+     * a request.
+     *
+     * <p>This method is only called after the servlet's <code>init()</code>
+     * method has completed successfully.
+     * 
+     * <p>  The status code of the response always should be set for a servlet 
+     * that throws or sends an error.
+     *
+     * 
+     * <p>Servlets typically run inside multithreaded servlet containers
+     * that can handle multiple requests concurrently. Developers must 
+     * be aware to synchronize access to any shared resources such as files,
+     * network connections, and as well as the servlet's class and instance 
+     * variables. 
+     * More information on multithreaded programming in Java is available in 
+     * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
+     * the Java tutorial on multi-threaded programming</a>.
+     *
+     *
+     * @param req 	the <code>ServletRequest</code> object that contains
+     *			the client's request
+     *
+     * @param res 	the <code>ServletResponse</code> object that contains
+     *			the servlet's response
+     *
+     * @exception ServletException 	if an exception occurs that interferes
+     *					with the servlet's normal operation 
+     *
+     * @exception IOException 		if an input or output exception occurs
+     *
+     */
+
+    public void service(ServletRequest req, ServletResponse res)
+	throws ServletException, IOException;
+	
+	
+
+    /**
+     * Returns information about the servlet, such
+     * as author, version, and copyright.
+     * 
+     * <p>The string that this method returns should
+     * be plain text and not markup of any kind (such as HTML, XML,
+     * etc.).
+     *
+     * @return 		a <code>String</code> containing servlet information
+     *
+     */
+
+    public String getServletInfo();
+    
+    
+
+    /**
+     *
+     * Called by the servlet container to indicate to a servlet that the
+     * servlet is being taken out of service.  This method is
+     * only called once all threads within the servlet's
+     * <code>service</code> method have exited or after a timeout
+     * period has passed. After the servlet container calls this 
+     * method, it will not call the <code>service</code> method again
+     * on this servlet.
+     *
+     * <p>This method gives the servlet an opportunity 
+     * to clean up any resources that are being held (for example, memory,
+     * file handles, threads) and make sure that any persistent state is
+     * synchronized with the servlet's current state in memory.
+     *
+     */
+
+    public void destroy();
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletConfig.java b/javax.servlet/src/main/java/javax/servlet/ServletConfig.java
new file mode 100644
index 0000000..347720a
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletConfig.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.util.Enumeration;
+
+
+
+/**
+ * 
+ * A servlet configuration object used by a servlet container
+ * used to pass information to a servlet during initialization. 
+ *
+ */
+ 
+public interface ServletConfig {
+    
+
+    /**
+     * Returns a reference to the {@link ServletContext} in which the caller
+     * is executing.
+     *
+     *
+     * @return		a {@link ServletContext} object, used
+     *			by the caller to interact with its servlet 
+     *                  container
+     * 
+     * @see		ServletContext
+     *
+     */
+
+    public ServletContext getServletContext();
+    
+    /**
+     * Returns a <code>String</code> containing the value of the 
+     * named initialization parameter, or <code>null</code> if 
+     * the parameter does not exist.
+     *
+     * @param name	a <code>String</code> specifying the name
+     *			of the initialization parameter
+     *
+     * @return		a <code>String</code> containing the value 
+     *			of the initialization parameter
+     *
+     */
+
+    public String getInitParameter(String name);
+
+
+    /**
+     * Returns the names of the servlet's initialization parameters
+     * as an <code>Enumeration</code> of <code>String</code> objects, 
+     * or an empty <code>Enumeration</code> if the servlet has
+     * no initialization parameters.
+     *
+     * @return		an <code>Enumeration</code> of <code>String</code> 
+     *			objects containing the names of the servlet's 
+     *			initialization parameters
+     *
+     *
+     *
+     */
+
+    public Enumeration getInitParameterNames();
+
+
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletContext.java b/javax.servlet/src/main/java/javax/servlet/ServletContext.java
new file mode 100644
index 0000000..5c7b170
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletContext.java
@@ -0,0 +1,516 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+
+
+/**
+ *
+ * Defines a set of methods that a servlet uses to communicate with its
+ * servlet container, for example, to get the MIME type of a file, dispatch
+ * requests, or write to a log file.
+ *
+ * <p>There is one context per "web application" per Java Virtual Machine.  (A
+ * "web application" is a collection of servlets and content installed under a
+ * specific subset of the server's URL namespace such as <code>/catalog</code>
+ * and possibly installed via a <code>.war</code> file.)
+ *
+ * <p>In the case of a web
+ * application marked "distributed" in its deployment descriptor, there will
+ * be one context instance for each virtual machine.  In this situation, the
+ * context cannot be used as a location to share global information (because
+ * the information won't be truly global).  Use an external resource like
+ * a database instead.
+ *
+ * <p>The <code>ServletContext</code> object is contained within
+ * the {@link ServletConfig} object, which the Web server provides the
+ * servlet when the servlet is initialized.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see 	Servlet#getServletConfig
+ * @see 	ServletConfig#getServletContext
+ *
+ */
+
+public interface ServletContext {
+
+
+    /**
+     * Returns a <code>ServletContext</code> object that
+     * corresponds to a specified URL on the server.
+     *
+     * <p>This method allows servlets to gain
+     * access to the context for various parts of the server, and as
+     * needed obtain {@link RequestDispatcher} objects from the context.
+     * The given path must be begin with "/", is interpreted relative
+     * to the server's document root and is matched against the context roots of
+     * other web applications hosted on this container.
+     *
+     * <p>In a security conscious environment, the servlet container may
+     * return <code>null</code> for a given URL.
+     *
+     * @param uripath 	a <code>String</code> specifying the context path of
+     *			another web application in the container.
+     * @return		the <code>ServletContext</code> object that
+     *			corresponds to the named URL, or null if either
+			none exists or the container wishes to restrict
+     * 			this access.
+     *
+     * @see 		RequestDispatcher
+     *
+     */
+
+    public ServletContext getContext(String uripath);
+
+
+
+    /**
+     * Returns the major version of the Java Servlet API that this
+     * servlet container supports. All implementations that comply
+     * with Version 2.1 must have this method
+     * return the integer 2.
+     *
+     * @return 		2
+     *
+     */
+
+    public int getMajorVersion();
+
+
+
+    /**
+     * Returns the minor version of the Servlet API that this
+     * servlet container supports. All implementations that comply
+     * with Version 2.1 must have this method
+     * return the integer 1.
+     *
+     * @return 		1
+     *
+     */
+
+    public int getMinorVersion();
+
+
+
+    /**
+     * Returns the MIME type of the specified file, or <code>null</code> if
+     * the MIME type is not known. The MIME type is determined
+     * by the configuration of the servlet container, and may be specified
+     * in a web application deployment descriptor. Common MIME
+     * types are <code>"text/html"</code> and <code>"image/gif"</code>.
+     *
+     *
+     * @param   file    a <code>String</code> specifying the name
+     *			of a file
+     *
+     * @return 		a <code>String</code> specifying the file's MIME type
+     *
+     */
+
+    public String getMimeType(String file);
+
+    /**
+     * Returns a URL to the resource that is mapped to a specified
+     * path. The path must begin with a "/" and is interpreted
+     * as relative to the current context root.
+     *
+     * <p>This method allows the servlet container to make a resource
+     * available to servlets from any source. Resources
+     * can be located on a local or remote
+     * file system, in a database, or in a <code>.war</code> file.
+     *
+     * <p>The servlet container must implement the URL handlers
+     * and <code>URLConnection</code> objects that are necessary
+     * to access the resource.
+     *
+     * <p>This method returns <code>null</code>
+     * if no resource is mapped to the pathname.
+     *
+     * <p>Some containers may allow writing to the URL returned by
+     * this method using the methods of the URL class.
+     *
+     * <p>The resource content is returned directly, so be aware that
+     * requesting a <code>.jsp</code> page returns the JSP source code.
+     * Use a <code>RequestDispatcher</code> instead to include results of
+     * an execution.
+     *
+     * <p>This method has a different purpose than
+     * <code>java.lang.Class.getResource</code>,
+     * which looks up resources based on a class loader. This
+     * method does not use class loaders.
+     *
+     * @param path 				a <code>String</code> specifying
+     *						the path to the resource
+     *
+     * @return 					the resource located at the named path,
+     * 						or <code>null</code> if there is no resource
+     *						at that path
+     *
+     * @exception MalformedURLException 	if the pathname is not given in
+     * 						the correct form
+     *
+     */
+
+    public URL getResource(String path) throws MalformedURLException;
+
+
+
+    /**
+     * Returns the resource located at the named path as
+     * an <code>InputStream</code> object.
+     *
+     * <p>The data in the <code>InputStream</code> can be
+     * of any type or length. The path must be specified according
+     * to the rules given in <code>getResource</code>.
+     * This method returns <code>null</code> if no resource exists at
+     * the specified path.
+     *
+     * <p>Meta-information such as content length and content type
+     * that is available via <code>getResource</code>
+     * method is lost when using this method.
+     *
+     * <p>The servlet container must implement the URL handlers
+     * and <code>URLConnection</code> objects necessary to access
+     * the resource.
+     *
+     * <p>This method is different from
+     * <code>java.lang.Class.getResourceAsStream</code>,
+     * which uses a class loader. This method allows servlet containers
+     * to make a resource available
+     * to a servlet from any location, without using a class loader.
+     *
+     *
+     * @param path 	a <code>String</code> specifying the path
+     *			to the resource
+     *
+     * @return 		the <code>InputStream</code> returned to the
+     *			servlet, or <code>null</code> if no resource
+     *			exists at the specified path
+     *
+     *
+     */
+
+    public InputStream getResourceAsStream(String path);
+
+
+
+
+    /**
+     *
+     * Returns a {@link RequestDispatcher} object that acts
+     * as a wrapper for the resource located at the given path.
+     * A <code>RequestDispatcher</code> object can be used to forward
+     * a request to the resource or to include the resource in a response.
+     * The resource can be dynamic or static.
+     *
+     * <p>The pathname must begin with a "/" and is interpreted as relative
+     * to the current context root.  Use <code>getContext</code> to obtain
+     * a <code>RequestDispatcher</code> for resources in foreign contexts.
+     * This method returns <code>null</code> if the <code>ServletContext</code>
+     * cannot return a <code>RequestDispatcher</code>.
+     *
+     * @param path 	a <code>String</code> specifying the pathname
+     *			to the resource
+     *
+     * @return 		a <code>RequestDispatcher</code> object
+     *			that acts as a wrapper for the resource
+     *			at the specified path
+     *
+     * @see 		RequestDispatcher
+     * @see 		ServletContext#getContext
+     *
+     */
+
+    public RequestDispatcher getRequestDispatcher(String path);
+
+
+
+    /**
+     *
+     * @deprecated	As of Java Servlet API 2.1, with no direct replacement.
+     *
+     * <p>This method was originally defined to retrieve a servlet
+     * from a <code>ServletContext</code>. In this version, this method
+     * always returns <code>null</code> and remains only to preserve
+     * binary compatibility. This method will be permanently removed
+     * in a future version of the Java Servlet API.
+     *
+     * <p>In lieu of this method, servlets can share information using the
+     * <code>ServletContext</code> class and can perform shared business logic
+     * by invoking methods on common non-servlet classes.
+     *
+     */
+
+    public Servlet getServlet(String name) throws ServletException;
+
+
+
+
+
+
+    /**
+     *
+     * @deprecated	As of Java Servlet API 2.0, with no replacement.
+     *
+     * <p>This method was originally defined to return an <code>Enumeration</code>
+     * of all the servlets known to this servlet context. In this
+     * version, this method always returns an empty enumeration and
+     * remains only to preserve binary compatibility. This method
+     * will be permanently removed in a future version of the Java
+     * Servlet API.
+     *
+     */
+
+    public Enumeration getServlets();
+
+
+
+
+
+
+    /**
+     * @deprecated	As of Java Servlet API 2.1, with no replacement.
+     *
+     * <p>This method was originally defined to return an
+     * <code>Enumeration</code>
+     * of all the servlet names known to this context. In this version,
+     * this method always returns an empty <code>Enumeration</code> and
+     * remains only to preserve binary compatibility. This method will
+     * be permanently removed in a future version of the Java Servlet API.
+     *
+     */
+
+    public Enumeration getServletNames();
+
+
+
+
+
+    /**
+     *
+     * Writes the specified message to a servlet log file, usually
+     * an event log. The name and type of the servlet log file is
+     * specific to the servlet container.
+     *
+     *
+     * @param msg 	a <code>String</code> specifying the
+     *			message to be written to the log file
+     *
+     */
+
+    public void log(String msg);
+
+
+
+
+
+    /**
+     * @deprecated	As of Java Servlet API 2.1, use
+     * 			{@link #log(String message, Throwable throwable)}
+     *			instead.
+     *
+     * <p>This method was originally defined to write an
+     * exception's stack trace and an explanatory error message
+     * to the servlet log file.
+     *
+     */
+
+    public void log(Exception exception, String msg);
+
+
+
+
+
+    /**
+     * Writes an explanatory message and a stack trace
+     * for a given <code>Throwable</code> exception
+     * to the servlet log file. The name and type of the servlet log
+     * file is specific to the servlet container, usually an event log.
+     *
+     *
+     * @param message 		a <code>String</code> that
+     *				describes the error or exception
+     *
+     * @param throwable 	the <code>Throwable</code> error
+     *				or exception
+     *
+     */
+
+    public void log(String message, Throwable throwable);
+
+
+
+
+
+    /**
+     * Returns a <code>String</code> containing the real path
+     * for a given virtual path. For example, the path "/index.html"
+     * returns the absolute file path on the server's filesystem would be
+     * served by a request for "http://host/contextPath/index.html",
+     * where contextPath is the context path of this ServletContext..
+     *
+     * <p>The real path returned will be in a form
+     * appropriate to the computer and operating system on
+     * which the servlet container is running, including the
+     * proper path separators. This method returns <code>null</code>
+     * if the servlet container cannot translate the virtual path
+     * to a real path for any reason (such as when the content is
+     * being made available from a <code>.war</code> archive).
+     *
+     *
+     * @param path 	a <code>String</code> specifying a virtual path
+     *
+     *
+     * @return 		a <code>String</code> specifying the real path,
+     *                  or null if the translation cannot be performed
+     *			
+     *
+     */
+
+    public String getRealPath(String path);
+
+
+
+
+    /**
+     * Returns the name and version of the servlet container on which
+     * the servlet is running.
+     *
+     * <p>The form of the returned string is
+     * <i>servername</i>/<i>versionnumber</i>.
+     * For example, the JavaServer Web Development Kit may return the string
+     * <code>JavaServer Web Dev Kit/1.0</code>.
+     *
+     * <p>The servlet container may return other optional information
+     * after the primary string in parentheses, for example,
+     * <code>JavaServer Web Dev Kit/1.0 (JDK 1.1.6; Windows NT 4.0 x86)</code>.
+     *
+     *
+     * @return 		a <code>String</code> containing at least the
+     *			servlet container name and version number
+     *
+     */
+
+    public String getServerInfo();
+
+
+
+
+    /**
+     * Returns the servlet container attribute with the given name,
+     * or <code>null</code> if there is no attribute by that name.
+     * An attribute allows a servlet container to give the
+     * servlet additional information not
+     * already provided by this interface. See your
+     * server documentation for information about its attributes.
+     * A list of supported attributes can be retrieved using
+     * <code>getAttributeNames</code>.
+     *
+     * <p>The attribute is returned as a <code>java.lang.Object</code>
+     * or some subclass.
+     * Attribute names should follow the same convention as package
+     * names. The Java Servlet API specification reserves names
+     * matching <code>java.*</code>, <code>javax.*</code>,
+     * and <code>sun.*</code>.
+     *
+     *
+     * @param name 	a <code>String</code> specifying the name
+     *			of the attribute
+     *
+     * @return 		an <code>Object</code> containing the value
+     *			of the attribute, or <code>null</code>
+     *			if no attribute exists matching the given
+     *			name
+     *
+     * @see 		ServletContext#getAttributeNames
+     *
+     */
+
+    public Object getAttribute(String name);
+
+
+
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * attribute names available
+     * within this servlet context. Use the
+     * {@link #getAttribute} method with an attribute name
+     * to get the value of an attribute.
+     *
+     * @return 		an <code>Enumeration</code> of attribute
+     *			names
+     *
+     * @see		#getAttribute
+     *
+     */
+
+    public Enumeration getAttributeNames();
+
+
+
+
+    /**
+     *
+     * Binds an object to a given attribute name in this servlet context. If
+     * the name specified is already used for an attribute, this
+     * method will replace the attribute with the new to the new attribute.
+     *
+     * <p>Attribute names should follow the same convention as package
+     * names. The Java Servlet API specification reserves names
+     * matching <code>java.*</code>, <code>javax.*</code>, and
+     * <code>sun.*</code>.
+     *
+     *
+     * @param name 	a <code>String</code> specifying the name
+     *			of the attribute
+     *
+     * @param object 	an <code>Object</code> representing the
+     *			attribute to be bound
+     *
+     *
+     *
+     */
+
+    public void setAttribute(String name, Object object);
+
+
+
+
+
+    /**
+     * Removes the attribute with the given name from
+     * the servlet context. After removal, subsequent calls to
+     * {@link #getAttribute} to retrieve the attribute's value
+     * will return <code>null</code>.
+     *
+     *
+     * @param name	a <code>String</code> specifying the name
+     * 			of the attribute to be removed
+     *
+     */
+
+    public void removeAttribute(String name);
+}
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletException.java b/javax.servlet/src/main/java/javax/servlet/ServletException.java
new file mode 100644
index 0000000..b442440
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletException.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+
+/**
+ * Defines a general exception a servlet can throw when it
+ * encounters difficulty.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ */
+
+
+public class ServletException extends Exception {
+
+    private Throwable rootCause;
+
+
+
+
+
+    /**
+     * Constructs a new servlet exception.
+     *
+     */
+
+    public ServletException() {
+	super();
+    }
+    
+   
+
+    
+
+    /**
+     * Constructs a new servlet exception with the
+     * specified message. The message can be written 
+     * to the server log and/or displayed for the user. 
+     *
+     * @param message 		a <code>String</code> 
+     *				specifying the text of 
+     *				the exception message
+     *
+     */
+
+    public ServletException(String message) {
+	super(message);
+    }
+    
+   
+   
+    
+
+    /**
+     * Constructs a new servlet exception when the servlet 
+     * needs to throw an exception and include a message 
+     * about the "root cause" exception that interfered with its 
+     * normal operation, including a description message.
+     *
+     *
+     * @param message 		a <code>String</code> containing 
+     *				the text of the exception message
+     *
+     * @param rootCause		the <code>Throwable</code> exception 
+     *				that interfered with the servlet's
+     *				normal operation, making this servlet
+     *				exception necessary
+     *
+     */
+    
+    public ServletException(String message, Throwable rootCause) {
+       super(message);
+       this.rootCause = rootCause;
+    }
+
+
+
+
+
+    /**
+     * Constructs a new servlet exception when the servlet 
+     * needs to throw an exception and include a message
+     * about the "root cause" exception that interfered with its
+     * normal operation.  The exception's message is based on the localized
+     * message of the underlying exception.
+     *
+     * <p>This method calls the <code>getLocalizedMessage</code> method
+     * on the <code>Throwable</code> exception to get a localized exception
+     * message. When subclassing <code>ServletException</code>, 
+     * this method can be overridden to create an exception message 
+     * designed for a specific locale.
+     *
+     * @param rootCause 	the <code>Throwable</code> exception
+     * 				that interfered with the servlet's
+     *				normal operation, making the servlet exception
+     *				necessary
+     *
+     */
+
+    public ServletException(Throwable rootCause) {
+       super(rootCause.getLocalizedMessage());
+       this.rootCause = rootCause;
+    }
+  
+  
+ 
+ 
+    
+    /**
+     * Returns the exception that caused this servlet exception.
+     *
+     *
+     * @return			the <code>Throwable</code> 
+     *				that caused this servlet exception
+     *
+     */
+    
+    public Throwable getRootCause() {
+	return rootCause;
+    }
+}
+
+
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletInputStream.java b/javax.servlet/src/main/java/javax/servlet/ServletInputStream.java
new file mode 100644
index 0000000..ba3ac20
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletInputStream.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * 
+ * Provides an input stream for reading binary data from a client
+ * request, including an efficient <code>readLine</code> method
+ * for reading data one line at a time. With some protocols, such
+ * as HTTP POST and PUT, a <code>ServletInputStream</code>
+ * object can be used to read data sent from the client.
+ *
+ * <p>A <code>ServletInputStream</code> object is normally retrieved via
+ * the {@link ServletRequest#getInputStream} method.
+ *
+ *
+ * <p>This is an abstract class that a servlet container implements.
+ * Subclasses of this class
+ * must implement the <code>java.io.InputStream.read()</code> method.
+ *
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see		ServletRequest 
+ *
+ */
+
+public abstract class ServletInputStream extends InputStream {
+
+
+
+    /**
+     * Does nothing, because this is an abstract class.
+     *
+     */
+
+    protected ServletInputStream() { }
+
+  
+  
+    
+    /**
+     *
+     * Reads the input stream, one line at a time. Starting at an
+     * offset, reads bytes into an array, until it reads a certain number
+     * of bytes or reaches a newline character, which it reads into the
+     * array as well.
+     *
+     * <p>This method returns -1 if it reaches the end of the input
+     * stream before reading the maximum number of bytes.
+     *
+     *
+     *
+     * @param b 		an array of bytes into which data is read
+     *
+     * @param off 		an integer specifying the character at which
+     *				this method begins reading
+     *
+     * @param len		an integer specifying the maximum number of 
+     *				bytes to read
+     *
+     * @return			an integer specifying the actual number of bytes 
+     *				read, or -1 if the end of the stream is reached
+     *
+     * @exception IOException	if an input or output exception has occurred
+     *
+     */
+     
+    public int readLine(byte[] b, int off, int len) throws IOException {
+
+	if (len <= 0) {
+	    return 0;
+	}
+	int count = 0, c;
+
+	while ((c = read()) != -1) {
+	    b[off++] = (byte)c;
+	    count++;
+	    if (c == '\n' || count == len) {
+		break;
+	    }
+	}
+	return count > 0 ? count : -1;
+    }
+}
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletOutputStream.java b/javax.servlet/src/main/java/javax/servlet/ServletOutputStream.java
new file mode 100644
index 0000000..c29e7cf
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletOutputStream.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.CharConversionException;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * Provides an output stream for sending binary data to the
+ * client. A <code>ServletOutputStream</code> object is normally retrieved 
+ * via the {@link ServletResponse#getOutputStream} method.
+ *
+ * <p>This is an abstract class that the servlet container implements.
+ * Subclasses of this class
+ * must implement the <code>java.io.OutputStream.write(int)</code>
+ * method.
+ *
+ * 
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see 	ServletResponse
+ *
+ */
+
+public abstract class ServletOutputStream extends OutputStream {
+
+    private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
+    private static ResourceBundle lStrings =
+	ResourceBundle.getBundle(LSTRING_FILE);
+
+
+    
+    /**
+     *
+     * Does nothing, because this is an abstract class.
+     *
+     */
+
+    protected ServletOutputStream() { }
+
+
+    /**
+     * Writes a <code>String</code> to the client, 
+     * without a carriage return-line feed (CRLF) 
+     * character at the end.
+     *
+     *
+     * @param s			the <code>String</code to send to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void print(String s) throws IOException {
+	if (s==null) s="null";
+	int len = s.length();
+	for (int i = 0; i < len; i++) {
+	    char c = s.charAt (i);
+
+	    //
+	    // XXX NOTE:  This is clearly incorrect for many strings,
+	    // but is the only consistent approach within the current
+	    // servlet framework.  It must suffice until servlet output
+	    // streams properly encode their output.
+	    //
+	    if ((c & 0xff00) != 0) {	// high order byte must be zero
+		String errMsg = lStrings.getString("err.not_iso8859_1");
+		Object[] errArgs = new Object[1];
+		errArgs[0] = new Character(c);
+		errMsg = MessageFormat.format(errMsg, errArgs);
+		throw new CharConversionException(errMsg);
+	    }
+	    write (c);
+	}
+    }
+
+
+
+    /**
+     * Writes a <code>boolean</code> value to the client,
+     * with no carriage return-line feed (CRLF) 
+     * character at the end.
+     *
+     * @param b			the <code>boolean</code> value 
+     *				to send to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void print(boolean b) throws IOException {
+	String msg;
+	if (b) {
+	    msg = lStrings.getString("value.true");
+	} else {
+	    msg = lStrings.getString("value.false");
+	}
+	print(msg);
+    }
+
+
+
+    /**
+     * Writes a character to the client,
+     * with no carriage return-line feed (CRLF) 
+     * at the end.
+     *
+     * @param c			the character to send to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void print(char c) throws IOException {
+	print(String.valueOf(c));
+    }
+
+
+
+
+    /**
+     *
+     * Writes an int to the client,
+     * with no carriage return-line feed (CRLF) 
+     * at the end.
+     *
+     * @param i			the int to send to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */  
+
+    public void print(int i) throws IOException {
+	print(String.valueOf(i));
+    }
+
+
+
+ 
+    /**
+     * 
+     * Writes a <code>long</code> value to the client,
+     * with no carriage return-line feed (CRLF) at the end.
+     *
+     * @param l			the <code>long</code> value 
+     *				to send to the client
+     *
+     * @exception IOException 	if an input or output exception 
+     *				occurred
+     * 
+     */
+
+    public void print(long l) throws IOException {
+	print(String.valueOf(l));
+    }
+
+
+
+    /**
+     *
+     * Writes a <code>float</code> value to the client,
+     * with no carriage return-line feed (CRLF) at the end.
+     *
+     * @param f			the <code>float</code> value
+     *				to send to the client
+     *
+     * @exception IOException	if an input or output exception occurred
+     *
+     *
+     */
+
+    public void print(float f) throws IOException {
+	print(String.valueOf(f));
+    }
+
+
+
+    /**
+     *
+     * Writes a <code>double</code> value to the client,
+     * with no carriage return-line feed (CRLF) at the end.
+     * 
+     * @param d			the <code>double</code> value
+     *				to send to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void print(double d) throws IOException {
+	print(String.valueOf(d));
+    }
+
+
+
+    /**
+     * Writes a carriage return-line feed (CRLF)
+     * to the client.
+     *
+     *
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println() throws IOException {
+	print("\r\n");
+    }
+
+
+
+    /**
+     * Writes a <code>String</code> to the client, 
+     * followed by a carriage return-line feed (CRLF).
+     *
+     *
+     * @param s			the </code>String</code> to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println(String s) throws IOException {
+	print(s);
+	println();
+    }
+
+
+
+
+    /**
+     *
+     * Writes a <code>boolean</code> value to the client, 
+     * followed by a 
+     * carriage return-line feed (CRLF).
+     *
+     *
+     * @param b			the <code>boolean</code> value 
+     *				to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println(boolean b) throws IOException {
+	print(b);
+	println();
+    }
+
+
+
+    /**
+     *
+     * Writes a character to the client, followed by a carriage
+     * return-line feed (CRLF).
+     *
+     * @param c			the character to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println(char c) throws IOException {
+	print(c);
+	println();
+    }
+
+
+
+    /**
+     *
+     * Writes an int to the client, followed by a 
+     * carriage return-line feed (CRLF) character.
+     *
+     *
+     * @param i			the int to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println(int i) throws IOException {
+	print(i);
+	println();
+    }
+
+
+
+    /**  
+     *
+     * Writes a <code>long</code> value to the client, followed by a 
+     * carriage return-line feed (CRLF).
+     *
+     *
+     * @param l			the <code>long</code> value to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */  
+
+    public void println(long l) throws IOException {
+	print(l);
+	println();
+    }
+
+
+
+    /**
+     *
+     * Writes a <code>float</code> value to the client, 
+     * followed by a carriage return-line feed (CRLF).
+     *
+     * @param f			the <code>float</code> value 
+     *				to write to the client
+     *
+     *
+     * @exception IOException 	if an input or output exception 
+     *				occurred
+     *
+     */
+
+    public void println(float f) throws IOException {
+	print(f);
+	println();
+    }
+
+
+
+    /**
+     *
+     * Writes a <code>double</code> value to the client, 
+     * followed by a carriage return-line feed (CRLF).
+     *
+     *
+     * @param d			the <code>double</code> value
+     *				to write to the client
+     *
+     * @exception IOException 	if an input or output exception occurred
+     *
+     */
+
+    public void println(double d) throws IOException {
+	print(d);
+	println();
+    }
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletRequest.java b/javax.servlet/src/main/java/javax/servlet/ServletRequest.java
new file mode 100644
index 0000000..039c222
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletRequest.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Enumeration;
+
+
+
+/**
+ * Defines an object to provide client request information to a servlet.  The
+ * servlet container creates a <code>ServletRequest</code> object and passes
+ * it as an argument to the servlet's <code>service</code> method.
+ *
+ * <p>A <code>ServletRequest</code> object provides data including
+ * parameter name and values, attributes, and an input stream.
+ * Interfaces that extend <code>ServletRequest</code> can provide
+ * additional protocol-specific data (for example, HTTP data is
+ * provided by {@link javax.servlet.http.HttpServletRequest}.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see 	javax.servlet.http.HttpServletRequest
+ *
+ */
+
+public interface ServletRequest {
+
+
+
+
+    /**
+     *
+     * Returns the value of the named attribute as an <code>Object</code>,
+     * or <code>null</code> if no attribute of the given name exists.
+     *
+     * <p> Attributes can be set two ways.  The servlet container may set
+     * attributes to make available custom information about a request.
+     * For example, for requests made using HTTPS, the attribute
+     * <code>javax.servlet.request.X509Certificate</code> can be used to
+     * retrieve information on the certificate of the client.  Attributes
+     * can also be set programatically using
+     * {@link ServletRequest#setAttribute}.  This allows information to be
+     * embedded into a request before a {@link RequestDispatcher} call.
+     *
+     * <p>Attribute names should follow the same conventions as package
+     * names. This specification reserves names matching <code>java.*</code>,
+     * <code>javax.*</code>, and <code>sun.*</code>.
+     *
+     * @param name	a <code>String</code> specifying the name of
+     *			the attribute
+     *
+     * @return		an <code>Object</code> containing the value
+     *			of the attribute, or <code>null</code> if
+     *			the attribute does not exist
+     *
+     */
+
+    public Object getAttribute(String name);
+
+
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * names of the attributes available to this request.
+     * This method returns an empty <code>Enumeration</code>
+     * if the request has no attributes available to it.
+     *
+     *
+     * @return		an <code>Enumeration</code> of strings
+     *			containing the names
+     * 			of the request's attributes
+     *
+     */
+
+    public Enumeration getAttributeNames();
+
+
+
+
+    /**
+	 * Returns the name of the character encoding used in the body of this
+	 * request. This method returns <code>null</code> if the request
+	 * does not specify a character encoding
+	 *
+	 *
+	 * @return		a <code>String</code> containing the name of
+	 *			the chararacter encoding, or <code>null</code>
+	 *			if the request does not specify a character encoding
+	 *
+	 */
+	
+	public String getCharacterEncoding();
+
+
+
+	/**
+     * Returns the length, in bytes, of the request body
+     * and made available by the input stream, or -1 if the
+     * length is not known. For HTTP servlets, same as the value
+     * of the CGI variable CONTENT_LENGTH.
+     *
+     * @return		an integer containing the length of the
+     * 			request body or -1 if the length is not known
+     *
+     */
+
+    public int getContentLength();
+
+
+
+
+    /**
+     * Returns the MIME type of the body of the request, or
+     * <code>null</code> if the type is not known. For HTTP servlets,
+     * same as the value of the CGI variable CONTENT_TYPE.
+     *
+     * @return		a <code>String</code> containing the name
+     *			of the MIME type of
+     * 			the request, or null if the type is not known
+     *
+     */
+
+    public String getContentType();
+
+
+
+
+    /**
+     * Retrieves the body of the request as binary data using
+     * a {@link ServletInputStream}.  Either this method or
+     * {@link #getReader} may be called to read the body, not both.
+     *
+     * @return			a {@link ServletInputStream} object containing
+     * 				the body of the request
+     *
+     * @exception IllegalStateException  if the {@link #getReader} method
+     * 					 has already been called for this request
+     *
+     * @exception IOException    	if an input or output exception occurred
+     *
+     */
+
+    public ServletInputStream getInputStream() throws IOException;
+
+
+
+
+    /**
+     * Returns the value of a request parameter as a <code>String</code>,
+     * or <code>null</code> if the parameter does not exist. Request parameters
+     * are extra information sent with the request.  For HTTP servlets,
+     * parameters are contained in the query string or posted form data.
+     *
+     * <p>You should only use this method when you are sure the
+     * parameter has only one value. If the parameter might have
+     * more than one value, use {@link #getParameterValues}.
+     *
+     * <p>If you use this method with a multivalued
+     * parameter, the value returned is equal to the first value
+     * in the array returned by <code>getParameterValues</code>.
+     *
+     * <p>If the parameter data was sent in the request body, such as occurs
+     * with an HTTP POST request, then reading the body directly via {@link
+     * #getInputStream} or {@link #getReader} can interfere
+     * with the execution of this method.
+     *
+     * @param name 	a <code>String</code> specifying the
+     *			name of the parameter
+     *
+     * @return		a <code>String</code> representing the
+     *			single value of the parameter
+     *
+     * @see 		#getParameterValues
+     *
+     */
+
+    public String getParameter(String name);
+
+
+
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code>
+     * objects containing the names of the parameters contained
+     * in this request. If the request has
+     * no parameters, the method returns an
+     * empty <code>Enumeration</code>.
+     *
+     * @return		an <code>Enumeration</code> of <code>String</code>
+     *			objects, each <code>String</code> containing
+     * 			the name of a request parameter; or an
+     *			empty <code>Enumeration</code> if the
+     *			request has no parameters
+     *
+     */
+
+    public Enumeration getParameterNames();
+
+
+
+
+    /**
+     * Returns an array of <code>String</code> objects containing
+     * all of the values the given request parameter has, or
+     * <code>null</code> if the parameter does not exist.
+     *
+     * <p>If the parameter has a single value, the array has a length
+     * of 1.
+     *
+     * @param name	a <code>String</code> containing the name of
+     *			the parameter whose value is requested
+     *
+     * @return		an array of <code>String</code> objects
+     *			containing the parameter's values
+     *
+     * @see		#getParameter
+     *
+     */
+
+    public String[] getParameterValues(String name);
+
+    /**
+     * Returns the name and version of the protocol the request uses
+     * in the form <i>protocol/majorVersion.minorVersion</i>, for
+     * example, HTTP/1.1. For HTTP servlets, the value
+     * returned is the same as the value of the CGI variable
+     * <code>SERVER_PROTOCOL</code>.
+     *
+     * @return		a <code>String</code> containing the protocol
+     *			name and version number
+     *
+     */
+
+    public String getProtocol();
+
+
+
+
+    /**
+     * Returns the name of the scheme used to make this request,
+     * for example,
+     * <code>http</code>, <code>https</code>, or <code>ftp</code>.
+     * Different schemes have different rules for constructing URLs,
+     * as noted in RFC 1738.
+     *
+     * @return		a <code>String</code> containing the name
+     *			of the scheme used to make this request
+     *
+     */
+
+    public String getScheme();
+
+
+
+
+    /**
+     * Returns the host name of the server that received the request.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_NAME</code>.
+     *
+     * @return		a <code>String</code> containing the name
+     *			of the server to which the request was sent
+     */
+
+    public String getServerName();
+
+
+
+
+    /**
+     * Returns the port number on which this request was received.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_PORT</code>.
+     *
+     * @return		an integer specifying the port number
+     *
+     */
+
+    public int getServerPort();
+
+
+
+    /**
+     * Retrieves the body of the request as character data using
+     * a <code>BufferedReader</code>.  The reader translates the character
+     * data according to the character encoding used on the body.
+     * Either this method or {@link #getInputStream} may be called to read the
+     * body, not both.
+     *
+     *
+     * @return					a <code>BufferedReader</code>
+     *						containing the body of the request	
+     *
+     * @exception IllegalStateException   	if {@link #getInputStream} method
+     * 						has been called on this request
+     *
+     * @exception IOException  			if an input or output exception occurred
+     *
+     * @see 					#getInputStream
+     *
+     */
+
+    public BufferedReader getReader() throws IOException;
+
+
+
+
+    /**
+     * Returns the Internet Protocol (IP) address of the client
+     * that sent the request.  For HTTP servlets, same as the value of the
+     * CGI variable <code>REMOTE_ADDR</code>.
+     *
+     * @return		a <code>String</code> containing the
+     *			IP address of the client that sent the request
+     *
+     */
+
+    public String getRemoteAddr();
+
+
+
+
+    /**
+     * Returns the fully qualified name of the client that sent the
+     * request. If the engine cannot or chooses not to resolve the hostname
+     * (to improve performance), this method returns the dotted-string form of
+     * the IP address. For HTTP servlets, same as the value of the CGI variable
+     * <code>REMOTE_HOST</code>.
+     *
+     * @return		a <code>String</code> containing the fully
+     * qualified name of the client
+     *
+     */
+
+    public String getRemoteHost();
+
+
+
+
+    /**
+     *
+     * Stores an attribute in this request.
+     * Attributes are reset between requests.  This method is most
+     * often used in conjunction with {@link RequestDispatcher}.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name			a <code>String</code> specifying
+     *					the name of the attribute
+     *
+     * @param o				the <code>Object</code> to be stored
+     *
+     */
+
+    public void setAttribute(String name, Object o);
+
+
+
+
+    /**
+     *
+     * @deprecated 	As of Version 2.1 of the Java Servlet API,
+     * 			use {@link ServletContext#getRealPath} instead.
+     *
+     */
+
+    public String getRealPath(String path);
+
+
+}
+
diff --git a/javax.servlet/src/main/java/javax/servlet/ServletResponse.java b/javax.servlet/src/main/java/javax/servlet/ServletResponse.java
new file mode 100644
index 0000000..e658b45
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/ServletResponse.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+import java.io.*;
+
+
+/**
+ * Defines an object to assist a servlet in sending a response to the client.
+ * The servlet container creates a <code>ServletResponse</code> object and
+ * passes it as an argument to the servlet's <code>service</code> method.
+ *
+ * <p>To send binary data in a MIME body response, use
+ * the {@link ServletOutputStream} returned by {@link #getOutputStream}.
+ * To send character data, use the <code>PrintWriter</code> object 
+ * returned by {@link #getWriter}. To mix binary and text data,
+ * for example, to create a multipart response, use a
+ * <code>ServletOutputStream</code> and manage the character sections
+ * manually.
+ *
+ * <p>The charset for the MIME body response can be specified with 
+ * {@link #setContentType}.  For example, "text/html; charset=Shift_JIS".
+ * If no charset is specified, ISO-8859-1 will be used.  
+ * The <code>setContentType</code> or <code>setLocale</code> method 
+ * must be called before <code>getWriter</code> for the charset to 
+ * affect the construction of the writer.
+ * 
+ * <p>See the Internet RFCs such as 
+ * <a href="http://info.internet.isi.edu/in-notes/rfc/files/rfc2045.txt">
+ * RFC 2045</a> for more information on MIME. Protocols such as SMTP
+ * and HTTP define profiles of MIME, and those standards
+ * are still evolving.
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ * @see		ServletOutputStream
+ *
+ */
+ 
+public interface ServletResponse {
+
+
+    
+    /**
+     * Returns the name of the charset used for
+     * the MIME body sent in this response.
+     *
+     * <p>If no charset has been assigned, it is implicitly
+     * set to <code>ISO-8859-1</code> (<code>Latin-1</code>).
+     *
+     * <p>See RFC 2047 (http://ds.internic.net/rfc/rfc2045.txt)
+     * for more information about character encoding and MIME.
+     *
+     * @return		a <code>String</code> specifying the
+     *			name of the charset, for
+     *			example, <code>ISO-8859-1</code>
+     *
+     */
+  
+    public String getCharacterEncoding();
+    
+    
+
+    /**
+     * Returns a {@link ServletOutputStream} suitable for writing binary 
+     * data in the response. The servlet container does not encode the
+     * binary data.  
+     
+     * <p> Calling flush() on the ServletOutputStream commits the response.
+     
+     * Either this method or {@link #getWriter} may 
+     * be called to write the body, not both.
+     *
+     * @return				a {@link ServletOutputStream} for writing binary data	
+     *
+     * @exception IllegalStateException if the <code>getWriter</code> method
+     * 					has been called on this response
+     *
+     * @exception IOException 		if an input or output exception occurred
+     *
+     * @see 				#getWriter
+     *
+     */
+
+    public ServletOutputStream getOutputStream() throws IOException;
+    
+    
+
+    /**
+     * Returns a <code>PrintWriter</code> object that 
+     * can send character text to the client. 
+     * The character encoding used is the one specified 
+     * in the <code>charset=</code> property of the
+     * {@link #setContentType} method, which must be called
+     * <i>before</i> calling this method for the charset to take effect. 
+     *
+     * <p>If necessary, the MIME type of the response is 
+     * modified to reflect the character encoding used.
+     *
+     * <p> Calling flush() on the PrintWriter commits the response.
+     *
+     * <p>Either this method or {@link #getOutputStream} may be called
+     * to write the body, not both.
+     *
+     * 
+     * @return 				a <code>PrintWriter</code> object that 
+     *					can return character data to the client 
+     *
+     * @exception UnsupportedEncodingException  if the charset specified in
+     *						<code>setContentType</code> cannot be
+     *						used
+     *
+     * @exception IllegalStateException    	if the <code>getOutputStream</code>
+     * 						method has already been called for this 
+     *						response object
+     *
+     * @exception IOException   		if an input or output exception occurred
+     *
+     * @see 					#getOutputStream
+     * @see 					#setContentType
+     *
+     */
+
+    public PrintWriter getWriter() throws IOException;
+    
+    
+    
+    
+
+    /**
+     * Sets the length of the content body in the response
+     * In HTTP servlets, this method sets the HTTP Content-Length header.
+     *
+     *
+     * @param len 	an integer specifying the length of the 
+     * 			content being returned to the client; sets
+     *			the Content-Length header
+     *
+     */
+
+    public void setContentLength(int len);
+    
+    
+
+    /**
+     * Sets the content type of the response being sent to
+     * the client. The content type may include the type of character
+     * encoding used, for example, <code>text/html; charset=ISO-8859-4</code>.
+     *
+     * <p>If obtaining a <code>PrintWriter</code>, this method should be 
+     * called first.
+     *
+     *
+     * @param type 	a <code>String</code> specifying the MIME 
+     *			type of the content
+     *
+     * @see 		#getOutputStream
+     * @see 		#getWriter
+     *
+     */
+
+    public void setContentType(String type);
+
+
+
+}
+
+
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/SingleThreadModel.java b/javax.servlet/src/main/java/javax/servlet/SingleThreadModel.java
new file mode 100644
index 0000000..14b54fd
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/SingleThreadModel.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+/**
+ * Ensures that servlets handle
+ * only one request at a time. This interface has no methods.
+ *
+ * <p>If a servlet implements this interface, you are <i>guaranteed</i>
+ * that no two threads will execute concurrently in the
+ * servlet's <code>service</code> method. The servlet container
+ * can make this guarantee by synchronizing access to a single
+ * instance of the servlet, or by maintaining a pool of servlet
+ * instances and dispatching each new request to a free servlet.
+ *
+ * <p>This interface does not prevent
+ * synchronization problems that result from servlets accessing shared
+ * resources such as static class variables or classes outside
+ * the scope of the servlet.
+ *
+ *
+ * @author	Various
+ * @version	$Version$
+ *
+ */
+
+public interface SingleThreadModel {
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/UnavailableException.java b/javax.servlet/src/main/java/javax/servlet/UnavailableException.java
new file mode 100644
index 0000000..3ea2d57
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/UnavailableException.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 1999,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 javax.servlet;
+
+
+/**
+ * Defines an exception that a servlet throws to indicate
+ * that it is permanently or temporarily unavailable.
+ *
+ * <p>When a servlet is permanently unavailable, something is wrong
+ * with the servlet, and it cannot handle
+ * requests until some action is taken. For example, the servlet
+ * might be configured incorrectly, or its state may be corrupted.
+ * A servlet should log both the error and the corrective action
+ * that is needed.
+ *
+ * <p>A servlet is temporarily unavailable if it cannot handle
+ * requests momentarily due to some system-wide problem. For example,
+ * a third-tier server might not be accessible, or there may be
+ * insufficient memory or disk storage to handle requests. A system
+ * administrator may need to take corrective action.
+ *
+ * <p>Servlet containers can safely treat both types of unavailable
+ * exceptions in the same way. However, treating temporary unavailability
+ * effectively makes the servlet container more robust. Specifically,
+ * the servlet container might block requests to the servlet for a period
+ * of time suggested by the exception, rather than rejecting them until
+ * the servlet container restarts.
+ *
+ *
+ * @author 	Various
+ * @version 	$Version$
+ *
+ */
+
+public class UnavailableException
+extends ServletException {
+
+    private Servlet     servlet;           // what's unavailable
+    private boolean     permanent;         // needs admin action?
+    private int         seconds;           // unavailability estimate
+
+    /**
+     *
+     * @param servlet 	the <code>Servlet</code> instance that is
+     *                  unavailable
+     *
+     * @param msg 	a <code>String</code> specifying the
+     *                  descriptive message
+     *
+     */
+
+    public UnavailableException(Servlet servlet, String msg) {
+	super(msg);
+	this.servlet = servlet;
+	permanent = true;
+    }
+
+    /**
+     *
+     * @param seconds	an integer specifying the number of seconds
+     * 			the servlet expects to be unavailable; if
+     *			zero or negative, indicates that the servlet
+     *			can't make an estimate
+     *
+     * @param servlet	the <code>Servlet</code> that is unavailable
+     *
+     * @param msg	a <code>String</code> specifying the descriptive
+     *			message, which can be written to a log file or
+     *			displayed for the user.
+     *
+     */
+
+    public UnavailableException(int seconds, Servlet servlet, String msg) {
+	super(msg);
+	this.servlet = servlet;
+	if (seconds <= 0)
+	    this.seconds = -1;
+	else
+	    this.seconds = seconds;
+	permanent = false;
+    }
+
+    /**
+     *
+     * Returns a <code>boolean</code> indicating
+     * whether the servlet is permanently unavailable.
+     * If so, something is wrong with the servlet, and the
+     * system administrator must take some corrective action.
+     *
+     * @return		<code>true</code> if the servlet is
+     *			permanently unavailable; <code>false</code>
+     *			if the servlet is available or temporarily
+     *			unavailable
+     *
+     */
+
+    public boolean isPermanent() {
+	return permanent;
+    }
+
+    /**
+     *
+     * Returns the servlet that is reporting its unavailability.
+     *
+     * @return		the <code>Servlet</code> object that is
+     *			throwing the <code>UnavailableException</code>
+     *
+     */
+
+    public Servlet getServlet() {
+	return servlet;
+    }
+
+    /**
+     * Returns the number of seconds the servlet expects to
+     * be temporarily unavailable.
+     *
+     * <p>If this method returns a negative number, the servlet
+     * is permanently unavailable or cannot provide an estimate of
+     * how long it will be unavailable. No effort is
+     * made to correct for the time elapsed since the exception was
+     * first reported.
+     *
+     * @return		an integer specifying the number of seconds
+     *			the servlet will be temporarily unavailable,
+     *			or a negative number if the servlet is permanently
+     *			unavailable or cannot make an estimate
+     *
+     */
+
+    public int getUnavailableSeconds() {
+	return permanent ? -1 : seconds;
+    }
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/http/Cookie.java b/javax.servlet/src/main/java/javax/servlet/http/Cookie.java
new file mode 100644
index 0000000..baeac67
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/Cookie.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to 
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely 
+ * identify a client, so cookies are commonly used for session management.
+ * 
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the 
+ * optional attributes, so use them sparingly to improve the interoperability 
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link HttpServletResponse#addCookie} method, which adds
+ * fields to HTTP response headers to send cookies to the 
+ * browser, one at a time. The browser is expected to 
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ * 
+ * <p>The browser returns cookies to the servlet by adding 
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link HttpServletRequest#getCookies} method.
+ * Several cookies might have the same name but different path attributes.
+ * 
+ * <p>Cookies affect the caching of the Web pages that use them. 
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1 
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @author	Various
+ * @version	$Version$
+ *
+ */
+
+// XXX would implement java.io.Serializable too, but can't do that
+// so long as sun.servlet.* must run on older JDK 1.02 JVMs which
+// don't include that support.
+
+public class Cookie implements Cloneable {
+
+    private static final String LSTRING_FILE =
+	"javax.servlet.http.LocalStrings";
+    private static ResourceBundle lStrings =
+	ResourceBundle.getBundle(LSTRING_FILE);
+    
+    //
+    // The value of the cookie itself.
+    //
+    
+    private String name;	// NAME= ... "$Name" style is reserved
+    private String value;	// value of NAME
+
+    //
+    // Attributes encoded in the header's cookie fields.
+    //
+    
+    private String comment;	// ;Comment=VALUE ... describes cookie's use
+				// ;Discard ... implied by maxAge < 0
+    private String domain;	// ;Domain=VALUE ... domain that sees cookie
+    private int maxAge = -1;	// ;Max-Age=VALUE ... cookies auto-expire
+    private String path;	// ;Path=VALUE ... URLs that see the cookie
+    private boolean secure;	// ;Secure ... e.g. use SSL
+    private int version = 0;	// ;Version=1 ... means RFC 2109++ style
+    
+    
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p>The name must conform to RFC 2109. That means it can contain 
+     * only ASCII alphanumeric characters and cannot contain commas, 
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p>The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * <code>setValue</code> method.
+     *
+     * <p>By default, cookies are created according to the Netscape
+     * cookie specification. The version can be changed with the 
+     * <code>setVersion</code> method.
+     *
+     *
+     * @param name 			a <code>String</code> specifying the name of the cookie
+     *
+     * @param value			a <code>String</code> specifying the value of the cookie
+     *
+     * @throws IllegalArgumentException	if the cookie name contains illegal characters
+     *					(for example, a comma, space, or semicolon)
+     *					or it is one of the tokens reserved for use
+     *					by the cookie protocol
+     * @see #setValue
+     * @see #setVersion
+     *
+     */
+
+    public Cookie(String name, String value) {
+	if (!isToken(name)
+		|| name.equalsIgnoreCase("Comment")	// rfc2019
+		|| name.equalsIgnoreCase("Discard")	// 2019++
+		|| name.equalsIgnoreCase("Domain")
+		|| name.equalsIgnoreCase("Expires")	// (old cookies)
+		|| name.equalsIgnoreCase("Max-Age")	// rfc2019
+		|| name.equalsIgnoreCase("Path")
+		|| name.equalsIgnoreCase("Secure")
+		|| name.equalsIgnoreCase("Version")
+	    ) {
+	    String errMsg = lStrings.getString("err.cookie_name_is_token");
+	    Object[] errArgs = new Object[1];
+	    errArgs[0] = name;
+	    errMsg = MessageFormat.format(errMsg, errArgs);
+	    throw new IllegalArgumentException(errMsg);
+	}
+
+	this.name = name;
+	this.value = value;
+    }
+
+
+
+
+
+    /**
+     *
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie 
+     * to the user. Comments
+     * are not supported by Netscape Version 0 cookies.
+     *
+     * @param purpose		a <code>String</code> specifying the comment 
+     *				to display to the user
+     *
+     * @see #getComment
+     *
+     */
+
+    public void setComment(String purpose) {
+	comment = purpose;
+    }
+    
+    
+    
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * <code>null</code> if the cookie has no comment.
+     *
+     * @return			a <code>String</code> containing the comment,
+     *				or <code>null</code> if none
+     *
+     * @see #setComment
+     *
+     */ 
+
+    public String getComment() {
+	return comment;
+    }
+    
+    
+    
+
+
+    /**
+     *
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p>The form of the domain name is specified by RFC 2109. A domain
+     * name begins with a dot (<code>.foo.com</code>) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, <code>www.foo.com</code>, but not 
+     * <code>a.b.foo.com</code>). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     *
+     * @param pattern		a <code>String</code> containing the domain name
+     *				within which this cookie is visible;
+     *				form is according to RFC 2109
+     *
+     * @see #getDomain
+     *
+     */
+
+    public void setDomain(String pattern) {
+	domain = pattern.toLowerCase();	// IE allegedly needs this
+    }
+    
+    
+    
+    
+
+    /**
+     * Returns the domain name set for this cookie. The form of 
+     * the domain name is set by RFC 2109.
+     *
+     * @return			a <code>String</code> containing the domain name
+     *
+     * @see #setDomain
+     *
+     */ 
+
+    public String getDomain() {
+	return domain;
+    }
+
+
+
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p>A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p>A negative value means
+     * that the cookie is not stored persistently and will be deleted
+     * when the Web browser exits. A zero value causes the cookie
+     * to be deleted.
+     *
+     * @param expiry		an integer specifying the maximum age of the
+     * 				cookie in seconds; if negative, means
+     *				the cookie is not stored; if zero, deletes
+     *				the cookie
+     *
+     *
+     * @see #getMaxAge
+     *
+     */
+
+    public void setMaxAge(int expiry) {
+	maxAge = expiry;
+    }
+
+
+
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds,
+     * By default, <code>-1</code> indicating the cookie will persist
+     * until browser shutdown.
+     *
+     *
+     * @return			an integer specifying the maximum age of the
+     *				cookie in seconds; if negative, means
+     *				the cookie persists until browser shutdown
+     *
+     *
+     * @see #setMaxAge
+     *
+     */
+
+    public int getMaxAge() {
+	return maxAge;
+    }
+    
+    
+    
+
+    /**
+     * Specifies a path for the cookie
+     * to which the client should return the cookie.
+     *
+     * <p>The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories. 
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p>Consult RFC 2109 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     *
+     * @param uri		a <code>String</code> specifying a path
+     *
+     *
+     * @see #getPath
+     *
+     */
+
+    public void setPath(String uri) {
+	path = uri;
+    }
+
+
+
+
+    /**
+     * Returns the path on the server 
+     * to which the browser returns this cookie. The
+     * cookie is visible to all subpaths on the server.
+     *
+     *
+     * @return		a <code>String</code> specifying a path that contains
+     *			a servlet name, for example, <i>/catalog</i>
+     *
+     * @see #setPath
+     *
+     */ 
+
+    public String getPath() {
+	return path;
+    }
+
+
+
+
+
+    /**
+     * Indicates to the browser whether the cookie should only be sent
+     * using a secure protocol, such as HTTPS or SSL.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @param flag	if <code>true</code>, sends the cookie from the browser
+     *			to the server using only when using a secure protocol;
+     *			if <code>false</code>, sent on any protocol
+     *
+     * @see #getSecure
+     *
+     */
+ 
+    public void setSecure(boolean flag) {
+	secure = flag;
+    }
+
+
+
+
+    /**
+     * Returns <code>true</code> if the browser is sending cookies
+     * only over a secure protocol, or <code>false</code> if the
+     * browser can send cookies using any protocol.
+     *
+     * @return		<code>true</code> if the browser uses a secure protocol;
+     * 			 otherwise, <code>true</code>
+     *
+     * @see #setSecure
+     *
+     */
+
+    public boolean getSecure() {
+	return secure;
+    }
+
+
+
+
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return		a <code>String</code> specifying the cookie's name
+     *
+     */
+
+    public String getName() {
+	return name;
+    }
+
+
+
+
+
+    /**
+     *
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p>With Version 0 cookies, values should not contain white 
+     * space, brackets, parentheses, equals signs, commas,
+     * double quotes, slashes, question marks, at signs, colons,
+     * and semicolons. Empty values may not behave the same way
+     * on all browsers.
+     *
+     * @param newValue		a <code>String</code> specifying the new value 
+     *
+     *
+     * @see #getValue
+     * @see Cookie
+     *
+     */
+
+    public void setValue(String newValue) {
+	value = newValue;
+    }
+
+
+
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return			a <code>String</code> containing the cookie's
+     *				present value
+     *
+     * @see #setValue
+     * @see Cookie
+     *
+     */
+
+    public String getValue() {
+	return value;
+    }
+
+
+
+
+    /**
+     * Returns the version of the protocol this cookie complies 
+     * with. Version 1 complies with RFC 2109, 
+     * and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided
+     * by a browser use and identify the browser's cookie version.
+     * 
+     *
+     * @return			0 if the cookie complies with the
+     *				original Netscape specification; 1
+     *				if the cookie complies with RFC 2109
+     *
+     * @see #setVersion
+     *
+     */
+
+    public int getVersion() {
+	return version;
+    }
+
+
+
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2109.
+     *
+     * <p>Since RFC 2109 is still somewhat new, consider
+     * version 1 as experimental; do not use it yet on production sites.
+     *
+     *
+     * @param v			0 if the cookie should comply with 
+     *				the original Netscape specification;
+     *				1 if the cookie should comply with RFC 2109
+     *
+     * @see #getVersion
+     *
+     */
+
+    public void setVersion(int v) {
+	version = v;
+    }
+
+    // Note -- disabled for now to allow full Netscape compatibility
+    // from RFC 2068, token special case characters
+    // 
+    // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
+
+    private static final String tspecials = ",;";
+    
+    
+    
+
+    /*
+     * Tests a string and returns true if the string counts as a 
+     * reserved token in the Java language.
+     * 
+     * @param value		the <code>String</code> to be tested
+     *
+     * @return			<code>true</code> if the <code>String</code> is
+     *				a reserved token; <code>false</code>
+     *				if it is not			
+     */
+
+    private boolean isToken(String value) {
+	int len = value.length();
+
+	for (int i = 0; i < len; i++) {
+	    char c = value.charAt(i);
+
+	    if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
+		return false;
+	}
+	return true;
+    }
+
+
+
+
+
+
+    /**
+     *
+     * Overrides the standard <code>java.lang.Object.clone</code> 
+     * method to return a copy of this cookie.
+     *		
+     *
+     */
+
+    public Object clone() {
+	try {
+	    return super.clone();
+	} catch (CloneNotSupportedException e) {
+	    throw new RuntimeException(e.getMessage());
+	}
+    }
+}
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpServlet.java b/javax.servlet/src/main/java/javax/servlet/http/HttpServlet.java
new file mode 100644
index 0000000..ff7681b
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpServlet.java
@@ -0,0 +1,979 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Method;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+
+/**
+ *
+ * Provides an abstract class to be subclassed to create
+ * an HTTP servlet suitable for a Web site. A subclass of
+ * <code>HttpServlet</code> must override at least 
+ * one method, usually one of these:
+ *
+ * <ul>
+ * <li> <code>doGet</code>, if the servlet supports HTTP GET requests
+ * <li> <code>doPost</code>, for HTTP POST requests
+ * <li> <code>doPut</code>, for HTTP PUT requests
+ * <li> <code>doDelete</code>, for HTTP DELETE requests
+ * <li> <code>init</code> and <code>destroy</code>, 
+ * to manage resources that are held for the life of the servlet
+ * <li> <code>getServletInfo</code>, which the servlet uses to
+ * provide information about itself 
+ * </ul>
+ *
+ * <p>There's almost no reason to override the <code>service</code>
+ * method. <code>service</code> handles standard HTTP
+ * requests by dispatching them to the handler methods
+ * for each HTTP request type (the <code>do</code><i>XXX</i>
+ * methods listed above).
+ *
+ * <p>Likewise, there's almost no reason to override the 
+ * <code>doOptions</code> and <code>doTrace</code> methods.
+ * 
+ * <p>Servlets typically run on multithreaded servers,
+ * so be aware that a servlet must handle concurrent
+ * requests and be careful to synchronize access to shared resources.
+ * Shared resources include in-memory data such as
+ * instance or class variables and external objects
+ * such as files, database connections, and network 
+ * connections.
+ * See the
+ * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
+ * Java Tutorial on Multithreaded Programming</a> for more
+ * information on handling multiple threads in a Java program.
+ *
+ * @author	Various
+ * @version	$Version$
+ *
+ */
+
+
+
+public abstract class HttpServlet extends GenericServlet
+    implements java.io.Serializable
+{
+    private static final String METHOD_DELETE = "DELETE";
+    private static final String METHOD_HEAD = "HEAD";
+    private static final String METHOD_GET = "GET";
+    private static final String METHOD_OPTIONS = "OPTIONS";
+    private static final String METHOD_POST = "POST";
+    private static final String METHOD_PUT = "PUT";
+    private static final String METHOD_TRACE = "TRACE";
+
+    private static final String HEADER_IFMODSINCE = "If-Modified-Since";
+    private static final String HEADER_LASTMOD = "Last-Modified";
+    
+    private static final String LSTRING_FILE =
+	"javax.servlet.http.LocalStrings";
+    private static ResourceBundle lStrings =
+	ResourceBundle.getBundle(LSTRING_FILE);
+   
+   
+   
+    
+    /**
+     * Does nothing, because this is an abstract class.
+     * 
+     */
+
+    public HttpServlet() { }
+    
+    
+
+    /**
+     *
+     * Called by the server (via the <code>service</code> method) to
+     * allow a servlet to handle a GET request. 
+     *
+     * <p>Overriding this method to support a GET request also
+     * automatically supports an HTTP HEAD request. A HEAD
+     * request is a GET request that returns no body in the
+     * response, only the request header fields.
+     *
+     * <p>When overriding this method, read the request data,
+     * write the response headers, get the response's writer or 
+     * output stream object, and finally, write the response data.
+     * It's best to include content type and encoding. When using
+     * a <code>PrintWriter</code> object to return the response,
+     * set the content type before accessing the
+     * <code>PrintWriter</code> object.
+     *
+     * <p>The servlet container must write the headers before
+     * committing the response, because in HTTP the headers must be sent
+     * before the response body.
+     *
+     * <p>Where possible, set the Content-Length header (with the
+     * {@link javax.servlet.ServletResponse#setContentLength} method),
+     * to allow the servlet container to use a persistent connection 
+     * to return its response to the client, improving performance.
+     * The content length is automatically set if the entire response fits
+     * inside the response buffer.
+     * 
+     * <p>The GET method should be safe, that is, without
+     * any side effects for which users are held responsible.
+     * For example, most form queries have no side effects.
+     * If a client request is intended to change stored data,
+     * the request should use some other HTTP method.
+     *
+     * <p>The GET method should also be idempotent, meaning
+     * that it can be safely repeated. Sometimes making a
+     * method safe also makes it idempotent. For example, 
+     * repeating queries is both safe and idempotent, but
+     * buying a product online or modifying data is neither
+     * safe nor idempotent. 
+     *
+     * <p>If the request is incorrectly formatted, <code>doGet</code>
+     * returns an HTTP "Bad Request" message.
+     * 
+     *
+     * @param req	an {@link HttpServletRequest} object that
+     *			contains the request the client has made
+     *			of the servlet
+     *
+     * @param resp	an {@link HttpServletResponse} object that
+     *			contains the response the servlet sends
+     *			to the client
+     * 
+     * @exception IOException	if an input or output error is 
+     *				detected when the servlet handles
+     *				the GET request
+     *
+     * @exception ServletException	if the request for the GET
+     *					could not be handled
+     *
+     * 
+     * @see javax.servlet.ServletResponse#setContentType
+     *
+     */
+
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	String protocol = req.getProtocol();
+	String msg = lStrings.getString("http.method_get_not_supported");
+	if (protocol.endsWith("1.1")) {
+	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+	} else {
+	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+	}
+    }
+
+
+
+
+
+    /**
+     *
+     * Returns the time the <code>HttpServletRequest</code>
+     * object was last modified,
+     * in milliseconds since midnight January 1, 1970 GMT.
+     * If the time is unknown, this method returns a negative
+     * number (the default).
+     *
+     * <p>Servlets that support HTTP GET requests and can quickly determine
+     * their last modification time should override this method.
+     * This makes browser and proxy caches work more effectively,
+     * reducing the load on server and network resources.
+     *
+     *
+     * @param req	the <code>HttpServletRequest</code> 
+     *			object that is sent to the servlet
+     *
+     * @return		a <code>long</code> integer specifying
+     *			the time the <code>HttpServletRequest</code>
+     *			object was last modified, in milliseconds
+     *			since midnight, January 1, 1970 GMT, or
+     *			-1 if the time is not known
+     *
+     */
+
+    protected long getLastModified(HttpServletRequest req) {
+	return -1;
+    }
+
+
+
+
+    /**
+     * 
+     *
+     * <p>Receives an HTTP HEAD request from the protected
+     * <code>service</code> method and handles the
+     * request.
+     * The client sends a HEAD request when it wants
+     * to see only the headers of a response, such as
+     * Content-Type or Content-Length. The HTTP HEAD
+     * method counts the output bytes in the response
+     * to set the Content-Length header accurately.
+     *
+     * <p>If you override this method, you can avoid computing
+     * the response body and just set the response headers
+     * directly to improve performance. Make sure that the
+     * <code>doHead</code> method you write is both safe
+     * and idempotent (that is, protects itself from being
+     * called multiple times for one HTTP HEAD request).
+     *
+     * <p>If the HTTP HEAD request is incorrectly formatted,
+     * <code>doHead</code> returns an HTTP "Bad Request"
+     * message.
+     *
+     *
+     * @param req	the request object that is passed
+     *			to the servlet
+     *			
+     * @param resp	the response object that the servlet
+     *			uses to return the headers to the clien
+     *
+     * @exception IOException		if an input or output error occurs
+     *
+     * @exception ServletException	if the request for the HEAD
+     *					could not be handled
+     */
+
+    protected void doHead(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	NoBodyResponse response = new NoBodyResponse(resp);
+	
+	doGet(req, response);
+	response.setContentLength();
+    }
+    
+
+
+
+
+    /**
+     *
+     * Called by the server (via the <code>service</code> method)
+     * to allow a servlet to handle a POST request.
+     *
+     * The HTTP POST method allows the client to send
+     * data of unlimited length to the Web server a single time
+     * and is useful when posting information such as
+     * credit card numbers.
+     *
+     * <p>When overriding this method, read the request data,
+     * write the response headers, get the response's writer or output
+     * stream object, and finally, write the response data. It's best 
+     * to include content type and encoding. When using a
+     * <code>PrintWriter</code> object to return the response, set the 
+     * content type before accessing the <code>PrintWriter</code> object. 
+     *
+     * <p>The servlet container must write the headers before committing the
+     * response, because in HTTP the headers must be sent before the 
+     * response body.
+     *
+     * <p>Where possible, set the Content-Length header (with the
+     * {@link javax.servlet.ServletResponse#setContentLength} method),
+     * to allow the servlet container to use a persistent connection 
+     * to return its response to the client, improving performance.
+     * The content length is automatically set if the entire response fits
+     * inside the response buffer.  
+     *
+     * <p>When using HTTP 1.1 chunked encoding (which means that the response
+     * has a Transfer-Encoding header), do not set the Content-Length header. 
+     *
+     * <p>This method does not need to be either safe or idempotent.
+     * Operations requested through POST can have side effects for
+     * which the user can be held accountable, for example, 
+     * updating stored data or buying items online.
+     *
+     * <p>If the HTTP POST request is incorrectly formatted,
+     * <code>doPost</code> returns an HTTP "Bad Request" message.
+     *
+     *
+     * @param req	an {@link HttpServletRequest} object that
+     *			contains the request the client has made
+     *			of the servlet
+     *
+     * @param resp	an {@link HttpServletResponse} object that
+     *			contains the response the servlet sends
+     *			to the client
+     * 
+     * @exception IOException	if an input or output error is 
+     *				detected when the servlet handles
+     *				the request
+     *
+     * @exception ServletException	if the request for the POST
+     *					could not be handled
+     *
+     *
+     * @see javax.servlet.ServletOutputStream
+     * @see javax.servlet.ServletResponse#setContentType
+     *
+     *
+     */
+
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	String protocol = req.getProtocol();
+	String msg = lStrings.getString("http.method_post_not_supported");
+	if (protocol.endsWith("1.1")) {
+	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+	} else {
+	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+	}
+    }
+
+
+
+
+    /**
+     * Called by the server (via the <code>service</code> method)
+     * to allow a servlet to handle a PUT request.
+     *
+     * The PUT operation allows a client to 
+     * place a file on the server and is similar to 
+     * sending a file by FTP.
+     *
+     * <p>When overriding this method, leave intact
+     * any content headers sent with the request (including
+     * Content-Length, Content-Type, Content-Transfer-Encoding,
+     * Content-Encoding, Content-Base, Content-Language, Content-Location,
+     * Content-MD5, and Content-Range). If your method cannot
+     * handle a content header, it must issue an error message
+     * (HTTP 501 - Not Implemented) and discard the request.
+     * For more information on HTTP 1.1, see RFC 2068
+     * <a href="http://info.internet.isi.edu:80/in-notes/rfc/files/rfc2068.txt"></a>.
+     *
+     * <p>This method does not need to be either safe or idempotent.
+     * Operations that <code>doPut</code> performs can have side
+     * effects for which the user can be held accountable. When using
+     * this method, it may be useful to save a copy of the
+     * affected URL in temporary storage.
+     *
+     * <p>If the HTTP PUT request is incorrectly formatted,
+     * <code>doPut</code> returns an HTTP "Bad Request" message.
+     *
+     *
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     * @param resp	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				PUT request
+     *
+     * @exception ServletException	if the request for the PUT
+     *					cannot be handled
+     *
+     */
+  
+    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	String protocol = req.getProtocol();
+	String msg = lStrings.getString("http.method_put_not_supported");
+	if (protocol.endsWith("1.1")) {
+	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+	} else {
+	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+	}
+    }
+
+
+
+
+    /**
+     * 
+     * Called by the server (via the <code>service</code> method)
+     * to allow a servlet to handle a DELETE request.
+     *
+     * The DELETE operation allows a client to remove a document
+     * or Web page from the server.
+     * 
+     * <p>This method does not need to be either safe
+     * or idempotent. Operations requested through
+     * DELETE can have side effects for which users
+     * can be held accountable. When using
+     * this method, it may be useful to save a copy of the
+     * affected URL in temporary storage.
+     *
+     * <p>If the HTTP DELETE request is incorrectly formatted,
+     * <code>doDelete</code> returns an HTTP "Bad Request"
+     * message.
+     *
+     *
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     *
+     * @param resp	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client				
+     *
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				DELETE request
+     *
+     * @exception ServletException	if the request for the
+     *					DELETE cannot be handled
+     *
+     */
+     
+    protected void doDelete(HttpServletRequest req,
+			    HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	String protocol = req.getProtocol();
+	String msg = lStrings.getString("http.method_delete_not_supported");
+	if (protocol.endsWith("1.1")) {
+	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
+	} else {
+	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
+	}
+    }
+    
+
+
+
+
+    private Method[] getAllDeclaredMethods(Class c) {
+	if (c.getName().equals("javax.servlet.http.HttpServlet"))
+	    return null;
+	
+	int j=0;
+	Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
+	Method[] thisMethods = c.getDeclaredMethods();
+	
+	if (parentMethods!=null) {
+	    Method[] allMethods =
+		new Method[parentMethods.length + thisMethods.length];
+	    for (int i=0; i<parentMethods.length; i++) {
+		allMethods[i]=parentMethods[i];
+		j=i;
+	    }
+	    j++;
+	    for (int i=j; i<thisMethods.length+j; i++) {
+		allMethods[i] = thisMethods[i-j];
+	    }
+	    return allMethods;
+	}
+	return thisMethods;
+    }
+
+
+
+
+
+
+    /**
+     * Called by the server (via the <code>service</code> method)
+     * to allow a servlet to handle a OPTIONS request.
+     *
+     * The OPTIONS request determines which HTTP methods 
+     * the server supports and
+     * returns an appropriate header. For example, if a servlet
+     * overrides <code>doGet</code>, this method returns the
+     * following header:
+     *
+     * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code>
+     *
+     * <p>There's no need to override this method unless the
+     * servlet implements new HTTP methods, beyond those 
+     * implemented by HTTP 1.1.
+     *
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     *
+     * @param resp	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client				
+     *
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				OPTIONS request
+     *
+     * @exception ServletException	if the request for the
+     *					OPTIONS cannot be handled
+     *
+     */
+         
+    protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	Method[] methods = getAllDeclaredMethods(this.getClass());
+	
+	boolean ALLOW_GET = false;
+	boolean ALLOW_HEAD = false;
+	boolean ALLOW_POST = false;
+	boolean ALLOW_PUT = false;
+	boolean ALLOW_DELETE = false;
+	boolean ALLOW_TRACE = true;
+	boolean ALLOW_OPTIONS = true;
+	
+	for (int i=0; i<methods.length; i++) {
+	    Method m = methods[i];
+	    
+	    if (m.getName().equals("doGet")) {
+		ALLOW_GET = true;
+		ALLOW_HEAD = true;
+	    }
+	    if (m.getName().equals("doPost")) 
+		ALLOW_POST = true;
+	    if (m.getName().equals("doPut"))
+		ALLOW_PUT = true;
+	    if (m.getName().equals("doDelete"))
+		ALLOW_DELETE = true;
+	    
+	}
+	
+	String allow = null;
+	if (ALLOW_GET)
+	    if (allow==null) allow=METHOD_GET;
+	if (ALLOW_HEAD)
+	    if (allow==null) allow=METHOD_HEAD;
+	    else allow += ", " + METHOD_HEAD;
+	if (ALLOW_POST)
+	    if (allow==null) allow=METHOD_POST;
+	    else allow += ", " + METHOD_POST;
+	if (ALLOW_PUT)
+	    if (allow==null) allow=METHOD_PUT;
+	    else allow += ", " + METHOD_PUT;
+	if (ALLOW_DELETE)
+	    if (allow==null) allow=METHOD_DELETE;
+	    else allow += ", " + METHOD_DELETE;
+	if (ALLOW_TRACE)
+	    if (allow==null) allow=METHOD_TRACE;
+	    else allow += ", " + METHOD_TRACE;
+	if (ALLOW_OPTIONS)
+	    if (allow==null) allow=METHOD_OPTIONS;
+	    else allow += ", " + METHOD_OPTIONS;
+	
+	resp.setHeader("Allow", allow);
+    }
+    
+    
+    
+    
+    /**
+     * Called by the server (via the <code>service</code> method)
+     * to allow a servlet to handle a TRACE request.
+     *
+     * A TRACE returns the headers sent with the TRACE
+     * request to the client, so that they can be used in
+     * debugging. There's no need to override this method. 
+     *
+     *
+     *
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     *
+     * @param resp	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client				
+     *
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				TRACE request
+     *
+     * @exception ServletException	if the request for the
+     *					TRACE cannot be handled
+     *
+     */
+
+    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) 
+	throws ServletException, IOException
+    {
+	
+	int responseLength;
+	
+	String CRLF = "\r\n";
+	String responseString = "TRACE "+ req.getRequestURI()+
+	    " " + req.getProtocol();
+	
+	Enumeration reqHeaderEnum = req.getHeaderNames();
+	
+	while( reqHeaderEnum.hasMoreElements() ) {
+	    String headerName = (String)reqHeaderEnum.nextElement();
+	    responseString += CRLF + headerName + ": " +
+		req.getHeader(headerName); 
+	}
+	
+	responseString += CRLF;
+	
+	responseLength = responseString.length();
+	
+	resp.setContentType("message/http");
+	resp.setContentLength(responseLength);
+	ServletOutputStream out = resp.getOutputStream();
+	out.print(responseString);	
+	out.close();
+	return;
+    }		
+
+
+
+
+
+    /**
+     *
+     * Receives standard HTTP requests from the public
+     * <code>service</code> method and dispatches
+     * them to the <code>do</code><i>XXX</i> methods defined in 
+     * this class. This method is an HTTP-specific version of the 
+     * {@link javax.servlet.Servlet#service} method. There's no
+     * need to override this method.
+     *
+     *
+     *
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     *
+     * @param resp	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client				
+     *
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				TRACE request
+     *
+     * @exception ServletException	if the request for the
+     *					TRACE cannot be handled
+     * 
+     * @see 				javax.servlet.Servlet#service
+     *
+     */
+
+    protected void service(HttpServletRequest req, HttpServletResponse resp)
+	throws ServletException, IOException
+    {
+	String method = req.getMethod();
+
+	if (method.equals(METHOD_GET)) {
+	    long lastModified = getLastModified(req);
+	    if (lastModified == -1) {
+		// servlet doesn't support if-modified-since, no reason
+		// to go through further expensive logic
+		doGet(req, resp);
+	    } else {
+		long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
+		if (ifModifiedSince < (lastModified / 1000 * 1000)) {
+		    // If the servlet mod time is later, call doGet()
+                    // Round down to the nearest second for a proper compare
+                    // A ifModifiedSince of -1 will always be less
+		    maybeSetLastModified(resp, lastModified);
+		    doGet(req, resp);
+		} else {
+		    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+		}
+	    }
+
+	} else if (method.equals(METHOD_HEAD)) {
+	    long lastModified = getLastModified(req);
+	    maybeSetLastModified(resp, lastModified);
+	    doHead(req, resp);
+
+	} else if (method.equals(METHOD_POST)) {
+	    doPost(req, resp);
+	    
+	} else if (method.equals(METHOD_PUT)) {
+	    doPut(req, resp);	
+	    
+	} else if (method.equals(METHOD_DELETE)) {
+	    doDelete(req, resp);
+	    
+	} else if (method.equals(METHOD_OPTIONS)) {
+	    doOptions(req,resp);
+	    
+	} else if (method.equals(METHOD_TRACE)) {
+	    doTrace(req,resp);
+	    
+	} else {
+	    //
+	    // Note that this means NO servlet supports whatever
+	    // method was requested, anywhere on this server.
+	    //
+
+	    String errMsg = lStrings.getString("http.method_not_implemented");
+	    Object[] errArgs = new Object[1];
+	    errArgs[0] = method;
+	    errMsg = MessageFormat.format(errMsg, errArgs);
+	    
+	    resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
+	}
+    }
+    
+
+
+
+
+    /*
+     * Sets the Last-Modified entity header field, if it has not
+     * already been set and if the value is meaningful.  Called before
+     * doGet, to ensure that headers are set before response data is
+     * written.  A subclass might have set this header already, so we
+     * check.
+     */
+
+    private void maybeSetLastModified(HttpServletResponse resp,
+				      long lastModified) {
+	if (resp.containsHeader(HEADER_LASTMOD))
+	    return;
+	if (lastModified >= 0)
+	    resp.setDateHeader(HEADER_LASTMOD, lastModified);
+    }
+   
+   
+   
+    
+    /**
+     *
+     * Dispatches client requests to the protected
+     * <code>service</code> method. There's no need to
+     * override this method.
+     *
+     * 
+     * @param req	the {@link HttpServletRequest} object that
+     *			contains the request the client made of
+     *			the servlet
+     *
+     *
+     * @param res	the {@link HttpServletResponse} object that
+     *			contains the response the servlet returns
+     *			to the client				
+     *
+     *
+     * @exception IOException	if an input or output error occurs
+     *				while the servlet is handling the
+     *				TRACE request
+     *
+     * @exception ServletException	if the request for the
+     *					TRACE cannot be handled
+     *
+     * 
+     * @see javax.servlet.Servlet#service
+     *
+     */
+
+    public void service(ServletRequest req, ServletResponse res)
+	throws ServletException, IOException
+    {
+	HttpServletRequest	request;
+	HttpServletResponse	response;
+	
+	try {
+	    request = (HttpServletRequest) req;
+	    response = (HttpServletResponse) res;
+	} catch (ClassCastException e) {
+	    throw new ServletException("non-HTTP request or response");
+	}
+	service(request, response);
+    }
+}
+
+
+
+
+/*
+ * A response that includes no body, for use in (dumb) "HEAD" support.
+ * This just swallows that body, counting the bytes in order to set
+ * the content length appropriately.  All other methods delegate directly
+ * to the HTTP Servlet Response object used to construct this one.
+ */
+// file private
+class NoBodyResponse implements HttpServletResponse {
+    private HttpServletResponse		resp;
+    private NoBodyOutputStream		noBody;
+    private PrintWriter			writer;
+    private boolean			didSetContentLength;
+
+    // file private
+    NoBodyResponse(HttpServletResponse r) {
+	resp = r;
+	noBody = new NoBodyOutputStream();
+    }
+
+    // file private
+    void setContentLength() {
+	if (!didSetContentLength)
+	  resp.setContentLength(noBody.getContentLength());
+    }
+
+
+    // SERVLET RESPONSE interface methods
+
+    public void setContentLength(int len) {
+	resp.setContentLength(len);
+	didSetContentLength = true;
+    }
+
+    public void setContentType(String type)
+      { resp.setContentType(type); }
+
+    public ServletOutputStream getOutputStream() throws IOException
+      { return noBody; }
+
+    public String getCharacterEncoding()
+	{ return resp.getCharacterEncoding(); }
+
+    public PrintWriter getWriter() throws UnsupportedEncodingException
+    {
+	if (writer == null) {
+	    OutputStreamWriter	w;
+
+	    w = new OutputStreamWriter(noBody, getCharacterEncoding());
+	    writer = new PrintWriter(w);
+	}
+	return writer;
+    }
+
+    public void addCookie(Cookie cookie)
+      { resp.addCookie(cookie); }
+
+    public boolean containsHeader(String name)
+      { return resp.containsHeader(name); }
+
+    /** @deprecated */
+    public void setStatus(int sc, String sm)
+      { resp.setStatus(sc, sm); }
+
+    public void setStatus(int sc)
+      { resp.setStatus(sc); }
+
+    public void setHeader(String name, String value)
+      { resp.setHeader(name, value); }
+
+    public void setIntHeader(String name, int value)
+      { resp.setIntHeader(name, value); }
+
+    public void setDateHeader(String name, long date)
+      { resp.setDateHeader(name, date); }
+
+    public void sendError(int sc, String msg) throws IOException
+      { resp.sendError(sc, msg); }
+
+    public void sendError(int sc) throws IOException
+      { resp.sendError(sc); }
+
+    public void sendRedirect(String location) throws IOException
+      { resp.sendRedirect(location); }
+    
+    public String encodeURL(String url) 
+      { return resp.encodeURL(url); }
+
+    public String encodeRedirectURL(String url)
+      { return resp.encodeRedirectURL(url); }
+      
+    /**
+     * @deprecated	As of Version 2.1, replaced by
+     * 			{@link HttpServletResponse#encodeURL}.
+     *
+     */
+     
+     
+    public String encodeUrl(String url) 
+      { return this.encodeURL(url); }
+      
+      
+      
+      
+      
+      
+      
+
+    /**
+     * @deprecated	As of Version 2.1, replaced by
+     *			{@link HttpServletResponse#encodeRedirectURL}.
+     *
+     */
+     
+     
+    public String encodeRedirectUrl(String url)
+      { return this.encodeRedirectURL(url); }
+
+}
+
+
+
+
+
+
+
+/*
+ * Servlet output stream that gobbles up all its data.
+ */
+ 
+// file private
+class NoBodyOutputStream extends ServletOutputStream {
+
+    private static final String LSTRING_FILE =
+	"javax.servlet.http.LocalStrings";
+    private static ResourceBundle lStrings =
+	ResourceBundle.getBundle(LSTRING_FILE);
+
+    private int		contentLength = 0;
+
+    // file private
+    NoBodyOutputStream() {}
+
+    // file private
+    int getContentLength() {
+	return contentLength;
+    }
+
+    public void write(int b) {
+	contentLength++;
+    }
+
+    public void write(byte buf[], int offset, int len)
+	throws IOException
+    {
+	if (len >= 0) {
+	    contentLength += len;
+	} else {
+	    // XXX
+	    // isn't this really an IllegalArgumentException?
+	    
+	    String msg = lStrings.getString("err.io.negativelength");
+	    throw new IOException(msg);
+	}
+    }
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpServletRequest.java b/javax.servlet/src/main/java/javax/servlet/http/HttpServletRequest.java
new file mode 100644
index 0000000..68c77cc
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpServletRequest.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import javax.servlet.ServletRequest;
+import java.util.Enumeration;
+
+/**
+ *
+ * Extends the {@link javax.servlet.ServletRequest} interface
+ * to provide request information for HTTP servlets.
+ *
+ * <p>The servlet container creates an <code>HttpServletRequest</code>
+ * object and passes it as an argument to the servlet's service
+ * methods (<code>doGet</code>, <code>doPost</code>, etc).
+ *
+ *
+ * @author 	Various
+ * @version	$Version$
+ *
+ *
+ */
+
+public interface HttpServletRequest extends ServletRequest {
+
+    /**
+     * Returns the name of the authentication scheme used to protect
+     * the servlet, for example, "BASIC" or "SSL".
+     * If the servlet is not authenticated <code>null</code> is returned.
+     *
+     * <p>Same as the value of the CGI variable AUTH_TYPE.
+     *
+     *
+     * @return		a <code>String</code> specifying the name of
+     *			the authentication scheme, or
+     *			<code>null</code> if the request was not
+     *			authenticated
+     *
+     */
+
+    public String getAuthType();
+
+
+
+
+    /**
+     *
+     * Returns an array containing all of the <code>Cookie</code>
+     * objects the client sent with this request.
+     * This method returns <code>null</code> if no cookies were sent.
+     *
+     * @return		an array of all the <code>Cookies</code>
+     *			included with this request, or <code>null</code>
+     *			if the request has no cookies
+     *
+     *
+     */
+
+    public Cookie[] getCookies();
+
+
+
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>long</code> value that represents a
+     * <code>Date</code> object. Use this method with
+     * headers that contain dates, such as
+     * <code>If-Modified-Since</code>.
+     *
+     * <p>The date is returned as
+     * the number of milliseconds since January 1, 1970 GMT.
+     * The header name is case insensitive.
+     *
+     * <p>If the request did not have a header of the
+     * specified name, this method returns -1. If the header
+     * can't be converted to a date, the method throws
+     * an <code>IllegalArgumentException</code>.
+     *
+     * @param name		a <code>String</code> specifying the
+     *				name of the header
+     *
+     * @return			a <code>long</code> value
+     *				representing the date specified
+     *				in the header expressed as
+     *				the number of milliseconds
+     *				since January 1, 1970 GMT,
+     *				or -1 if the named header
+     *				was not included with the
+     *				reqest
+     *
+     * @exception	IllegalArgumentException	If the header value
+     *							can't be converted
+     *							to a date
+     *
+     */
+
+    public long getDateHeader(String name);
+
+
+
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>String</code>. If the request did not include a header
+     * of the specified name, this method returns <code>null</code>.
+     * The header name is case insensitive. You can use
+     * this method with any request header.
+     *
+     * @param name		a <code>String</code> specifying the
+     *				header name
+     *
+     * @return			a <code>String</code> containing the
+     *				value of the requested
+     *				header, or <code>null</code>
+     *				if the request does not
+     *				have a header of that name
+     *
+     */			
+
+    public String getHeader(String name);
+
+
+
+
+    /**
+     *
+     * Returns an enumeration of all the header names
+     * this request contains. If the request has no
+     * headers, this method returns an empty enumeration.
+     *
+     * <p>Some servlet containers do not allow do not allow
+     * servlets to access headers using this method, in
+     * which case this method returns <code>null</code>
+     *
+     * @return			an enumeration of all the
+     *				header names sent with this
+     *				request; if the request has
+     *				no headers, an empty enumeration;
+     *				if the servlet container does not
+     *				allow servlets to use this method,
+     *				<code>null</code>
+     *				
+     *
+     */
+
+    public Enumeration getHeaderNames();
+
+
+
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as an <code>int</code>. If the request does not have a header
+     * of the specified name, this method returns -1. If the
+     * header cannot be converted to an integer, this method
+     * throws a <code>NumberFormatException</code>.
+     *
+     * <p>The header name is case insensitive.
+     *
+     * @param name		a <code>String</code> specifying the name
+     *				of a request header
+     *
+     * @return			an integer expressing the value
+     * 				of the request header or -1
+     *				if the request doesn't have a
+     *				header of this name
+     *
+     * @exception	NumberFormatException		If the header value
+     *							can't be converted
+     *							to an <code>int</code>
+     */
+
+    public int getIntHeader(String name);
+
+
+
+
+    /**
+     *
+     * Returns the name of the HTTP method with which this
+     * request was made, for example, GET, POST, or PUT.
+     * Same as the value of the CGI variable REQUEST_METHOD.
+     *
+     * @return			a <code>String</code>
+     *				specifying the name
+     *				of the method with which
+     *				this request was made
+     *
+     */
+
+    public String getMethod();
+
+
+
+
+    /**
+     *
+     * Returns any extra path information associated with
+     * the URL the client sent when it made this request.
+     * The extra path information follows the servlet path
+     * but precedes the query string.
+     * This method returns <code>null</code> if there
+     * was no extra path information.
+     *
+     * <p>Same as the value of the CGI variable PATH_INFO.
+     *
+     *
+     * @return		a <code>String</code>, decoded by the
+     *			web container, specifying
+     *			extra path information that comes
+     *			after the servlet path but before
+     *			the query string in the request URL;
+     *			or <code>null</code> if the URL does not have
+     *			any extra path information
+     *
+     */
+
+    public String getPathInfo();
+
+
+
+
+    /**
+     *
+     * Returns any extra path information after the servlet name
+     * but before the query string, and translates it to a real
+     * path. Same as the value of the CGI variable PATH_TRANSLATED.
+     *
+     * <p>If the URL does not have any extra path information,
+     * this method returns <code>null</code>.
+     *
+     * The web container does not decode this string.
+     *
+     *
+     * @return		a <code>String</code> specifying the
+     *			real path, or <code>null</code> if
+     *			the URL does not have any extra path
+     *			information
+     *
+     *
+     */
+
+    public String getPathTranslated();
+
+
+
+
+    /**
+     *
+     * Returns the query string that is contained in the request
+     * URL after the path. This method returns <code>null</code>
+     * if the URL does not have a query string. Same as the value
+     * of the CGI variable QUERY_STRING.
+     *
+     * @return		a <code>String</code> containing the query
+     *			string or <code>null</code> if the URL
+     *			contains no query string. The value is not
+     *			decoded by the container.
+     *
+     */
+
+    public String getQueryString();
+
+
+
+
+    /**
+     *
+     * Returns the login of the user making this request, if the
+     * user has been authenticated, or <code>null</code> if the user
+     * has not been authenticated.
+     * Whether the user name is sent with each subsequent request
+     * depends on the browser and type of authentication. Same as the
+     * value of the CGI variable REMOTE_USER.
+     *
+     * @return		a <code>String</code> specifying the login
+     *			of the user making this request, or <code>null</code
+     *			if the user login is not known
+     *
+     */
+
+    public String getRemoteUser();
+
+
+
+
+    /**
+     *
+     * Returns the session ID specified by the client. This may
+     * not be the same as the ID of the actual session in use.
+     * For example, if the request specified an old (expired)
+     * session ID and the server has started a new session, this
+     * method gets a new session with a new ID. If the request
+     * did not specify a session ID, this method returns
+     * <code>null</code>.
+     *
+     *
+     * @return		a <code>String</code> specifying the session
+     *			ID, or <code>null</code> if the request did
+     *			not specify a session ID
+     *
+     * @see		#isRequestedSessionIdValid
+     *
+     */
+
+    public String getRequestedSessionId();
+
+
+
+
+    /**
+     *
+     * Returns the part of this request's URL from the protocol
+     * name up to the query string in the first line of the HTTP request.
+     * The web container does not decode this String.
+     * For example:
+     *
+     *
+
+     * <table>
+     * <tr align=left><th>First line of HTTP request      </th>
+     * <th>     Returned Value</th>
+     * <tr><td>POST /some/path.html HTTP/1.1<td><td>/some/path.html
+     * <tr><td>GET http://foo.bar/a.html HTTP/1.0
+     * <td><td>/a.html
+     * <tr><td>HEAD /xyz?a=b HTTP/1.1<td><td>/xyz
+     * </table>
+     *
+     * <p>To reconstruct an URL with a scheme and host, use
+     * {@link HttpUtils#getRequestURL}.
+     *
+     * @return		a <code>String</code> containing
+     *			the part of the URL from the
+     *			protocol name up to the query string
+     *
+     * @see		HttpUtils#getRequestURL
+     *
+     */
+
+    public String getRequestURI();
+
+    /**
+     *
+     * Returns the part of this request's URL that calls
+     * the servlet. This includes either the servlet name or
+     * a path to the servlet, but does not include any extra
+     * path information or a query string. Same as the value
+     * of the CGI variable SCRIPT_NAME.
+     *
+     *
+     * @return		a <code>String</code> containing
+     *			the name or path of the servlet being
+     *			called, as specified in the request URL,
+     *			decoded.
+     *
+     *
+     */
+
+    public String getServletPath();
+
+
+
+
+    /**
+     *
+     * Returns the current <code>HttpSession</code>
+     * associated with this request or, if if there is no
+     * current session and <code>create</code> is true, returns
+     * a new session.
+     *
+     * <p>If <code>create</code> is <code>false</code>
+     * and the request has no valid <code>HttpSession</code>,
+     * this method returns <code>null</code>.
+     *
+     * <p>To make sure the session is properly maintained,
+     * you must call this method before
+     * the response is committed. If the container is using cookies
+     * to maintain session integrity and is asked to create a new session
+     * when the response is committed, an IllegalStateException is thrown.
+     *
+     *
+     *
+     *
+     * @param	create	<code>true</code> to create
+     *			a new session for this request if necessary;
+     *			<code>false</code> to return <code>null</code>
+     *			if there's no current session
+     *			
+     *
+     * @return 		the <code>HttpSession</code> associated
+     *			with this request or <code>null</code> if
+     * 			<code>create</code> is <code>false</code>
+     *			and the request has no valid session
+     *
+     * @see	#getSession()
+     *
+     *
+     */
+
+    public HttpSession getSession(boolean create);
+
+
+
+
+
+    /**
+     *
+     * Returns the current session associated with this request,
+     * or if the request does not have a session, creates one.
+     *
+     * @return		the <code>HttpSession</code> associated
+     *			with this request
+     *
+     * @see	#getSession(boolean)
+     *
+     */
+
+    public HttpSession getSession();
+
+
+
+
+
+
+    /**
+     *
+     * Checks whether the requested session ID is still valid.
+     *
+     * @return			<code>true</code> if this
+     *				request has an id for a valid session
+     *				in the current session context;
+     *				<code>false</code> otherwise
+     *
+     * @see			#getRequestedSessionId
+     * @see			#getSession(boolean)
+     * @see			HttpSessionContext
+     *
+     */
+
+    public boolean isRequestedSessionIdValid();
+
+
+
+
+    /**
+     *
+     * Checks whether the requested session ID came in as a cookie.
+     *
+     * @return			<code>true</code> if the session ID
+     *				came in as a
+     *				cookie; otherwise, <code>false</code>
+     *
+     *
+     * @see			#getSession(boolean)
+     *
+     */
+
+    public boolean isRequestedSessionIdFromCookie();
+
+
+
+
+    /**
+     *
+     * Checks whether the requested session ID came in as part of the
+     * request URL.
+     *
+     * @return			<code>true</code> if the session ID
+     *				came in as part of a URL; otherwise,
+     *				<code>false</code>
+     *
+     *
+     * @see			#getSession(boolean)
+     *
+     */
+
+    public boolean isRequestedSessionIdFromURL();
+
+
+
+
+
+    /**
+     *
+     * @deprecated		As of Version 2.1 of the Java Servlet
+     *				API, use {@link #isRequestedSessionIdFromURL}
+     *				instead.
+     *
+     */
+
+    public boolean isRequestedSessionIdFromUrl();
+
+
+
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpServletResponse.java b/javax.servlet/src/main/java/javax/servlet/http/HttpServletResponse.java
new file mode 100644
index 0000000..0335f6b
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpServletResponse.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+
+/**
+ *
+ * Extends the {@link ServletResponse} interface to provide HTTP-specific
+ * functionality in sending a response.  For example, it has methods
+ * to access HTTP headers and cookies.
+ *
+ * <p>The servlet container creates an <code>HttpServletRequest</code> object
+ * and passes it as an argument to the servlet's service methods
+ * (<code>doGet</code>, <code>doPost</code>, etc).
+ *
+ *
+ * @author	Various
+ * @version	$Version$
+ *
+ * @see		javax.servlet.ServletResponse
+ *
+ */
+
+
+
+public interface HttpServletResponse extends ServletResponse {
+
+    /**
+     * Adds the specified cookie to the response.  This method can be called
+     * multiple times to set more than one cookie.
+     *
+     * @param cookie the Cookie to return to the client
+     *
+     */
+
+    public void addCookie(Cookie cookie);
+
+    /**
+     * Returns a boolean indicating whether the named response header
+     * has already been set.
+     *
+     * @param	name	the header name
+     * @return		<code>true</code> if the named response header
+     *			has already been set;
+     * 			<code>false</code> otherwise
+     */
+
+    public boolean containsHeader(String name);
+
+    /**
+     * Encodes the specified URL by including the session ID in it,
+     * or, if encoding is not needed, returns the URL unchanged.
+     * The implementation of this method includes the logic to
+     * determine whether the session ID needs to be encoded in the URL.
+     * For example, if the browser supports cookies, or session
+     * tracking is turned off, URL encoding is unnecessary.
+     *
+     * <p>For robust session tracking, all URLs emitted by a servlet
+     * should be run through this
+     * method.  Otherwise, URL rewriting cannot be used with browsers
+     * which do not support cookies.
+     *
+     * @param	url	the url to be encoded.
+     * @return		the encoded URL if encoding is needed;
+     * 			the unchanged URL otherwise.
+     */
+
+    public String encodeURL(String url);
+
+    /**
+     * Encodes the specified URL for use in the
+     * <code>sendRedirect</code> method or, if encoding is not needed,
+     * returns the URL unchanged.  The implementation of this method
+     * includes the logic to determine whether the session ID
+     * needs to be encoded in the URL.  Because the rules for making
+     * this determination can differ from those used to decide whether to
+     * encode a normal link, this method is seperate from the
+     * <code>encodeURL</code> method.
+     *
+     * <p>All URLs sent to the <code>HttpServletResponse.sendRedirect</code>
+     * method should be run through this method.  Otherwise, URL
+     * rewriting cannot be used with browsers which do not support
+     * cookies.
+     *
+     * @param	url	the url to be encoded.
+     * @return		the encoded URL if encoding is needed;
+     * 			the unchanged URL otherwise.
+     *
+     * @see #sendRedirect
+     * @see #encodeUrl
+     */
+
+    public String encodeRedirectURL(String url);
+
+    /**
+     * @deprecated	As of version 2.1, use encodeURL(String url) instead
+     *
+     * @param	url	the url to be encoded.
+     * @return		the encoded URL if encoding is needed;
+     * 			the unchanged URL otherwise.
+     */
+
+    public String encodeUrl(String url);
+
+    /**
+     * @deprecated	As of version 2.1, use
+     *			encodeRedirectURL(String url) instead
+     *
+     * @param	url	the url to be encoded.
+     * @return		the encoded URL if encoding is needed;
+     * 			the unchanged URL otherwise.
+     */
+
+    public String encodeRedirectUrl(String url);
+
+    /**
+     * Sends an error response to the client using the specified
+     * status clearing the buffer.  The server defaults to creating the
+     * response to look like an HTML-formatted server error page containing the specified message, setting the content type
+     * to "text/html", leaving cookies and other headers unmodified.
+     *
+     * If an error-page declaration has been made for the web application
+     * corresponding to the status code passed in, it will be served back in
+     * preference to the suggested msg parameter.
+     *
+     * <p>If the response has already been committed, this method throws
+     * an IllegalStateException.
+     * After using this method, the response should be considered
+     * to be committed and should not be written to.
+     *
+     * @param	sc	the error status code
+     * @param	msg	the descriptive message
+     * @exception	IOException	If an input or output exception occurs
+     * @exception	IllegalStateException	If the response was committed
+     */
+
+    public void sendError(int sc, String msg) throws IOException;
+
+    /**
+     * Sends an error response to the client using the specified status
+     * code and clearing the buffer.
+     * <p>If the response has already been committed, this method throws
+     * an IllegalStateException.
+     * After using this method, the response should be considered
+     * to be committed and should not be written to.
+     *
+     * @param	sc	the error status code
+     * @exception	IOException	If an input or output exception occurs
+     * @exception	IllegalStateException	If the response was committed
+     *						before this method call
+     */
+
+    public void sendError(int sc) throws IOException;
+
+    /**
+     * Sends a temporary redirect response to the client using the
+     * specified redirect location URL.  This method can accept relative URLs;
+     * the servlet container must convert the relative URL to an absolute URL
+     * before sending the response to the client. If the location is relative
+     * without a leading '/' the container interprets it as relative to
+     * the current request URI. If the location is relative with a leading
+     * '/' the container interprets it as relative to the servlet container root.
+     *
+     * <p>If the response has already been committed, this method throws
+     * an IllegalStateException.
+     * After using this method, the response should be considered
+     * to be committed and should not be written to.
+     *
+     * @param		location	the redirect location URL
+     * @exception	IOException	If an input or output exception occurs
+     * @exception	IllegalStateException	If the response was committed
+     */
+
+    public void sendRedirect(String location) throws IOException;
+
+    /**
+     *
+     * Sets a response header with the given name and
+     * date-value.  The date is specified in terms of
+     * milliseconds since the epoch.  If the header had already
+     * been set, the new value overwrites the previous one.  The
+     * <code>containsHeader</code> method can be used to test for the
+     * presence of a header before setting its value.
+     *
+     * @param	name	the name of the header to set
+     * @param	date	the assigned date value
+     *
+     * @see #containsHeader
+     */
+
+    public void setDateHeader(String name, long date);
+
+    /**
+     *
+     * Sets a response header with the given name and value.
+     * If the header had already been set, the new value overwrites the
+     * previous one.  The <code>containsHeader</code> method can be
+     * used to test for the presence of a header before setting its
+     * value.
+     *
+     * @param	name	the name of the header
+     * @param	value	the header value
+     *
+     * @see #containsHeader
+     */
+
+    public void setHeader(String name, String value);
+
+    /**
+     * Sets a response header with the given name and
+     * integer value.  If the header had already been set, the new value
+     * overwrites the previous one.  The <code>containsHeader</code>
+     * method can be used to test for the presence of a header before
+     * setting its value.
+     *
+     * @param	name	the name of the header
+     * @param	value	the assigned integer value
+     *
+     * @see #containsHeader
+     */
+
+    public void setIntHeader(String name, int value);
+
+    /**
+     * Sets the status code for this response.  This method is used to
+     * set the return status code when there is no error (for example,
+     * for the status codes SC_OK or SC_MOVED_TEMPORARILY).  If there
+     * is an error, the <code>sendError</code> method should be used
+     * instead.
+     * <p> The container clears the buffer and sets the Location header, preserving
+     * cookies and other headers.
+     *
+     * @param	sc	the status code
+     *
+     * @see #sendError(int, String)
+     */
+
+    public void setStatus(int sc);
+
+    /**
+     * @deprecated As of version 2.1, due to ambiguous meaning of the
+     * message parameter. To set a status code
+     * use <code>setStatus(int)</code>, to send an error with a description
+     * use <code>sendError(int, String)</code>.
+     *
+     * Sets the status code and message for this response.
+     *
+     * @param	sc	the status code
+     * @param	sm	the status message
+     */
+
+    public void setStatus(int sc, String sm);
+
+
+    /*
+     * Server status codes; see RFC 2068.
+     */
+
+    /**
+     * Status code (100) indicating the client can continue.
+     */
+
+    public static final int SC_CONTINUE = 100;
+
+
+    /**
+     * Status code (101) indicating the server is switching protocols
+     * according to Upgrade header.
+     */
+
+    public static final int SC_SWITCHING_PROTOCOLS = 101;
+
+    /**
+     * Status code (200) indicating the request succeeded normally.
+     */
+
+    public static final int SC_OK = 200;
+
+    /**
+     * Status code (201) indicating the request succeeded and created
+     * a new resource on the server.
+     */
+
+    public static final int SC_CREATED = 201;
+
+    /**
+     * Status code (202) indicating that a request was accepted for
+     * processing, but was not completed.
+     */
+
+    public static final int SC_ACCEPTED = 202;
+
+    /**
+     * Status code (203) indicating that the meta information presented
+     * by the client did not originate from the server.
+     */
+
+    public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
+
+    /**
+     * Status code (204) indicating that the request succeeded but that
+     * there was no new information to return.
+     */
+
+    public static final int SC_NO_CONTENT = 204;
+
+    /**
+     * Status code (205) indicating that the agent <em>SHOULD</em> reset
+     * the document view which caused the request to be sent.
+     */
+
+    public static final int SC_RESET_CONTENT = 205;
+
+    /**
+     * Status code (206) indicating that the server has fulfilled
+     * the partial GET request for the resource.
+     */
+
+    public static final int SC_PARTIAL_CONTENT = 206;
+
+    /**
+     * Status code (300) indicating that the requested resource
+     * corresponds to any one of a set of representations, each with
+     * its own specific location.
+     */
+
+    public static final int SC_MULTIPLE_CHOICES = 300;
+
+    /**
+     * Status code (301) indicating that the resource has permanently
+     * moved to a new location, and that future references should use a
+     * new URI with their requests.
+     */
+
+    public static final int SC_MOVED_PERMANENTLY = 301;
+
+    /**
+     * Status code (302) indicating that the resource has temporarily
+     * moved to another location, but that future references should
+     * still use the original URI to access the resource.
+     */
+
+    public static final int SC_MOVED_TEMPORARILY = 302;
+
+    /**
+     * Status code (303) indicating that the response to the request
+     * can be found under a different URI.
+     */
+
+    public static final int SC_SEE_OTHER = 303;
+
+    /**
+     * Status code (304) indicating that a conditional GET operation
+     * found that the resource was available and not modified.
+     */
+
+    public static final int SC_NOT_MODIFIED = 304;
+
+    /**
+     * Status code (305) indicating that the requested resource
+     * <em>MUST</em> be accessed through the proxy given by the
+     * <code><em>Location</em></code> field.
+     */
+
+    public static final int SC_USE_PROXY = 305;
+
+    /**
+     * Status code (400) indicating the request sent by the client was
+     * syntactically incorrect.
+     */
+
+    public static final int SC_BAD_REQUEST = 400;
+
+    /**
+     * Status code (401) indicating that the request requires HTTP
+     * authentication.
+     */
+
+    public static final int SC_UNAUTHORIZED = 401;
+
+    /**
+     * Status code (402) reserved for future use.
+     */
+
+    public static final int SC_PAYMENT_REQUIRED = 402;
+
+    /**
+     * Status code (403) indicating the server understood the request
+     * but refused to fulfill it.
+     */
+
+    public static final int SC_FORBIDDEN = 403;
+
+    /**
+     * Status code (404) indicating that the requested resource is not
+     * available.
+     */
+
+    public static final int SC_NOT_FOUND = 404;
+
+    /**
+     * Status code (405) indicating that the method specified in the
+     * <code><em>Request-Line</em></code> is not allowed for the resource
+     * identified by the <code><em>Request-URI</em></code>.
+     */
+
+    public static final int SC_METHOD_NOT_ALLOWED = 405;
+
+    /**
+     * Status code (406) indicating that the resource identified by the
+     * request is only capable of generating response entities which have
+     * content characteristics not acceptable according to the accept
+     * headerssent in the request.
+     */
+
+    public static final int SC_NOT_ACCEPTABLE = 406;
+
+    /**
+     * Status code (407) indicating that the client <em>MUST</em> first
+     * authenticate itself with the proxy.
+     */
+
+    public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
+
+    /**
+     * Status code (408) indicating that the client did not produce a
+     * requestwithin the time that the server was prepared to wait.
+     */
+
+    public static final int SC_REQUEST_TIMEOUT = 408;
+
+    /**
+     * Status code (409) indicating that the request could not be
+     * completed due to a conflict with the current state of the
+     * resource.
+     */
+
+    public static final int SC_CONFLICT = 409;
+
+    /**
+     * Status code (410) indicating that the resource is no longer
+     * available at the server and no forwarding address is known.
+     * This condition <em>SHOULD</em> be considered permanent.
+     */
+
+    public static final int SC_GONE = 410;
+
+    /**
+     * Status code (411) indicating that the request cannot be handled
+     * without a defined <code><em>Content-Length</em></code>.
+     */
+
+    public static final int SC_LENGTH_REQUIRED = 411;
+
+    /**
+     * Status code (412) indicating that the precondition given in one
+     * or more of the request-header fields evaluated to false when it
+     * was tested on the server.
+     */
+
+    public static final int SC_PRECONDITION_FAILED = 412;
+
+    /**
+     * Status code (413) indicating that the server is refusing to process
+     * the request because the request entity is larger than the server is
+     * willing or able to process.
+     */
+
+    public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
+
+    /**
+     * Status code (414) indicating that the server is refusing to service
+     * the request because the <code><em>Request-URI</em></code> is longer
+     * than the server is willing to interpret.
+     */
+
+    public static final int SC_REQUEST_URI_TOO_LONG = 414;
+
+    /**
+     * Status code (415) indicating that the server is refusing to service
+     * the request because the entity of the request is in a format not
+     * supported by the requested resource for the requested method.
+     */
+
+    public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
+
+    /**
+     * Status code (500) indicating an error inside the HTTP server
+     * which prevented it from fulfilling the request.
+     */
+
+    public static final int SC_INTERNAL_SERVER_ERROR = 500;
+
+    /**
+     * Status code (501) indicating the HTTP server does not support
+     * the functionality needed to fulfill the request.
+     */
+
+    public static final int SC_NOT_IMPLEMENTED = 501;
+
+    /**
+     * Status code (502) indicating that the HTTP server received an
+     * invalid response from a server it consulted when acting as a
+     * proxy or gateway.
+     */
+
+    public static final int SC_BAD_GATEWAY = 502;
+
+    /**
+     * Status code (503) indicating that the HTTP server is
+     * temporarily overloaded, and unable to handle the request.
+     */
+
+    public static final int SC_SERVICE_UNAVAILABLE = 503;
+
+    /**
+     * Status code (504) indicating that the server did not receive
+     * a timely response from the upstream server while acting as
+     * a gateway or proxy.
+     */
+
+    public static final int SC_GATEWAY_TIMEOUT = 504;
+
+    /**
+     * Status code (505) indicating that the server does not support
+     * or refuses to support the HTTP protocol version that was used
+     * in the request message.
+     */
+
+    public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
+}
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpSession.java b/javax.servlet/src/main/java/javax/servlet/http/HttpSession.java
new file mode 100644
index 0000000..94872a1
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpSession.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>The servlet container uses this interface to create a session
+ * between an HTTP client and an HTTP server. The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows servlets to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ *     the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ *     across multiple user connections
+ * </ul>
+ *
+ * <p>When an application stores an object in or removes an object from a
+ * session, the session checks whether the object implements
+ * {@link HttpSessionBindingListener}. If it does,
+ * the servlet notifies the object that it has been bound to or unbound
+ * from the session. Notifications are sent after the binding methods complete.
+ * For session that are invalidated or expire, notifications are sent after
+ * the session has been invalidatd or expired.
+ *
+ * <p>A servlet should be able to handle cases in which
+ * the client does not choose to join a session, such as when cookies are
+ * intentionally turned off. Until the client joins the session,
+ * <code>isNew</code> returns <code>true</code>.  If the client chooses
+ * not to join
+ * the session, <code>getSession</code> will return a different session
+ * on each request, and <code>isNew</code> will always return
+ * <code>true</code>.
+ *
+ * <p>Session information is scoped only to the current web application
+ * (<code>ServletContext</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @author	Various
+ * @version	$Version$
+ *
+ *
+ * @see 	HttpSessionBindingListener
+ * @see 	HttpSessionContext
+ *
+ */
+
+public interface HttpSession {
+
+
+
+
+    /**
+     *
+     * Returns the time when this session was created, measured
+     * in milliseconds since midnight January 1, 1970 GMT.
+     *
+     * @return				a <code>long</code> specifying
+     * 					when this session was created,
+     *					expressed in
+     *					milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public long getCreationTime();
+
+
+
+
+    /**
+     *
+     * Returns a string containing the unique identifier assigned
+     * to this session. The identifier is assigned
+     * by the servlet container and is implementation dependent.
+     *
+     * @return				a string specifying the identifier
+     *					assigned to this session
+     *
+     * @exeption IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public String getId();
+
+
+
+
+    /**
+     *
+     * Returns the last time the client sent a request associated with
+     * this session, as the number of milliseconds since midnight
+     * January 1, 1970 GMT, and marked by the time the container recieved the request.
+     *
+     * <p>Actions that your application takes, such as getting or setting
+     * a value associated with the session, do not affect the access
+     * time.
+     *
+     * @return				a <code>long</code>
+     *					representing the last time
+     *					the client sent a request associated
+     *					with this session, expressed in
+     *					milliseconds since 1/1/1970 GMT
+     *
+     * @exeption IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public long getLastAccessedTime();
+
+
+    /**
+     *
+     * Specifies the time, in seconds, between client requests before the
+     * servlet container will invalidate this session.  A negative time
+     * indicates the session should never timeout.
+     *
+     * @param interval		An integer specifying the number
+     * 				of seconds
+     *
+     */
+
+    public void setMaxInactiveInterval(int interval);
+
+
+
+
+   /**
+    * Returns the maximum time interval, in seconds, that
+    * the servlet container will keep this session open between
+    * client accesses. After this interval, the servlet container
+    * will invalidate the session.  The maximum time interval can be set
+    * with the <code>setMaxInactiveInterval</code> method.
+    * A negative time indicates the session should never timeout.
+    *
+    *
+    * @return		an integer specifying the number of
+    *			seconds this session remains open
+    *			between client requests
+    *
+    * @see		#setMaxInactiveInterval
+    *
+    *
+    */
+
+    public int getMaxInactiveInterval();
+
+
+
+
+   /**
+    *
+    * @deprecated 	As of Version 2.1, this method is
+    *			deprecated and has no replacement.
+    *			It will be removed in a future
+    *			version of the Java Servlet API.
+    *
+    */
+
+    public HttpSessionContext getSessionContext();
+
+
+
+
+    /**
+     *
+     *
+     * @param name		a string specifying the name of the object
+     *
+     * @return			the object with the specified name
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public Object getValue(String name);
+
+
+
+
+    /**
+     *
+     *
+     * @return				an array of <code>String</code>
+     *					objects specifying the
+     *					names of all the objects bound to
+     *					this session
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public String[] getValueNames();
+
+
+
+
+    /**
+     *
+     *
+     * @param name			the name to which the object is bound;
+     *					cannot be null
+     *
+     * @param value			the object to be bound; cannot be null
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					invalidated session
+     *
+     */
+
+    public void putValue(String name, Object value);
+
+
+
+
+
+    /**
+     *
+     *
+     * @param name				the name of the object to
+     *						remove from this session
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					invalidated session
+     */
+
+    public void removeValue(String name);
+
+
+
+
+    /**
+     *
+     * Invalidates this session then unbinds any objects bound
+     * to it.
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					already invalidated session
+     *
+     */
+
+    public void invalidate();
+
+
+
+
+    /**
+     *
+     * Returns <code>true</code> if the client does not yet know about the
+     * session or if the client chooses not to join the session.  For
+     * example, if the server used only cookie-based sessions, and
+     * the client had disabled the use of cookies, then a session would
+     * be new on each request.
+     *
+     * @return 				<code>true</code> if the
+     *					server has created a session,
+     *					but the client has not yet joined
+     *
+     * @exception IllegalStateException	if this method is called on an
+     *					already invalidated session
+     *
+     */
+
+    public boolean isNew();
+}
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java
new file mode 100644
index 0000000..f967ad9
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingEvent.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import java.util.EventObject;
+
+
+/**
+ *
+ * Sent to an object that implements
+ * {@link HttpSessionBindingListener} when the object is
+ * bound to or unbound from the session.
+ *
+ * <p>The session binds the object by a call to
+ * <code>HttpSession.putValue</code> and unbinds the object
+ * by a call to <code>HttpSession.removeValue</code>.
+ *
+ *
+ *
+ * @author		Various
+ * @version		$Version$
+ *
+ * @see 		HttpSession
+ * @see 		HttpSessionBindingListener
+ *
+ */
+
+public class HttpSessionBindingEvent extends EventObject {
+
+
+
+
+    /* The name to which the object is being bound or unbound */
+
+    private String name;
+
+
+
+    /**
+     *
+     * Constructs an event that notifies an object that it
+     * has been bound to or unbound from a session.
+     * To receive the event, the object must implement
+     * {@link HttpSessionBindingListener}.
+     *
+     *
+     *
+     * @param session 	the session to which the object is bound or unbound
+     *
+     * @param name 	the name with which the object is bound or unbound
+     *
+     * @see			#getName
+     * @see			#getSession
+     *
+     */
+
+    public HttpSessionBindingEvent(HttpSession session, String name) {
+	super(session);
+	this.name = name;
+    }
+
+
+
+
+
+
+	/**
+	 *
+     * Returns the name with which the object is bound to or
+	 * unbound from the session.
+	 *
+	 *
+	 * @return		a string specifying the name with which
+	 *			the object is bound to or unbound from
+	 *			the session
+	 *
+	 *
+	 */
+	
+	public String getName() {
+	return name;
+	}
+
+
+
+
+
+
+    /**
+     *
+     * Returns the session to or from which the object is
+     * bound or unbound.
+     *
+     * @return		the session to which the object is
+     *			bound or from which the object is
+     *			unbound
+     *
+     *
+     *
+     */
+
+    public HttpSession getSession() {
+	return (HttpSession) getSource();
+    }
+}
+
+
+
+
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingListener.java b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingListener.java
new file mode 100644
index 0000000..f78e1fe
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionBindingListener.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import java.util.EventListener;
+
+
+
+
+
+/**
+ * Causes an object to be notified when it is bound to
+ * or unbound from a session. The object is notified
+ * by an {@link HttpSessionBindingEvent} object.
+ *
+ *
+ * @author		Various
+ * @version		$Version$
+ *
+ * @see HttpSession
+ * @see HttpSessionBindingEvent
+ *
+ */
+
+public interface HttpSessionBindingListener extends EventListener {
+
+
+
+    /**
+     *
+     * Notifies the object that it is being bound to
+     * a session and identifies the session.
+     *
+     * @param event		the event that identifies the
+     *				session
+     *
+     * @see #valueUnbound
+     *
+     */
+
+    public void valueBound(HttpSessionBindingEvent event);
+
+
+
+    /**
+     *
+     * Notifies the object that it is being unbound
+     * from a session and identifies the session.
+     *
+     * @param event		the event that identifies
+     *				the session
+     *	
+     * @see #valueBound
+     *
+     */
+
+    public void valueUnbound(HttpSessionBindingEvent event);
+
+
+}
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpSessionContext.java b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionContext.java
new file mode 100644
index 0000000..85b776a
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpSessionContext.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import java.util.Enumeration;
+
+/**
+ *
+ * @author		Various
+ * @version		$Version$
+ *
+ * @deprecated		As of Java(tm) Servlet API 2.1
+ *			for security reasons, with no replacement.
+ *			This interface will be removed in a future
+ *			version of this API.
+ *
+ * @see			HttpSession
+ * @see			HttpSessionBindingEvent
+ * @see			HttpSessionBindingListener
+ *
+ */
+
+
+public interface HttpSessionContext {
+
+    /**
+     *
+     * @deprecated 	As of Java Servlet API 2.1 with
+     *			no replacement. This method must 
+     *			return null and will be removed in
+     *			a future version of this API.
+     *
+     */
+
+    public HttpSession getSession(String sessionId);
+    
+    
+    
+  
+    /**
+     *
+     * @deprecated	As of Java Servlet API 2.1 with
+     *			no replacement. This method must return 
+     *			an empty <code>Enumeration</code> and will be removed
+     *			in a future version of this API.
+     *
+     */
+
+    public Enumeration getIds();
+}
+
+
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/HttpUtils.java b/javax.servlet/src/main/java/javax/servlet/http/HttpUtils.java
new file mode 100644
index 0000000..99e4ed6
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/HttpUtils.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1999,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 javax.servlet.http;
+
+import javax.servlet.ServletInputStream;
+import java.util.Hashtable;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.io.IOException;
+
+
+/**
+ * Provides a collection of methods that are useful
+ * in writing HTTP servlets.
+ *
+ */
+
+
+public class HttpUtils {
+
+    private static final String LSTRING_FILE =
+	"javax.servlet.http.LocalStrings";
+    private static ResourceBundle lStrings =
+	ResourceBundle.getBundle(LSTRING_FILE);
+
+    static Hashtable nullHashtable = new Hashtable();
+
+
+
+    /**
+     * Constructs an empty <code>HttpUtils</code> object.
+     *
+     */
+
+    public HttpUtils() {}
+
+
+
+
+
+    /**
+     *
+     * Parses a query string passed from the client to the
+     * server and builds a <code>HashTable</code> object
+     * with key-value pairs.
+     * The query string should be in the form of a string
+     * packaged by the GET or POST method, that is, it
+     * should have key-value pairs in the form <i>key=value</i>,
+     * with each pair separated from the next by a & character.
+     *
+     * <p>A key can appear more than once in the query string
+     * with different values. However, the key appears only once in
+     * the hashtable, with its value being
+     * an array of strings containing the multiple values sent
+     * by the query string.
+     *
+     * <p>The keys and values in the hashtable are stored in their
+     * decoded form, so
+     * any + characters are converted to spaces, and characters
+     * sent in hexadecimal notation (like <i>%xx</i>) are
+     * converted to ASCII characters.
+     *
+     * @param s		a string containing the query to be parsed
+     *
+     * @return		a <code>HashTable</code> object built
+     * 			from the parsed key-value pairs
+     *
+     * @exception IllegalArgumentException	if the query string
+     *						is invalid
+     *
+     */
+
+    static public Hashtable parseQueryString(String s) {
+
+	String valArray[] = null;
+	
+	if (s == null) {
+	    throw new IllegalArgumentException();
+	}
+	Hashtable ht = new Hashtable();
+	StringBuffer sb = new StringBuffer();
+	StringTokenizer st = new StringTokenizer(s, "&");
+	while (st.hasMoreTokens()) {
+	    String pair = (String)st.nextToken();
+	    int pos = pair.indexOf('=');
+	    if (pos == -1) {
+		// XXX
+		// should give more detail about the illegal argument
+		throw new IllegalArgumentException();
+	    }
+	    String key = parseName(pair.substring(0, pos), sb);
+	    String val = parseName(pair.substring(pos+1, pair.length()), sb);
+	    if (ht.containsKey(key)) {
+		String oldVals[] = (String []) ht.get(key);
+		valArray = new String[oldVals.length + 1];
+		for (int i = 0; i < oldVals.length; i++)
+		    valArray[i] = oldVals[i];
+		valArray[oldVals.length] = val;
+	    } else {
+		valArray = new String[1];
+		valArray[0] = val;
+	    }
+	    ht.put(key, valArray);
+	}
+	return ht;
+    }
+
+
+
+
+    /**
+     *
+     * Parses data from an HTML form that the client sends to
+     * the server using the HTTP POST method and the
+     * <i>application/x-www-form-urlencoded</i> MIME type.
+     *
+     * <p>The data sent by the POST method contains key-value
+     * pairs. A key can appear more than once in the POST data
+     * with different values. However, the key appears only once in
+     * the hashtable, with its value being
+     * an array of strings containing the multiple values sent
+     * by the POST method.
+     *
+     * <p>The keys and values in the hashtable are stored in their
+     * decoded form, so
+     * any + characters are converted to spaces, and characters
+     * sent in hexadecimal notation (like <i>%xx</i>) are
+     * converted to ASCII characters.
+     *
+     *
+     *
+     * @param len	an integer specifying the length,
+     *			in characters, of the
+     *			<code>ServletInputStream</code>
+     *			object that is also passed to this
+     *			method
+     *
+     * @param in	the <code>ServletInputStream</code>
+     *			object that contains the data sent
+     *			from the client
+     *
+     * @return		a <code>HashTable</code> object built
+     *			from the parsed key-value pairs
+     *
+     *
+     * @exception IllegalArgumentException	if the data
+     *			sent by the POST method is invalid
+     *
+     */
+
+
+    static public Hashtable parsePostData(int len,
+					  ServletInputStream in)
+    {
+	// XXX
+	// should a length of 0 be an IllegalArgumentException
+	
+	if (len <=0)
+	    return new Hashtable(); // cheap hack to return an empty hash
+
+	if (in == null) {
+	    throw new IllegalArgumentException();
+	}
+	
+	//
+	// Make sure we read the entire POSTed body.
+	//
+        byte[] postedBytes = new byte [len];
+        try {
+            int offset = 0;
+
+	    do {
+		int inputLen = in.read (postedBytes, offset, len - offset);
+		if (inputLen <= 0) {
+		    String msg = lStrings.getString("err.io.short_read");
+		    throw new IllegalArgumentException (msg);
+		}
+		offset += inputLen;
+	    } while ((len - offset) > 0);
+
+	} catch (IOException e) {
+	    throw new IllegalArgumentException(e.getMessage());
+	}
+
+        // XXX we shouldn't assume that the only kind of POST body
+        // is FORM data encoded using ASCII or ISO Latin/1 ... or
+        // that the body should always be treated as FORM data.
+        //
+
+        try {
+            String postedBody = new String(postedBytes, 0, len, "8859_1");
+            return parseQueryString(postedBody);
+        } catch (java.io.UnsupportedEncodingException e) {
+            // XXX function should accept an encoding parameter & throw this
+            // exception.  Otherwise throw something expected.
+            throw new IllegalArgumentException(e.getMessage());
+        }
+    }
+
+
+
+
+    /*
+     * Parse a name in the query string.
+     */
+
+    static private String parseName(String s, StringBuffer sb) {
+	sb.setLength(0);
+	for (int i = 0; i < s.length(); i++) {
+	    char c = s.charAt(i);
+	    switch (c) {
+	    case '+':
+		sb.append(' ');
+		break;
+	    case '%':
+		try {
+		    sb.append((char) Integer.parseInt(s.substring(i+1, i+3),
+						      16));
+		    i += 2;
+		} catch (NumberFormatException e) {
+		    // XXX
+		    // need to be more specific about illegal arg
+		    throw new IllegalArgumentException();
+		} catch (StringIndexOutOfBoundsException e) {
+		    String rest  = s.substring(i);
+		    sb.append(rest);
+		    if (rest.length()==2)
+			i++;
+		}
+		
+		break;
+	    default:
+		sb.append(c);
+		break;
+	    }
+	}
+	return sb.toString();
+    }
+
+
+
+
+    /**
+     *
+     * Reconstructs the URL the client used to make the request,
+     * using information in the <code>HttpServletRequest</code> object.
+     * The returned URL contains a protocol, server name, port
+     * number, and server path, but it does not include query
+     * string parameters.
+     *
+     * <p>Because this method returns a <code>StringBuffer</code>,
+     * not a string, you can modify the URL easily, for example,
+     * to append query parameters.
+     *
+     * <p>This method is useful for creating redirect messages
+     * and for reporting errors.
+     *
+     * @param req	a <code>HttpServletRequest</code> object
+     *			containing the client's request
+     *
+     * @return		a <code>StringBuffer</code> object containing
+     *			the reconstructed URL
+     *
+     */
+
+    public static StringBuffer getRequestURL (HttpServletRequest req) {
+	StringBuffer url = new StringBuffer ();
+	String scheme = req.getScheme ();
+	int port = req.getServerPort ();
+	String urlPath = req.getRequestURI();
+	
+	//String		servletPath = req.getServletPath ();
+	//String		pathInfo = req.getPathInfo ();
+
+	url.append (scheme);		// http, https
+	url.append ("://");
+	url.append (req.getServerName ());
+	if ((scheme.equals ("http") && port != 80)
+		|| (scheme.equals ("https") && port != 443)) {
+	    url.append (':');
+	    url.append (req.getServerPort ());
+	}
+	//if (servletPath != null)
+	//    url.append (servletPath);
+	//if (pathInfo != null)
+	//    url.append (pathInfo);
+	url.append(urlPath);
+	return url;
+    }
+}
+
+
+
diff --git a/javax.servlet/src/main/java/javax/servlet/http/LocalStrings.properties b/javax.servlet/src/main/java/javax/servlet/http/LocalStrings.properties
new file mode 100644
index 0000000..5908d24
--- /dev/null
+++ b/javax.servlet/src/main/java/javax/servlet/http/LocalStrings.properties
@@ -0,0 +1,13 @@
+# Default localized string information
+# Localized for Locale en_US
+
+err.cookie_name_is_token=Cookie name {0} is a reserved token
+err.io.negativelength=Negative Length given in write method
+err.io.short_read=Short Read
+
+http.method_not_implemented=Method {0} is not defined in RFC 2068 and is not supported by the Servlet API 
+
+http.method_get_not_supported=HTTP method GET is not supported by this URL
+http.method_post_not_supported=HTTP method POST is not supported by this URL
+http.method_put_not_supported=HTTP method PUT is not supported by this URL
+http.method_delete_not_supported=Http method DELETE is not supported by this URL
