docs: protected HttpSession getIHttpSession(HttpServletRequest _request, HttpServletResponse _response, boolean create, boolean cacheOnly)
    {
      // create local variable - JIT performance improvement
      final boolean isTraceOn = com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled();
      if (isTraceOn && LoggingUtil.SESSION_LOGGER_CORE.isLoggable(Level.FINE))
      {
        LoggingUtil.SESSION_LOGGER_CORE.entering(methodClassName, methodNames[GET_IHTTP_SESSION], "createIfAbsent = " + create);
      }
  
      HttpSession session = null;
  
      SessionAffinityContext sac = getSessionAffinityContext(_request);
      
      if (!sac.isFirstSessionIdValid() && !sac.isAllSessionIdsSetViaSet()) { //PM89885
              List allSessionIds = _sam.getAllCookieValues(_request);
              sac.setAllSessionIds(allSessionIds);
              _sam.setNextId(sac); // we got rid of the first one in setAllSessionIds, get the next one so that we have an id to work with
      }
      
      String id = _sam.getInUseSessionID(_request, sac);
  
      /*
       * PK68691 retrieve header $WSFO set by Plugin. This header indicates the
       * failover request. Session manager will drop the in-memory session and
       * retrieves the latest session copy from the backend if the incoming
       * request is the failover one.
       */
      if ( (id != null) && (Boolean.valueOf(_request.getHeader("$WSFO")).booleanValue()) ) {
          IStore iStore = _coreHttpSessionManager.getIStore();
          iStore.removeFromMemory( id );
      }
  
      if (id != null) {
          if ( (!cacheOnly) || (_coreHttpSessionManager.getIStore().getFromMemory(id) != null)) {
              session = (HttpSession) _coreHttpSessionManager.getSession(_request, _response, sac, false); // don't create here
          }
      }
  
      if (session != null)
      { // we got existing session
        id = _sam.getInUseSessionID(_request, sac); // cmd 408029 - id may have
        // changed if we received
        // multiple session cookies
        if (session.getMaxInactiveInterval() == 0)
        {
          // Max Inact of 0 implies session is invalid -- set by remote
          // invalidateAll processing
          // we expect invalidator thread to clean it up, but if app requests the
          // session before that
          // happens, invalidate it here so it isn't given back out to app.
          session.invalidate();
          session = null;
        }
        else if (!id.equals(session.getId()))
        { // always do basic crossover check
          Object parms[] = new Object[] { getAppName(), session.getId(), id };
          // Needed to create a LogRecord so we could have parameters and a
          // throwable in the same log
          LoggingUtil.logParamsAndException(LoggingUtil.SESSION_LOGGER_CORE, Level.SEVERE, methodClassName, methodNames[GET_IHTTP_SESSION], "SessionContext.CrossoverOnRetrieve",
                                            parms, new SessionCrossoverStackTrace());
          session = null; // don't give out wrong session, but if create
          // is true, we'll continue to create new session
        }
        else if (_smc.isDebugSessionCrossover() && (crossoverCheck(_request, session)))
        { // crossover detection
          // must be enabled by DebugSessionCrossover property
          Object parms[] = new Object[] { _sap.getAppName(), session.getId(), getCurrentSessionId() };
          // Needed to create a LogRecord so we could have parameters and a
          // throwable in the same log
          LoggingUtil.logParamsAndException(LoggingUtil.SESSION_LOGGER_CORE, Level.SEVERE, methodClassName, methodNames[GET_IHTTP_SESSION], "SessionContext.CrossoverOnRetrieve",
                                            parms, new SessionCrossoverStackTrace());
          session = null;
        }
      }
  
      boolean createdOnThisRequest = false;
      if ((session == null) && create)
      {
        // PK80439: Validate that session id meets length requirements
        boolean reuseId = shouldReuseId(_request,sac) && 
                            checkSessionIdIsRightLength(_sam.getInUseSessionID(_request, sac)); 
        session = (HttpSession) _coreHttpSessionManager.createSession(_request, _response, sac, reuseId);
        createdOnThisRequest = true;
      }
  
      SessionData sd = (SessionData) session;
  
  
      if (sd != null) {
          // security integration stuff
          if (_smc.getIntegrateSecurity()) {
              SecurityCheckObject securityCheckObject = doSecurityCheck(sd, _request, create);
              if (securityCheckObject.isDoSecurityCheckAgain()) {
                  boolean reuseId = shouldReuseId(_request,sac) && 
                          checkSessionIdIsRightLength(_sam.getInUseSessionID(_request, sac)); 
                  session = (HttpSession) _coreHttpSessionManager.createSession(_request, _response, sac, reuseId);
                  sd = (SessionData)session;
                  createdOnThisRequest = true;
                  securityCheckObject = doSecurityCheck(sd, _request, create); //shouldn't have an issue with the session being owned by someone else since we invalidated the previous session and created a brand new session
              }
              sd = securityCheckObject.getSessionObject();
          }
        // cmd 372189 save pathinfo in case it contains ibmappid (for SIP) and app
        // calls sess.getIBMApplicationSession()
        // Note: concurrent requests should have same ibmappid encoded so we
        // should be ok even with concurrent requests
        if (isSIPApplication)
        {
          sd.setSIPCookieInfo(_request);
          sd.setPathInfo(_request.getPathInfo());
          // this needs to be called here after the pathInfo has been set up
          // only want to call this when we create a session since the logicalname
          // won't change
          // changed "if (createdOnThisRequest) {" to
          // "if (!_response.isCommitted()) {"
          // if the server shuts down, the logicalname does change, and we may
          // retrieve the session from the backend.
          // Therefore, we should always create the sip cookie (although, we don't
          // want to throw an exception if the response is committed)
          if (!_response.isCommitted())
          {
            setSIPCookieIfApplicable(_request, _response, sd);
          }
        }
      }
  
      if (_sap.getAllowDispatchRemoteInclude())
      {
        ((SessionAffinityManager) _sam).setSessionId(_request, sac); // sets the
        // full
        // session id
        // (includes
        // cacheid/cloneids)
        // on the
        // request
        // for RRD
      }
  
      if (isTraceOn && LoggingUtil.SESSION_LOGGER_CORE.isLoggable(Level.FINE))
      {
        LoggingUtil.SESSION_LOGGER_CORE.exiting(methodClassName, methodNames[GET_IHTTP_SESSION]);
      }
      return sd;
  
    }