/*
 * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.catalina.core;

import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.connector.RequestFacade;
import org.apache.catalina.session.StandardSession;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.RequestUtil;

import jakarta.servlet.AsyncContext;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.PushBuilder;
import java.io.IOException;
import java.util.*;
import jakarta.servlet.http.HttpServletMapping;
import org.apache.catalina.connector.MappingImpl;
// END GlassFish 896

/**
 * Wrapper around a <code>jakarta.servlet.http.HttpServletRequest</code>
 * that transforms an application request object (which might be the original
 * one passed to a servlet, or might be based on the 2.3
 * <code>jakarta.servlet.http.HttpServletRequestWrapper</code> class)
 * back into an internal <code>org.apache.catalina.HttpRequest</code>.
 *
 * @author Craig R. McClanahan
 * @author Remy Maucherat
 * @version $Revision: 1.15 $ $Date: 2007/05/03 21:58:54 $
 */
public class ApplicationHttpRequest extends HttpServletRequestWrapper {

    // ------------------------------------------------------- Static Variables

    /**
     * The set of attribute names that are special for request dispatchers
     */
    private static final HashSet<String> specials = new HashSet<String>(15);

    static {
        specials.add(RequestDispatcher.INCLUDE_REQUEST_URI);
        specials.add(RequestDispatcher.INCLUDE_CONTEXT_PATH);
        specials.add(RequestDispatcher.INCLUDE_SERVLET_PATH);
        specials.add(RequestDispatcher.INCLUDE_MAPPING);
        specials.add(RequestDispatcher.INCLUDE_PATH_INFO);
        specials.add(RequestDispatcher.INCLUDE_QUERY_STRING);
        specials.add(RequestDispatcher.FORWARD_REQUEST_URI);
        specials.add(RequestDispatcher.FORWARD_CONTEXT_PATH);
        specials.add(RequestDispatcher.FORWARD_SERVLET_PATH);
        specials.add(RequestDispatcher.FORWARD_MAPPING);
        specials.add(RequestDispatcher.FORWARD_PATH_INFO);
        specials.add(RequestDispatcher.FORWARD_QUERY_STRING);
        specials.add(AsyncContext.ASYNC_REQUEST_URI);
        specials.add(AsyncContext.ASYNC_CONTEXT_PATH);
        specials.add(AsyncContext.ASYNC_SERVLET_PATH);
        specials.add(AsyncContext.ASYNC_MAPPING);
        specials.add(AsyncContext.ASYNC_PATH_INFO);
        specials.add(AsyncContext.ASYNC_QUERY_STRING);
    }


    // ----------------------------------------------------------- Constructors

    /**
     * Construct a new wrapped request around the specified servlet request.
     *
     * @param request the servlet request being wrapped
     * @param context the target context of the request dispatch
     * @param crossContext true if this is a cross-context dispatch, false
     * otherwise
     * @param dispatcherType the dispatcher type
     */
    public ApplicationHttpRequest(HttpServletRequest request,
                                  Context context,
                                  boolean crossContext,
                                  HttpServletMapping mappingForDispatch,
                                  DispatcherType dispatcherType) {
        super(request);
        this.context = context;
        this.crossContext = crossContext;
        this.mappingForDispatch = mappingForDispatch;
        this.dispatcherType = dispatcherType;

        setRequest(request);

        if (context.getManager() != null) {
            isSessionVersioningSupported =
                context.getManager().isSessionVersioningSupported();
            if (isSessionVersioningSupported) {
                Map<String, String> sessionVersions =
                    getSessionVersions();
                if (sessionVersions != null) {
                    requestedSessionVersion = sessionVersions.get(
                        context.getPath());
                }
            }
        }
    }


    // ----------------------------------------------------- Instance Variables

    /**
     * The context for this request.
     */
    protected Context context = null;

    /**
     * The context path for this request.
     */
    protected String contextPath = null;

    /**
     * If this request is cross context, since this changes session access
     * behavior.
     */
    protected boolean crossContext = false;

    private HttpServletMapping mappingForDispatch;

    /**
     * The dispatcher type.
     */
    protected DispatcherType dispatcherType;

    /**
     * The request parameters for this request.  This is initialized from the
     * wrapped request, but updates are allowed.
     */
    protected Map<String, String[]> parameters = null;

    /**
     * Have the parameters for this request already been parsed?
     */
    private boolean parsedParams = false;

