public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Disallow any direct access to resources under WEB-INF or META-INF
        MessageBytes requestPathMB = request.getRequestPathMB();
        if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
            || (requestPathMB.equalsIgnoreCase("/META-INF"))
            || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
            || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
        	notFound(response);
            return;
        }

        // Wait if we are reloading
        boolean reloaded = false;
        while (context.getPaused()) {
            reloaded = true;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                ;
            }
        }

        // Reloading will have stopped the old webappclassloader and
        // created a new one
        if (reloaded &&
                context.getLoader() != null &&
                context.getLoader().getClassLoader() != null) {
            Thread.currentThread().setContextClassLoader(
                    context.getLoader().getClassLoader());
        }

        // Select the Wrapper to be used for this Request
        Wrapper wrapper = request.getWrapper();
        if (wrapper == null) {
            notFound(response);
            return;
        } else if (wrapper.isUnavailable()) {
            // May be as a result of a reload, try and find the new wrapper
            wrapper = (Wrapper) container.findChild(wrapper.getName());
            if (wrapper == null) {
                notFound(response);
                return;
            }
        }
        
        // Acknowledge the request
        try {
            response.sendAcknowledgement();
        } catch (IOException ioe) {
            container.getLogger().error(MESSAGES.errorAcknowledgingRequest("standardContextValve.acknowledgeException"), ioe);
            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }

        // Normal request processing
        Object instances[] = context.getApplicationEventListeners();

        ServletRequestEvent event = null;

        if ((instances != null) 
                && (instances.length > 0)) {
            event = new ServletRequestEvent
                (((StandardContext) container).getServletContext(), 
                 request.getRequest());
            // create pre-service event
            for (int i = 0; i < instances.length; i++) {
                if (instances[i] == null)
                    continue;
                if (!(instances[i] instanceof ServletRequestListener))
                    continue;
                ServletRequestListener listener =
                    (ServletRequestListener) instances[i];
                try {
                    listener.requestInitialized(event);
                } catch (Throwable t) {
                    container.getLogger().error(MESSAGES.requestListenerInitException(instances[i].getClass().getName()), t);
                    ServletRequest sreq = request.getRequest();
                    sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t);
                    return;
                }
            }
        }
        boolean batchStarted = context.enterSipAppHa(false);
        
    	//the line below was replaced by the whole bunch of code because getting the parameter from the request is causing
    	//JRuby-Rails persistence to fail, go figure...
