protected void setOutDataValues(OutDataValues outDataValues) {
    Interaction interaction = findInteraction();

    interaction.setOutDataValues(
        InteractionDataFlowUtils.unmarshalDataValues(
            interaction.getModel(), interaction.getDefinition(), outDataValues));
  }
  public void initializePanel(ActivityInstance ai, Map inData) {
    FacesContext facesContext = FacesContext.getCurrentInstance();

    InteractionRegistry registry =
        (InteractionRegistry)
            ManagedBeanUtils.getManagedBean(facesContext, InteractionRegistry.BEAN_ID);
    if (null != registry) {
      // start new interaction
      ModelCache modelCache = ModelCache.findModelCache();
      SessionContext ippSessionContext = SessionContext.findSessionContext();

      Interaction interaction = registry.getInteraction(Interaction.getInteractionId(ai));
      if (null == interaction) {
        interaction =
            new Interaction(ippSessionContext.getUser(), ai, getContextId(ai), modelCache);
        interaction.setInDataValues(inData);
        registry.registerInteraction(interaction);
      }

      Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
      sessionMap.put(
          IframePanelConstants.KEY_COMMAND, IframePanelConstants.CMD_IFRAME_PANEL_INITIALIZE);
      sessionMap.put(IframePanelConstants.KEY_INTERACTION_ID, interaction.getId());
      if (!isIceFacesPanel(ai)) {
        sessionMap.put(IframePanelConstants.KEY_VIEW_ID, VIEW_ID_NON_IFACE_FACELET_CONTAINER);
      }
    }

    // TODO emit java script to load page into panel?
  }
  protected InDataValues getInDataValues() throws WebApplicationException {
    Interaction interaction = findInteraction();

    InDataValues result = new InDataValues();

    marshalInteractionInDataValues(
        interaction.getModel(), interaction.getDefinition(), interaction.getInDataValues(), result);

    return result;
  }
  protected ParameterXto getInDataValue(String parameterId) throws WebApplicationException {
    Interaction interaction = findInteraction();
    DataMapping dm = findDataFlow(interaction, parameterId, Direction.IN);

    ParameterXto result =
        marshalInDataValue(interaction.getModel(), dm, interaction.getInDataValue(parameterId));

    if (null == result) {
      throw new WebApplicationException(Status.NOT_FOUND);
    }

    return result;
  }
  protected DataMapping findDataFlow(
      Interaction interaction, String parameterId, Direction direction)
      throws WebApplicationException {
    DataMapping ret = null;
    ApplicationContext definition = interaction.getDefinition();

    if ((null != definition) && !isEmpty(parameterId)) {
      AccessPoint outParam = findParameterDefinition(interaction, parameterId, direction);
      if (null == outParam) {
        if (InteractionDataFlowUtils.supportDataMappingIds()) {
          ret = definition.getDataMapping(direction, parameterId);
        }
      } else {
        List<DataMapping> allDataMappings = definition.getAllDataMappings();
        for (DataMapping dataMapping : allDataMappings) {
          if (outParam.equals(dataMapping.getApplicationAccessPoint())) {
            ret = dataMapping;
            break;
          }
        }
      }
    }

    if (ret == null) {
      throw new WebApplicationException(Status.NOT_FOUND);
    }

    return ret;
  }
  protected String getInDataValueAsJson(String parameterId, String callback)
      throws WebApplicationException {
    Interaction interaction = findInteraction();
    DataMapping dm = findDataFlow(interaction, parameterId, Direction.IN);

    String result =
        marshalInDataValueAsJson(
            interaction.getModel(), dm, interaction.getInDataValue(parameterId));

    if (!isEmpty(callback)) {
      // provide JSONP
      result = callback + "(" + result + ");";
    }

    return result;
  }
  public Map getOutDataValues(ActivityInstance ai) {
    FacesContext facesContext = FacesContext.getCurrentInstance();

    Map<String, ? extends Serializable> outData = null;

    InteractionRegistry registry =
        (InteractionRegistry)
            ManagedBeanUtils.getManagedBean(facesContext, InteractionRegistry.BEAN_ID);

    Interaction interaction = registry.getInteraction(Interaction.getInteractionId(ai));
    if (null != interaction) {
      outData = interaction.getOutDataValues();
    }

    return outData;
  }
  protected void setOutDataValueByMappingId(String parameterId, Object value) {
    Interaction interaction = findInteraction();

    DataMapping dm = findDataFlow(interaction, parameterId, Direction.OUT);

    UiInteractionsRestlet.trace.warn(
        "Writing OUT data using data mapping ID \""
            + parameterId
            + "\", this is only supported for a transition period.");

    Serializable decodedValue = unmarshalOutDataValue(interaction.getModel(), dm, value);
    if (null != decodedValue) {
      String outParamId = dm.getApplicationAccessPoint().getId();
      interaction.setOutDataValue(outParamId, decodedValue);
    } else {
      throw new WebApplicationException(Status.BAD_REQUEST);
    }
  }
  public boolean closePanel(ActivityInstance ai, ClosePanelScenario scenario, Object parameters) {
    FacesContext facesContext = FacesContext.getCurrentInstance();

    if (ActivityInteractionControllerUtils.isExternalWebAppInterventionRequired(scenario)) {
      trace.info("Triggering asynchronous close of activity panel ...");

      InteractionRegistry registry =
          (InteractionRegistry)
              ManagedBeanUtils.getManagedBean(facesContext, InteractionRegistry.BEAN_ID);

      Interaction interaction = registry.getInteraction(Interaction.getInteractionId(ai));
      if ((null != interaction) && (Interaction.Status.Complete == interaction.getStatus())) {
        // out data mapping was already performed
        return true;
      }

      Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();

      sessionMap.put(IframePanelConstants.KEY_COMMAND, scenario.getId());
      sessionMap.put(IframePanelConstants.KEY_INTERACTION_ID, Interaction.getInteractionId(ai));
      if (!isIceFacesPanel(ai)) {
        sessionMap.put(IframePanelConstants.KEY_VIEW_ID, VIEW_ID_NON_IFACE_FACELET_CONTAINER);
      }

      PortalApplicationEventScript.getInstance()
          .addEventScript(
              "parent.InfinityBpm.ProcessPortal.sendCloseCommandToExternalWebApp('"
                  + getContentFrameId(ai)
                  + "', '"
                  + scenario.getId()
                  + "');");

      // close panel asynchronously after ICEfaces page responds via JavaScript
      return false;
    } else {
      // destroy interaction
      unregisterInteraction(ai);

      // synchronously close panel as no custom post processing needs to occur
      return true;
    }
  }
  protected void setOutDataValue(String parameterId, Object value) {
    Interaction interaction = findInteraction();

    AccessPoint outParam = findParameterDefinition(interaction, parameterId, Direction.OUT);
    if (null == outParam) {
      if (InteractionDataFlowUtils.supportDataMappingIds()) {
        setOutDataValueByMappingId(parameterId, value);
        return;
      } else {
        throw new WebApplicationException(Status.NOT_FOUND);
      }
    }

    Serializable decodedValue = unmarshalOutDataValue(interaction.getModel(), outParam, value);
    if (null != decodedValue) {
      interaction.setOutDataValue(parameterId, decodedValue);
    } else {
      throw new WebApplicationException(Status.BAD_REQUEST);
    }
  }
  protected AccessPoint findParameterDefinition(
      Interaction interaction, String parameterId, Direction direction)
      throws WebApplicationException {
    ApplicationContext definition = interaction.getDefinition();

    if ((null != definition) && !isEmpty(parameterId)) {
      for (AccessPoint ap : (List<AccessPoint>) definition.getAllAccessPoints()) {
        if ((direction == ap.getDirection()) && parameterId.equals(ap.getId())) {
          return ap;
        }
      }
    }

    return null;
  }
  protected InteractionOwner getOwner() throws WebApplicationException {
    Interaction interaction = findInteraction();

    return toWs(interaction.getOwner(), new InteractionOwner());
  }
  protected InteractionDefinition getDefinition() throws WebApplicationException {
    Interaction interaction = findInteraction();

    return toXto(interaction.getDefinition(), new InteractionDefinition(), interaction.getModel());
  }