    /**
     * The path information for this request.
     */
    protected String pathInfo = null;

    /**
     * The query parameters for the current request.
     */
    private String queryParamString = null;

    /**
     * The query string for this request.
     */
    protected String queryString = null;

    /**
     * The current request dispatcher path.
     */
    protected Object requestDispatcherPath = null;

    /**
     * The request URI for this request.
     */
    protected String requestURI = null;

    /**
     * The servlet path for this request.
     */
    protected String servletPath = null;

    /**
     * The currently active session for this request.
     */
    protected Session session = null;

    /**
     * Special attributes.
     */
    private HashMap<String, Object> specialAttributes = null;

    private String requestedSessionVersion = null;

    private boolean isSessionVersioningSupported = false;


    // ------------------------------------------------- ServletRequest Methods

    /**
     * Override the <code>getAttribute()</code> method of the wrapped request.
     *
     * @param name Name of the attribute to retrieve
     */
    @Override
    public Object getAttribute(String name) {

        if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
            if ( requestDispatcherPath != null ){
                return requestDispatcherPath.toString();
            } else {
                return null;
            }
        }

        if (!isSpecial(name)) {
            return getRequest().getAttribute(name);
        } else {
            Object value = null;
            if (specialAttributes != null) {
                value = specialAttributes.get(name);
            }
            if (value == null && name.startsWith("jakarta.servlet.forward")) {
                /*
                 * If it's a forward special attribute, and null, delegate
                 * to the wrapped request. This will allow access to the
                 * forward special attributes from a request that was first
                 * forwarded and then included, or forwarded multiple times
                 * in a row.
                 * Notice that forward special attributes are set only on
                 * the wrapper that was created for the initial forward
                 * (i.e., the top-most wrapper for a request that was
                 * forwarded multiple times in a row, and never included,
                 * will not contain any specialAttributes!).
                 * This is different from an include, where the special
                 * include attributes are set on every include wrapper.
                 */
                value = getRequest().getAttribute(name);
            }
            return value;
        }

    }


    /**
     * Override the <code>getAttributeNames()</code> method of the wrapped
     * request.
     */
    @Override
    public Enumeration<String> getAttributeNames() {
        return (new AttributeNamesEnumerator());
    }

    /**
     * Override the <code>removeAttribute()</code> method of the
     * wrapped request.
     *
     * @param name Name of the attribute to remove
     */
    @Override
    public void removeAttribute(String name) {

        if (isSpecial(name)) {
            if (specialAttributes != null) {
                specialAttributes.remove(name);
            }
        } else {
            getRequest().removeAttribute(name);
        }
    }


    /**
     * Override the <code>setAttribute()</code> method of the
     * wrapped request.
     *
     * @param name Name of the attribute to set
     * @param value Value of the attribute to set
     */
    @Override
    public void setAttribute(String name, Object value) {

        if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
            requestDispatcherPath = value;
            return;
        }

        if (isSpecial(name)) {
            if (specialAttributes != null) {
                specialAttributes.put(name, value);
            }
        } else {
            getRequest().setAttribute(name, value);
        }
    }


    /**
     * Return a RequestDispatcher that wraps the resource at the specified
     * path, which may be interpreted as relative to the current request path.
     *
     * @param path Path of the resource to be wrapped
     */
    @Override
    public RequestDispatcher getRequestDispatcher(String path) {

        if (context == null)
            return (null);

        // If the path is already context-relative, just pass it through
        if (path == null)
            return (null);
        else if (path.startsWith("/"))
            return (context.getServletContext().getRequestDispatcher(path));

        // Convert a request-relative path to a context-relative one
        String servletPath =
            (String) getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
        if (servletPath == null)
            servletPath = getServletPath();

        // Add the path info, if there is any
        String pathInfo = getPathInfo();
        String requestPath = null;

        if (pathInfo == null) {
            requestPath = servletPath;
        } else {
            requestPath = servletPath + pathInfo;
        }

        int pos = requestPath.lastIndexOf('/');
        String relative = null;
        if (pos >= 0) {
            relative = requestPath.substring(0, pos + 1) + path;
        } else {
            relative = requestPath + path;
        }

        return (context.getServletContext().getRequestDispatcher(relative));

    }


    @Override
    public DispatcherType getDispatcherType() {
        return dispatcherType;
    }


    // --------------------------------------------- HttpServletRequest Methods


    /**
     * Override the <code>getContextPath()</code> method of the wrapped
     * request.
     */
    @Override
    public String getContextPath() {

        return (this.contextPath);

    }


    /**
     * Override the <code>getParameter()</code> method of the wrapped request.
     *
     * @param name Name of the requested parameter
     */
    @Override
    public String getParameter(String name) {

        parseParameters();
        synchronized (parameters) {
            String[] value = parameters.get(name);
            return ((value != null) ? value[0] : null);
        }

    }


    /**
     * Override the <code>getParameterMap()</code> method of the
     * wrapped request.
     */
    @Override
    public Map<String, String[]> getParameterMap() {

        parseParameters();
        return (parameters);

    }


    /**
     * Override the <code>getParameterNames()</code> method of the
     * wrapped request.
     */
    @Override
    public Enumeration<String> getParameterNames() {

        parseParameters();
        synchronized (parameters) {
            return (new Enumerator<String>(parameters.keySet()));
        }

    }


    /**
     * Override the <code>getParameterValues()</code> method of the
     * wrapped request.
     *
     * @param name Name of the requested parameter
     */
    @Override
    public String[] getParameterValues(String name) {

        parseParameters();
        synchronized (parameters) {
            String[] value = parameters.get(name);
            return value;
        }

    }


    /**
     * Override the <code>getPathInfo()</code> method of the wrapped request.
     */
    @Override
    public String getPathInfo() {

        return (this.pathInfo);

    }


    /**
     * Override the <code>getQueryString()</code> method of the wrapped
     * request.
     */
    @Override
    public String getQueryString() {

        return (this.queryString);

    }


    /**
     * Override the <code>getRequestURI()</code> method of the wrapped
     * request.
     */
    @Override
    public String getRequestURI() {

        return (this.requestURI);

    }


    /**
     * Override the <code>getRequestURL()</code> method of the wrapped
     * request.
     */
    @Override
    public StringBuffer getRequestURL() {

        StringBuffer url = new StringBuffer();
        String scheme = getScheme();
        int port = getServerPort();
        if (port < 0)
            port = 80; // Work around java.net.URL bug

        url.append(scheme);
        url.append("://");
        url.append(getServerName());
        if ((scheme.equals("http") && (port != 80))
            || (scheme.equals("https") && (port != 443))) {
            url.append(':');
            url.append(port);
        }
        url.append(getRequestURI());

        return (url);
    }

    @Override
    public HttpServletMapping getHttpServletMapping() {
        HttpServletMapping result = null;
        switch (dispatcherType) {
        case INCLUDE:
            // Safe to cast because we received this in the ctor
            // as an HttpServletRequest.
            result = ((HttpServletRequest)getRequest()).getHttpServletMapping();
            break;
        case ASYNC:
        case FORWARD:
        case ERROR:
            result = mappingForDispatch;
            break;
        default: // REQUEST
            break;
        }

        return result;
    }

    /**
     * Override the <code>getServletPath()</code> method of the wrapped
     * request.
     */
    @Override
    public String getServletPath() {

        return (this.servletPath);

    }


    /**
     * Return the session associated with this Request, creating one
     * if necessary.
     */
    @Override
    public HttpSession getSession() {
        return (getSession(true));
    }


    /**
     * Return the session associated with this Request, creating one
     * if necessary and requested.
     *
     * @param create Create a new session if one does not exist
     */
    @Override
    public HttpSession getSession(boolean create) {

        if (crossContext) {

            // There cannot be a session if no context has been assigned yet
            if (context == null)
                return (null);

            // Return the current session if it exists and is valid
            if (session != null && session.isValid()) {
                return (session.getSession());
            }

            HttpSession other = super.getSession(false);
            if (create && (other == null)) {
                // First create a session in the first context: the problem is
                // that the top level request is the only one which can
                // create the cookie safely
                other = super.getSession(true);
            }
            if (other != null) {
                Session localSession = null;
                try {
                    if (isSessionVersioningSupported) {
                        localSession =
                            context.getManager().findSession(
                                other.getId(),
                                requestedSessionVersion);
                        //XXX need to revisit
                        if (localSession instanceof StandardSession) {
                            incrementSessionVersion((StandardSession) localSession,
                                                    context);
                        }
                    } else {
                        localSession =
                            context.getManager().findSession(other.getId());
                    }
                } catch (IOException e) {
                    // Ignore
                }

                if ((localSession != null) && !localSession.isValid()) {
                    localSession = null;
                } else if (localSession == null && create) {
                    //START OF 6364900
                    localSession =
                        context.getManager().createSession(other.getId());
                    //XXX need to revisit
                    if (isSessionVersioningSupported &&
                            localSession instanceof StandardSession) {
                        incrementSessionVersion((StandardSession) localSession,
                                                context);
                    }
                    //END OF 6364900
                    /* CR 6364900
                    localSession = context.getManager().createEmptySession();
                    localSession.setNew(true);
                    localSession.setValid(true);
                    localSession.setCreationTime(System.currentTimeMillis());
                    localSession.setMaxInactiveInterval
                        (context.getManager().getMaxInactiveIntervalSeconds());
                    localSession.setId(other.getId());
                    */
                    // START GlassFish 896
                    RequestFacadeHelper reqFacHelper = RequestFacadeHelper.getInstance(getRequest());
                    if (reqFacHelper != null) {
                        reqFacHelper.track(localSession);
                    }
                    // END GlassFish 896
                }
                if (localSession != null) {
                    localSession.access();
                    session = localSession;
                    return session.getSession();
                }
            }
            return null;

        } else {
            return super.getSession(create);
        }

    }


    /**
     * Returns true if the request specifies a JSESSIONID that is valid within
     * the context of this ApplicationHttpRequest, false otherwise.
     *
     * @return true if the request specifies a JSESSIONID that is valid within
     * the context of this ApplicationHttpRequest, false otherwise.
     */
    @Override
    public boolean isRequestedSessionIdValid() {

        if (crossContext) {

            String requestedSessionId = getRequestedSessionId();
            if (requestedSessionId == null)
                return (false);
            if (context == null)
                return (false);

            if (session != null
                    && requestedSessionId.equals(session.getIdInternal())) {
                return session.isValid();
            }

            Manager manager = context.getManager();
            if (manager == null)
                return (false);
            Session localSession = null;
            try {
                if (isSessionVersioningSupported) {
                    localSession = manager.findSession(requestedSessionId,
                                                       requestedSessionVersion);
                } else {
                    localSession = manager.findSession(requestedSessionId);
                }
            } catch (IOException e) {
                localSession = null;
            }
            if ((localSession != null) && localSession.isValid()) {
                return (true);
            } else {
                return (false);
            }

        } else {
            return super.isRequestedSessionIdValid();
        }
    }

    @Override
    public PushBuilder newPushBuilder() {
        return ((HttpServletRequest)getRequest()).newPushBuilder();
    }

    // -------------------------------------------------------- Package Methods

    /**
     * Recycle this request
     */
    public void recycle() {
        if (session != null) {
            session.endAccess();
        }
    }

    /**
     * Perform a shallow copy of the specified Map, and return the result.
     *
     * @param orig Origin Map to be copied
     */
    void copyMap(Map<String, String[]> orig, Map<String, String[]> dest) {

        if (orig == null)
            return;
        synchronized (orig) {
            for (Map.Entry<String, String[]> entry : orig.entrySet()) {
                dest.put(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Set the context path for this request.
     *
     * @param contextPath The new context path
     */
    void setContextPath(String contextPath) {
        this.contextPath = contextPath;
    }

    /**
     * Set the path information for this request.
     *
     * @param pathInfo The new path info
     */
    void setPathInfo(String pathInfo) {
        this.pathInfo = pathInfo;
    }

    /**
     * Set the query string for this request.
     *
     * @param queryString The new query string
     */
    void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    /**
     * Set the request that we are wrapping.
     *
     * @param request The new wrapped request
     */
    void setRequest(HttpServletRequest request) {

        super.setRequest(request);

        // Initialize the attributes for this request
        requestDispatcherPath =
            request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);

        // Initialize the path elements for this request
        contextPath = request.getContextPath();
        pathInfo = request.getPathInfo();
        queryString = request.getQueryString();
        requestURI = request.getRequestURI();
        servletPath = request.getServletPath();

    }

    /**
     * Set the request URI for this request.
     *
     * @param requestURI The new request URI
     */
    void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    /**
     * Set the servlet path for this request.
     *
     * @param servletPath The new servlet path
     */
    void setServletPath(String servletPath) {
        this.servletPath = servletPath;
    }

    /**
     * Parses the parameters of this request.
     *
     * If parameters are present in both the query string and the request
     * content, they are merged.
     */
    void parseParameters() {
        if (parsedParams) {
            return;
        }

        parameters = new HashMap<String, String[]>();
        synchronized (parameters) {
            copyMap(getRequest().getParameterMap(), parameters);
            mergeParameters();
            parsedParams = true;
        }
    }

    /**
     * Save query parameters for this request.
     *
     * @param queryString The query string containing parameters for this
     *                    request
     */
    void setQueryParams(String queryString) {
        this.queryParamString = queryString;
    }


    // ------------------------------------------------------ Protected Methods

    /**
     * Is this attribute name one of the special ones that is added only for
     * included servlets?
     *
     * @param name Attribute name to be tested
     */
    protected boolean isSpecial(String name) {
        return specials.contains(name);
    }

    /**
     * Initializes the special attributes of this request wrapper.
     *
     * @param requestUri The request URI
     * @param contextPath The context path
     * @param servletPath The servlet path
     * @param pathInfo The path info
     * @param queryString The query string
     */
    void initSpecialAttributes(String requestUri,
                               String contextPath,
                               String servletPath,
                               String pathInfo,
                               String queryString) {
        specialAttributes = new HashMap<String, Object>(5);
        HttpServletMapping originalMapping;

        switch (dispatcherType) {
        case INCLUDE:
            specialAttributes.put(RequestDispatcher.INCLUDE_REQUEST_URI,
                                  requestUri);
            specialAttributes.put(RequestDispatcher.INCLUDE_CONTEXT_PATH,
                                  contextPath);
            specialAttributes.put(RequestDispatcher.INCLUDE_SERVLET_PATH,
                                  servletPath);
            specialAttributes.put(RequestDispatcher.INCLUDE_MAPPING,
                                  mappingForDispatch);
            specialAttributes.put(RequestDispatcher.INCLUDE_PATH_INFO,
                                  pathInfo);
            specialAttributes.put(RequestDispatcher.INCLUDE_QUERY_STRING,
                                  queryString);
            break;
        case FORWARD:
        case ERROR:
            specialAttributes.put(RequestDispatcher.FORWARD_REQUEST_URI,
                                  requestUri);
            specialAttributes.put(RequestDispatcher.FORWARD_CONTEXT_PATH,
                                  contextPath);
            specialAttributes.put(RequestDispatcher.FORWARD_SERVLET_PATH,
                                  servletPath);
            specialAttributes.put(RequestDispatcher.FORWARD_PATH_INFO,
                                  pathInfo);
            specialAttributes.put(RequestDispatcher.FORWARD_QUERY_STRING,
                                  queryString);
            // Safe to cast because we received it in the ctor as HttpServletRequest
            originalMapping = ((HttpServletRequest)getRequest()).getHttpServletMapping();
            specialAttributes.put(RequestDispatcher.FORWARD_MAPPING, originalMapping);
            break;
        case ASYNC:
            specialAttributes.put(AsyncContext.ASYNC_REQUEST_URI,
                                  requestUri);
            specialAttributes.put(AsyncContext.ASYNC_CONTEXT_PATH,
                                  contextPath);
            specialAttributes.put(AsyncContext.ASYNC_SERVLET_PATH,
                                  servletPath);
            // Safe to cast because we received it in the ctor as HttpServletRequest
            originalMapping = ((HttpServletRequest)getRequest()).getHttpServletMapping();
            specialAttributes.put(AsyncContext.ASYNC_MAPPING,
                                  originalMapping);
            specialAttributes.put(AsyncContext.ASYNC_PATH_INFO,
                                  pathInfo);
            specialAttributes.put(AsyncContext.ASYNC_QUERY_STRING,
                                  queryString);
            break;
        default: // REQUEST
            break;
        }
    }

    /**
     * Merge the two sets of parameter values into a single String array.
     *
     * @param values1 First set of values
     * @param values2 Second set of values
     */
    protected String[] mergeValues(Object values1, Object values2) {

        ArrayList<String> results = new ArrayList<String>();

        if (values1 == null)
            ;
        else if (values1 instanceof String)
            results.add((String)values1);
        else if (values1 instanceof String[]) {
            String values[] = (String[]) values1;
            for (int i = 0; i < values.length; i++)
                results.add(values[i]);
        } else
            results.add(values1.toString());

        if (values2 == null)
            ;
        else if (values2 instanceof String)
            results.add((String)values2);
        else if (values2 instanceof String[]) {
            String values[] = (String[]) values2;
            for (int i = 0; i < values.length; i++)
                results.add(values[i]);
        } else
            results.add(values2.toString());

        String values[] = new String[results.size()];
        return results.toArray(values);

    }


    // ------------------------------------------------------ Private Methods

    /**
     * Merge the parameters from the saved query parameter string (if any), and
     * the parameters already present on this request (if any), such that the
     * parameter values from the query string show up first if there are
     * duplicate parameter names.
     */
    private void mergeParameters() {

        if ((queryParamString == null) || (queryParamString.length() < 1)) {
            return;
        }

        HashMap<String, String[]> queryParameters = new HashMap<String, String[]>();
        String encoding = getCharacterEncoding();
        if (encoding == null)
            encoding = Globals.ISO_8859_1_ENCODING;
        try {
            RequestUtil.parseParameters
                (queryParameters, queryParamString, encoding);
        } catch (Exception e) {
            // Ignore
        }
        synchronized (parameters) {
            // Merge any query parameters whose names are present in the
            // original parameter map
            Iterator<String> keys = parameters.keySet().iterator();
            while (keys.hasNext()) {
                String key = keys.next();
                Object queryValue = queryParameters.get(key);
                if (queryValue != null) {
                    parameters.put
                        (key, mergeValues(queryValue, parameters.get(key)));
                }
            }
            // Add any query parameters whose names are not present in the
            // original parameter map
            for (Map.Entry<String, String[]> e : queryParameters.entrySet()) {
                String key = e.getKey();
                if (parameters.get(key) == null) {
                    parameters.put(key, e.getValue());
                }
            }
        }
    }


    @SuppressWarnings("unchecked")
    private Map<String, String> getSessionVersions() {
        return (Map<String, String>) getAttribute(
                Globals.SESSION_VERSIONS_REQUEST_ATTRIBUTE);
    }


    // ----------------------------------- AttributeNamesEnumerator Inner Class

    /**
     * Utility class used to expose the special attributes as being available
     * as request attributes.
     */
    protected class AttributeNamesEnumerator implements Enumeration<String> {

        protected Enumeration<String> parentEnumeration = null;
        protected String next = null;
        private Iterator<String> specialNames = null;

        public AttributeNamesEnumerator() {
            parentEnumeration = getRequest().getAttributeNames();
            if (specialAttributes != null) {
                specialNames = specialAttributes.keySet().iterator();
            }
        }

        public boolean hasMoreElements() {
            return (specialNames != null && specialNames.hasNext())
                    || (next != null)
                    || ((next = findNext()) != null);
        }

        public String nextElement() {

            if (specialNames != null && specialNames.hasNext()) {
                return specialNames.next();
            }

            String result = next;
            if (next != null) {
                next = findNext();
            } else {
                throw new NoSuchElementException();
            }
            return result;
        }

        protected String findNext() {
            String result = null;
            while ((result == null) && (parentEnumeration.hasMoreElements())) {
                String current = parentEnumeration.nextElement();
                if (!isSpecial(current) ||
                        (!dispatcherType.equals(DispatcherType.FORWARD) &&
                        current.startsWith("jakarta.servlet.forward") &&
                        getAttribute(current) != null)) {
                    result = current;
                }
            }
            return result;
        }
    }

    /**
     * Increments the version of the given session, and stores it as a
     * request attribute, so it can later be included in a response cookie.
     */
    private void incrementSessionVersion(StandardSession ss,
                                         Context context) {
        if (ss == null || context == null) {
            return;
        }

        String versionString = Long.toString(ss.incrementVersion());
        Map<String, String> sessionVersions = getSessionVersions();
        if (sessionVersions == null) {
            sessionVersions = new HashMap<String, String>();
            setAttribute(Globals.SESSION_VERSIONS_REQUEST_ATTRIBUTE,
                         sessionVersions);
        }
        String path = context.getPath();
        if ("".equals(path)) {
            path = "/";
        }
        sessionVersions.put(path, versionString);
    }

    /**
     * Gets the facade for the request implementation object.
     */
    public RequestFacade getRequestFacade() {
        if (getRequest() instanceof RequestFacade) {
            return ((RequestFacade) (getRequest()));
        } else {
            return ((ApplicationHttpRequest) (getRequest())).getRequestFacade();
        }
    }
}