//			String sipApplicationKey = request.getParameter(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME);
    	
    	String sipApplicationKey = null;
    	String queryString = request.getQueryString();
    	if(queryString != null) {
        	int indexOfSipAppKey = queryString.indexOf(MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME);
        		        	
        	if(indexOfSipAppKey != -1) {
        		// +1 to remove the = sign also
        		String sipAppKeyParam = queryString.substring(indexOfSipAppKey + MobicentsSipApplicationSession.SIP_APPLICATION_KEY_PARAM_NAME.length() + 1);
        		int indexOfPoundSign = sipAppKeyParam.indexOf("&");
        		if(indexOfPoundSign != -1) {
        			sipAppKeyParam = sipAppKeyParam.substring(0, indexOfPoundSign);
        		} 
        		sipApplicationKey = sipAppKeyParam;
        	}
    	}
    	
    	MobicentsSipApplicationSession sipApplicationSessionImpl = null;
		if(sipApplicationKey != null && sipApplicationKey.length() > 0) {
			try {
				SipApplicationSessionKey sipApplicationSessionKey = 
					SessionManagerUtil.parseSipApplicationSessionKey(sipApplicationKey);
				sipApplicationSessionImpl = 
					((SipManager)context.getManager()).getSipApplicationSession(sipApplicationSessionKey, false);
				sipApplicationSessionImpl.addHttpSession(request.getSession());
			} catch (ParseException pe) {
				logger.error("Unexpected exception while parsing the sip application session key" + sipApplicationKey, pe);
			}
		} else {
			// Fix for Issue 882 : HTTP requests to a SIP application always create an HTTP session, even for static resources
			// Don't create an http session if not already created
			final HttpSession httpSession = request.getSession(false);
			if(httpSession != null) {
				context.getSipFactoryFacade().storeHttpSession(httpSession);
				ConvergedSession convergedSession = (ConvergedSession) httpSession;
				sipApplicationSessionImpl = convergedSession.getApplicationSession(false);
			}
		}
		// Fix for http://code.google.com/p/mobicents/issues/detail?id=1386 : 
		// Ensure SipApplicationSession concurrency control on converged HTTP apps
		context.enterSipApp(sipApplicationSessionImpl, null, false, true);
		try {
			wrapper.getPipeline().getFirst().invoke(request, response);
		} finally {
	        context.exitSipApp(sipApplicationSessionImpl, null);
	        context.exitSipAppHa(null, null, batchStarted);
		}
        // Fix for Issue 882 :remove the http session from the thread local to avoid any leaking of the session
        context.getSipFactoryFacade().removeHttpSession();
        
        if ((instances !=null ) &&
                (instances.length > 0)) {
            // create post-service event
            for (int i = 0; i < instances.length; i++) {
                if (instances[i] == null)
                    continue;
                if (!(instances[i] instanceof ServletRequestListener))
                    continue;
                ServletRequestListener listener =
                    (ServletRequestListener) instances[i];
                try {
                    listener.requestDestroyed(event);
                } catch (Throwable t) {
                    container.getLogger().error(MESSAGES.requestListenerDestroyException(instances[i].getClass().getName()), t);
                    ServletRequest sreq = request.getRequest();
                    sreq.setAttribute(RequestDispatcher.ERROR_EXCEPTION,t);
                }
            }
        }
                
    }
