public void execute(Event<UIPortlet<S, C>> event) throws Exception {
      UIPortlet<S, C> uiPortlet = event.getSource();
      PortalRequestContext prcontext = (PortalRequestContext) event.getRequestContext();

      // set the public render parameters from the request before creating the invocation
      HttpServletRequest request = prcontext.getRequest();
      setupPublicRenderParams(uiPortlet, request.getParameterMap());

      // set the navigational state
      String navState =
          prcontext.getRequestParameter(ExoPortletInvocationContext.NAVIGATIONAL_STATE_PARAM_NAME);
      if (navState != null) {
        uiPortlet.setNavigationalState(ParametersStateString.create(navState));
      }

      //
      ActionInvocation actionInvocation = uiPortlet.create(ActionInvocation.class, prcontext);
      if (actionInvocation == null) {
        return;
      }
      //
      PortletInvocationResponse portletResponse = uiPortlet.invoke(actionInvocation);

      // deal with potential portlet context modifications
      ExoPortletInstanceContext instanceCtx =
          (ExoPortletInstanceContext) actionInvocation.getInstanceContext();
      if (instanceCtx.getModifiedContext() != null) {
        StatefulPortletContext<C> updatedCtx =
            (StatefulPortletContext<C>) instanceCtx.getModifiedContext();
        C portletState = uiPortlet.getModifiedState(updatedCtx);
        uiPortlet.update(portletState);
      } else {
        // todo: fix me as this shouldn't probably be done only for the WSRP case
        PortletContext clonedContext = instanceCtx.getClonedContext();
        if (clonedContext != null) {
          C state = uiPortlet.getClonedState(clonedContext);
          uiPortlet.update(state);
        }
      }

      if (portletResponse instanceof UpdateNavigationalStateResponse) {
        handleUpdateNavigationalStateResponse(
            (UpdateNavigationalStateResponse) portletResponse, uiPortlet, prcontext);
      } else if (portletResponse instanceof HTTPRedirectionResponse) {
        handleRedirectionResponse(
            (HTTPRedirectionResponse) portletResponse, prcontext.getResponse());
        prcontext.setResponseComplete(true);
      } else if (portletResponse instanceof ErrorResponse) {
        handleErrorResponse((ErrorResponse) portletResponse);
      } else if (portletResponse instanceof SecurityResponse) {
        handleSecurityResponse((SecurityResponse) portletResponse);
      } else {
        throw new Exception(
            "Unexpected response type ["
                + portletResponse
                + "]. Expected an UpdateNavigationResponse"
                + ", a HTTPRedirectionResponse or an ErrorResponse.");
      }
    }
  /**
   * This method is called when the javax.portlet.Event is supported by the current portlet stored
   * in the Portlet Caontainer
   *
   * <p>The processEvent() method can also generates IPC events and hence the portal itself will
   * call the ProcessEventsActionListener once again
   */
  public static <S, C extends Serializable, I> List<javax.portlet.Event> processEvent(
      UIPortlet<S, C> uiPortlet, javax.portlet.Event event) {
    log.trace("Process Event: " + event.getName() + " for portlet: " + uiPortlet.getState());
    try {
      PortalRequestContext context =
          (PortalRequestContext) WebuiRequestContext.getCurrentInstance();

      //
      EventInvocation eventInvocation = uiPortlet.create(EventInvocation.class, context);

      //
      eventInvocation.setName(event.getQName());
      eventInvocation.setPayload(event.getValue());

      //
      PortletInvocationResponse piResponse = uiPortlet.invoke(eventInvocation);

      //
      ExoPortletInstanceContext instanceCtx =
          (ExoPortletInstanceContext) eventInvocation.getInstanceContext();
      if (instanceCtx.getModifiedContext() != null) {
        StatefulPortletContext<C> updatedCtx =
            (StatefulPortletContext<C>) instanceCtx.getModifiedContext();
        C portletState = updatedCtx.getState();
        uiPortlet.update(portletState);
      }

      // todo: handle the error response better than this.
      if (!(piResponse instanceof UpdateNavigationalStateResponse)) {
        if (piResponse instanceof ErrorResponse) {
          ErrorResponse errorResponse = (ErrorResponse) piResponse;
          throw (Exception) errorResponse.getCause();
        } else {
          throw new Exception(
              "Unexpected response type ["
                  + piResponse
                  + "]. Expected a UpdateNavigationResponse or an ErrorResponse.");
        }
      }

      UpdateNavigationalStateResponse navResponse = (UpdateNavigationalStateResponse) piResponse;

      //

      /*
       * Update the portlet window state according to the action output
       * information
       *
       * If the current node is displaying a usual layout page, also tells the
       * page which portlet to render or not when the state is maximized
       */
      WindowState state = new WindowState(getWindowStateOrDefault(navResponse));
      setNextState(uiPortlet, state);

      // update the portlet with the next mode to display
      PortletMode mode = new PortletMode(getPortletModeOrDefault(navResponse));
      setNextMode(uiPortlet, mode);

      StateString navState = navResponse.getNavigationalState();
      if (navState != null) {
        uiPortlet.setNavigationalState(navResponse.getNavigationalState());
      }
      setupPublicRenderParams(uiPortlet, navResponse.getPublicNavigationalStateUpdates());

      // TODO: (mwringe) add this to the UpdateNavigationStateResponse.Event class instead of here
      class PortletEvent implements javax.portlet.Event {
        QName qName;

        Serializable value;

        public PortletEvent(QName qName, Serializable value) {
          this.qName = qName;
          this.value = value;
        }

        public String getName() {
          return qName.getLocalPart();
        }

        public QName getQName() {
          return qName;
        }

        public Serializable getValue() {
          return value;
        }
      }

      List<UpdateNavigationalStateResponse.Event> nsEvents = navResponse.getEvents();
      List<javax.portlet.Event> events = new ArrayList<javax.portlet.Event>(nsEvents.size());
      if (nsEvents != null && !nsEvents.isEmpty()) {
        for (UpdateNavigationalStateResponse.Event nsEvent : nsEvents) {
          javax.portlet.Event portletEvent =
              new PortletEvent(nsEvent.getName(), nsEvent.getPayload());
          events.add(portletEvent);
        }
      }

      return events;
    } catch (Exception e) {
      log.error("Problem while processesing event for the portlet: " + uiPortlet.getState(), e);
    }
    return null;
  }