protected void maintainBridgeRequestScope(
      PortletRequest portletRequest,
      PortletResponse portletResponse,
      BridgeRequestScope.Transport bridgeRequestScopeTransport) {

    String bridgeRequestScopeId = bridgeRequestScope.getId();

    bridgeRequestScopeCache.put(bridgeRequestScopeId, bridgeRequestScope);

    String bridgeRequestScopeKey = portletName + PARAM_BRIDGE_REQUEST_SCOPE_ID;

    if (bridgeRequestScopeTransport == BridgeRequestScope.Transport.PORTLET_SESSION_ATTRIBUTE) {

      // TCK TestPage071: nonFacesResourceTest
      // TCK TestPage073: scopeAfterRedisplayResourcePPRTest
      PortletSession portletSession = portletRequest.getPortletSession(true);
      portletSession.setAttribute(bridgeRequestScopeKey, bridgeRequestScopeId);
    } else {

      if (portletResponse instanceof StateAwareResponse) {
        logger.debug(
            "Setting render parameter name=[{0}] value=[{1}]",
            bridgeRequestScopeKey, bridgeRequestScopeId);

        try {
          StateAwareResponse stateAwareResponse = (StateAwareResponse) portletResponse;
          stateAwareResponse.setRenderParameter(bridgeRequestScopeKey, bridgeRequestScopeId);
        } catch (IllegalStateException e) {

          // If a redirect occurred, then swallow/ignore the IllegalStateException
          if (bridgeRequestScope.isRedirectOccurred()) {

            // The Portlet API JavaDocs indicate that StateAwareResponse.setRenderParameter(String,
            // String)
            // must throw an IllegalStateException if ActionResponse.sendRedirect(String) was
            // previously
            // called. The JSR 329 TCK TestPage039 (requestNoScopeOnRedirectTest) and TestPage176
            // (redirectActionTest) both perform pseudo-redirects (effectively treated like
            // navigation-rules
            // from one JSF viewId to another). Since the tests don't actually call
            // ActionResponse.sendRedirect(String), this condition is never reached by the TCK.
            // However,
            // this condition is a real-world use-case and so the IllegalStateException must be
            // swallowed/ignored here so that portlet lifecycle processing is able to continue. For
            // more
            // information, see: http://issues.liferay.com/browse/FACES-1367
          }

          // Otherwise throw the IllegalStateException.
          else {
            throw e;
          }
        }
      }
    }
  }
  protected void initBridgeRequestScope(
      PortletRequest portletRequest,
      PortletResponse portletResponse,
      Bridge.PortletPhase portletPhase) {

    boolean bridgeRequestScopeEnabled = true;

    if (portletPhase == Bridge.PortletPhase.RESOURCE_PHASE) {
      bridgeRequestScopeEnabled =
          PortletConfigParam.BridgeRequestScopeAjaxEnabled.getBooleanValue(portletConfig);
    }

    if (bridgeRequestScopeEnabled) {

      // Determine if there is a bridge request scope "id" saved as a render parameter. Note that in
      // order to
      // avoid collisions with bridge request scopes for other portlets, the render parameter name
      // has to be
      // namespaced with the portlet name.
      String portletName = portletConfig.getPortletName();
      String bridgeRequestScopeKey = portletName + PARAM_BRIDGE_REQUEST_SCOPE_ID;

      // If there is a render parameter value found for the "id", then return the cached bridge
      // request scope
      // associated with the "id".
      String bridgeRequestScopeId = portletRequest.getParameter(bridgeRequestScopeKey);

      if (bridgeRequestScopeId != null) {

        bridgeRequestScope = bridgeRequestScopeCache.get(bridgeRequestScopeId);

        if (bridgeRequestScope != null) {
          logger.debug(
              "Found render parameter name=[{0}] value=[{1}] and cached bridgeRequestScope=[{2}]",
              bridgeRequestScopeKey, bridgeRequestScopeId, bridgeRequestScope);
        } else {

          if (bridgeRequestScopePreserved) {
            logger.error(
                "Found render parameter name=[{0}] value=[{1}] BUT bridgeRequestScope is NOT in the cache",
                bridgeRequestScopeKey, bridgeRequestScopeId);
          }
        }
      }

      // Otherwise, if there is a portlet session attribute found for the "id", then return the
      // cached bridge
      // request scope associated with the "id". Note: This occurs after an Ajax-based
      // ResourceRequest so that
      // non-excluded request attributes can be picked up by a subsequent RenderRequest.
      if (bridgeRequestScope == null) {

        // TCK TestPage071: nonFacesResourceTest
        // TCK TestPage073: scopeAfterRedisplayResourcePPRTest
        PortletSession portletSession = portletRequest.getPortletSession();
        bridgeRequestScopeId = (String) portletSession.getAttribute(bridgeRequestScopeKey);

        if (bridgeRequestScopeId != null) {

          portletSession.removeAttribute(bridgeRequestScopeKey);

          bridgeRequestScope = bridgeRequestScopeCache.get(bridgeRequestScopeId);

          if (bridgeRequestScope != null) {

            logger.debug(
                "Found (and removed) session-attribute name=[{0}] value=[{1}] and cached bridgeRequestScope=[{2}]",
                bridgeRequestScopeKey, bridgeRequestScopeId, bridgeRequestScope);

            if (portletResponse instanceof StateAwareResponse) {
              logger.debug(
                  "Setting former session-attribute as render parameter name=[{0}] value=[{1}]",
                  bridgeRequestScopeKey, bridgeRequestScopeId);

              StateAwareResponse stateAwareResponse = (StateAwareResponse) portletResponse;
              stateAwareResponse.setRenderParameter(bridgeRequestScopeKey, bridgeRequestScopeId);
            }
          } else {

            logger.error(
                "Found session attribute name=[{0}] value=[{1}] but bridgeRequestScope is not in the cache",
                bridgeRequestScopeKey, bridgeRequestScopeId);
          }
        }
      }

      // Otherwise, return a new factory created instance.
      if (bridgeRequestScope == null) {
        bridgeRequestScope =
            BridgeRequestScopeFactory.getBridgeRequestScopeInstance(
                portletRequest, portletConfig, bridgeConfig);
      }
    }
  }