public final void invoke ( Request request , Response response ) throws IOException , ServletException { MessageBytes requestPathMB = request . getRequestPathMB ( ) ; if ( ( requestPathMB . startsWithIgnoreCase ( "/META-INF/" , 0 ) ) || ( requestPathMB . equalsIgnoreCase ( "/META-INF" ) ) || ( requestPathMB . startsWithIgnoreCase ( "/WEB-INF/" , 0 ) ) || ( requestPathMB . equalsIgnoreCase ( "/WEB-INF" ) ) ) { notFound ( response ) ; return ; } boolean reloaded = false ; while ( context . getPaused ( ) ) { reloaded = true ; try { Thread . sleep ( 1000 ) ; } catch ( InterruptedException e ) { ; } } if ( reloaded && context . getLoader ( ) != null && context . getLoader ( ) . getClassLoader ( ) != null ) { Thread . currentThread ( ) . setContextClassLoader ( context . getLoader ( ) . getClassLoader ( ) ) ; } Wrapper wrapper = request . getWrapper ( ) ; if ( wrapper == null ) { notFound ( response ) ; return ; } else if ( wrapper . isUnavailable ( ) ) { wrapper = ( Wrapper ) container . findChild ( wrapper . getName ( ) ) ; if ( wrapper == null ) { notFound ( response ) ; return ; } } try { response . sendAcknowledgement ( ) ; } catch ( IOException ioe ) { container . getLogger ( ) . error ( MESSAGES . errorAcknowledgingRequest ( "standardContextValve.acknowledgeException" ) , ioe ) ; request . setAttribute ( RequestDispatcher . ERROR_EXCEPTION , ioe ) ; response . sendError ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR ) ; return ; } Object instances [ ] = context . getApplicationEventListeners ( ) ; ServletRequestEvent event = null ; if ( ( instances != null ) && ( instances . length > 0 ) ) { event = new ServletRequestEvent ( ( ( StandardContext ) container ) . getServletContext ( ) , request . getRequest ( ) ) ; for ( int i = 0 ; i < instances . length ; i ++ ) { if ( instances [ i ] == null ) continue ; if ( ! ( instances [ i ] instanceof ServletRequestListener ) ) continue ; ServletRequestListener listener = ( ServletRequestListener ) instances [ i ] ; try { listener . requestInitialized ( event ) ; } catch ( Throwable t ) { container . getLogger ( ) . error ( MESSAGES . requestListenerInitException ( instances [ i ] . getClass ( ) . getName ( ) ) , t ) ; ServletRequest sreq = request . getRequest ( ) ; sreq . setAttribute ( RequestDispatcher . ERROR_EXCEPTION , t ) ; return ; } } } boolean batchStarted = context . enterSipAppHa ( false ) ; String sipApplicationKey = null ; String queryString = request . getQueryString ( ) ; if ( queryString != null ) { int indexOfSipAppKey = queryString . indexOf ( MobicentsSipApplicationSession . SIP_APPLICATION_KEY_PARAM_NAME ) ; if ( indexOfSipAppKey != - 1 ) { String sipAppKeyParam = queryString . substring ( indexOfSipAppKey + MobicentsSipApplicationSession . SIP_APPLICATION_KEY_PARAM_NAME . length ( ) + 1 ) ; int indexOfPoundSign = sipAppKeyParam . indexOf ( "&" ) ; if ( indexOfPoundSign != - 1 ) { sipAppKeyParam = sipAppKeyParam . substring ( 0 , indexOfPoundSign ) ; } sipApplicationKey = sipAppKeyParam ; } } MobicentsSipApplicationSession sipApplicationSessionImpl = null ; if ( sipApplicationKey != null && sipApplicationKey . length ( ) > 0 ) { try { SipApplicationSessionKey sipApplicationSessionKey = SessionManagerUtil . parseSipApplicationSessionKey ( sipApplicationKey ) ; sipApplicationSessionImpl = ( ( SipManager ) context . getManager ( ) ) . getSipApplicationSession ( sipApplicationSessionKey , false ) ; sipApplicationSessionImpl . addHttpSession ( request . getSession ( ) ) ; } catch ( ParseException pe ) { logger . error ( "Unexpected exception while parsing the sip application session key" + sipApplicationKey , pe ) ; } } else { final HttpSession httpSession = request . getSession ( false ) ; if ( httpSession != null ) { context . getSipFactoryFacade ( ) . storeHttpSession ( httpSession ) ; ConvergedSession convergedSession = ( ConvergedSession ) httpSession ; sipApplicationSessionImpl = convergedSession . getApplicationSession ( false ) ; } } context . enterSipApp ( sipApplicationSessionImpl , null , false , true ) ; try { wrapper . getPipeline ( ) . getFirst ( ) . invoke ( request , response ) ; } finally { context . exitSipApp ( sipApplicationSessionImpl , null ) ; context . exitSipAppHa ( null , null , batchStarted ) ; } context . getSipFactoryFacade ( ) . removeHttpSession ( ) ; if ( ( instances != null ) && ( instances . length > 0 ) ) { for ( int i = 0 ; i < instances . length ; i ++ ) { if ( instances [ i ] == null ) continue ; if ( ! ( instances [ i ] instanceof ServletRequestListener ) ) continue ; ServletRequestListener listener = ( ServletRequestListener ) instances [ i ] ; try { listener . requestDestroyed ( event ) ; } catch ( Throwable t ) { container . getLogger ( ) . error ( MESSAGES . requestListenerDestroyException ( instances [ i ] . getClass ( ) . getName ( ) ) , t ) ; ServletRequest sreq = request . getRequest ( ) ; sreq . setAttribute ( RequestDispatcher . ERROR_EXCEPTION , t ) ; } } } }
Select the appropriate child Wrapper to process this request,
based on the specified request URI.  If no matching Wrapper can
be found, return an appropriate HTTP error.

@param request Request to be processed
@param response Response to be produced
@param valveContext Valve context used to forward to the next Valve

@exception IOException if an input/output error occurred
@exception ServletException if a servlet error occurred