@Override
  public ActionResult processAction(
      HttpServletRequest request, HttpServletResponse response, Portlet portlet)
      throws PortletContainerException {

    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);

    if (spiAgent == null) {
      return _portletContainer.processAction(request, response, portlet);
    }

    Object[] requestAttributeValues =
        captureRequestAttibutes(request, _ACTION_REQUEST_ATTRIBUTE_NAMES);

    request.setAttribute(WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.ACTION);
    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);

    try {
      spiAgent.service(request, response);

      return (ActionResult) request.getAttribute(WebKeys.SPI_AGENT_ACTION_RESULT);
    } catch (PortalResiliencyException pre) {
      _log.error(pre, pre);

      return ActionResult.EMPTY_ACTION_RESULT;
    } finally {
      request.removeAttribute(WebKeys.SPI_AGENT_ACTION_RESULT);

      restoreRequestAttibutes(request, _ACTION_REQUEST_ATTRIBUTE_NAMES, requestAttributeValues);
    }
  }
  @Override
  public void serveResource(
      HttpServletRequest request, HttpServletResponse response, Portlet portlet)
      throws PortletContainerException {

    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);

    if (spiAgent == null) {
      _portletContainer.serveResource(request, response, portlet);

      return;
    }

    Object[] requestAttributeValues =
        captureRequestAttibutes(request, _RESOURCE_REQUEST_ATTRIBUTE_NAMES);

    request.setAttribute(WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.RESOURCE);
    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);

    try {
      spiAgent.service(request, response);
    } catch (PortalResiliencyException pre) {
      _log.error(pre, pre);
    } finally {
      restoreRequestAttibutes(request, _RESOURCE_REQUEST_ATTRIBUTE_NAMES, requestAttributeValues);
    }
  }
  @Override
  public List<Event> processEvent(
      HttpServletRequest request,
      HttpServletResponse response,
      Portlet portlet,
      Layout layout,
      Event event)
      throws PortletContainerException {

    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);

    if (spiAgent == null) {
      return _portletContainer.processEvent(request, response, portlet, layout, event);
    }

    Object[] requestAttributeValues =
        captureRequestAttibutes(request, _EVENT_REQUEST_ATTRIBUTE_NAMES);

    request.setAttribute(WebKeys.SPI_AGENT_EVENT, event);
    request.setAttribute(WebKeys.SPI_AGENT_LAYOUT, layout);
    request.setAttribute(WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.EVENT);
    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);

    try {
      spiAgent.service(request, response);

      return (List<Event>) request.getAttribute(WebKeys.SPI_AGENT_EVENT_RESULT);
    } catch (PortalResiliencyException pre) {
      _log.error(pre, pre);

      return Collections.emptyList();
    } finally {
      request.removeAttribute(WebKeys.SPI_AGENT_EVENT_RESULT);

      restoreRequestAttibutes(request, _EVENT_REQUEST_ATTRIBUTE_NAMES, requestAttributeValues);
    }
  }