/** Start Process Definition */
  public static ProcessInstance runProcessDefinition(
      String user, long processDefinitionId, String uuid, List<FormElement> variables)
      throws WorkflowException {
    log.debug(
        "runProcessDefinition({}, {}, {}, {})",
        new Object[] {user, processDefinitionId, uuid, variables});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();
    ProcessInstance vo = new ProcessInstance();

    if (Config.SYSTEM_READONLY) {
      throw new WorkflowException("System is in read-only mode");
    }

    try {
      jbpmContext.setActorId(user);
      GraphSession graphSession = jbpmContext.getGraphSession();
      Map<String, Object> hm = new HashMap<String, Object>();
      hm.put(Config.WORKFLOW_PROCESS_INSTANCE_VARIABLE_UUID, uuid);

      for (FormElement fe : variables) {
        hm.put(fe.getName(), fe);
      }

      org.jbpm.graph.def.ProcessDefinition pd =
          graphSession.getProcessDefinition(processDefinitionId);
      org.jbpm.graph.exe.ProcessInstance pi = pd.createProcessInstance(hm);

      if (pi != null) {
        org.jbpm.taskmgmt.exe.TaskMgmtInstance tmi = pi.getTaskMgmtInstance();

        // http://community.jboss.org/thread/115182
        if (tmi.getTaskMgmtDefinition().getStartTask() != null) {
          org.jbpm.taskmgmt.exe.TaskInstance ti = tmi.createStartTaskInstance();

          if (Config.WORKFLOW_START_TASK_AUTO_RUN) {
            ti.start();
            ti.end();
          }
        } else {
          pi.getRootToken().signal();
        }

        jbpmContext.save(pi);
        vo = WorkflowUtils.copy(pi);
      }
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("runProcessDefinition: {}", vo);
    return vo;
  }
  /** Set Task Instance Values */
  public static void setTaskInstanceValues(
      long taskInstanceId, String transitionName, List<FormElement> values)
      throws WorkflowException {
    log.debug(
        "setTaskInstanceValues({}, {}, {})", new Object[] {taskInstanceId, transitionName, values});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
      Map<String, FormElement> hm = new HashMap<String, FormElement>();

      for (FormElement fe : values) {
        hm.put(fe.getName(), fe);
      }

      org.jbpm.taskmgmt.exe.TaskInstance ti = taskMgmtSession.getTaskInstance(taskInstanceId);
      ti.setVariables(hm);

      if (transitionName != null && !transitionName.equals("")) {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end(transitionName);
      } else {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end();
      }

      jbpmContext.save(ti);
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }
  }