/**
   * Process a transition of an existing workflow instance.
   *
   * @param context the current transition context
   * @return the new current transition context
   * @throws TransitioningException when the workflow cannot be processed
   */
  protected TransitionContext processTransition(TransitionContext context)
      throws TransitioningException {

    if (context == null) {
      throw new IllegalArgumentException("Cannot process workflow for context [null].");
    }

    try {
      WorkflowServiceLocator locator = new WorkflowServiceLocator();
      WorkflowService service = locator.getService(null);

      ServiceRequest<ProcessWorkflowRq> rq =
          new ServiceRequest<ProcessWorkflowRq>(super.getContext());

      ProcessWorkflowRq requestMessage = new ProcessWorkflowRq();
      requestMessage.setInstanceId(context.getInstanceId());
      requestMessage.setSignal(context.getSignal());
      requestMessage.setComment(context.getComment());
      requestMessage.getSubInstances().addAll(context.getSubInstances());
      requestMessage.setContext(context.getWorkflowContext());
      rq.setRequestMessage(requestMessage);

      ServiceResponse<WorkflowResultRs> rs = service.processWorkflow(rq);

      if (rs == null || rs.getResponseMessage() == null) {
        throw new TransitioningException("Starting workflow did not finish successful.");
      }

      WorkflowResultRs responseMessage = rs.getResponseMessage();

      TransitionContext newContext = new TransitionContext();
      newContext.setInstanceId(responseMessage.getInstanceId());
      newContext.setName(responseMessage.getWorkflowName());
      newContext.setWorkflowContext(responseMessage.getContext());
      newContext.setSignal(context.getSignal());
      newContext.setStateName(responseMessage.getStateName());
      newContext.getNextTransitions().addAll(responseMessage.getNextTransitions());

      return newContext;

    } catch (WorkflowException we) {
      throw new TransitioningException(
          "Error processing workflow with name "
              + context.getName()
              + " and id "
              + context.getInstanceId()
              + ".",
          we);
    } catch (Exception e) {
      throw new TransitioningException(
          "Unexpected error processing workflow with name "
              + context.getName()
              + " and id "
              + context.getInstanceId()
              + ".",
          e);
    }
  }
  /**
   * Start a new workflow instance for the given workflow name.
   *
   * @param requestMessage the workflow init message
   * @return the transition context
   * @throws TransitioningException when the workflow cannot be started
   */
  protected TransitionContext startWorkflow(InitWorkflowRq requestMessage)
      throws TransitioningException {

    if (requestMessage == null) {
      throw new IllegalArgumentException("Cannot start workflow for request [null].");
    }

    Name name = requestMessage.getWorkflowName();
    Description summary = requestMessage.getSummary();

    if (name == null || name.getValue() == null || name.getValue().isEmpty()) {
      throw new IllegalArgumentException("Cannot start workflow with name [null].");
    }
    if (summary == null || summary.getValue() == null || summary.getValue().isEmpty()) {
      requestMessage.setSummary(new Description("Workflow '" + name + "'"));
    }

    try {
      WorkflowServiceLocator locator = new WorkflowServiceLocator();
      WorkflowService service = locator.getService(null);

      ServiceRequest<InitWorkflowRq> rq = new ServiceRequest<InitWorkflowRq>(super.getContext());
      rq.setRequestMessage(requestMessage);

      ServiceResponse<WorkflowResultRs> rs = service.initWorkflow(rq);

      if (rs == null || rs.getResponseMessage() == null) {
        throw new TransitioningException("Starting workflow did not finish successful.");
      }

      WorkflowResultRs responseMessage = rs.getResponseMessage();

      TransitionContext transitionContext = new TransitionContext();
      transitionContext.setInstance(responseMessage.getInstance());
      transitionContext.setInstanceId(responseMessage.getInstanceId());
      transitionContext.setName(responseMessage.getWorkflowName());
      transitionContext.setWorkflowContext(responseMessage.getContext());
      transitionContext.getNextTransitions().addAll(responseMessage.getNextTransitions());

      return transitionContext;

    } catch (WorkflowException we) {
      throw new TransitioningException("Error starting workflow with name " + name + ".", we);
    } catch (Exception e) {
      throw new TransitioningException(
          "Unexpected error starting workflow with name " + name + ".", e);
    }
  }