public static void runTestLifeCycle(
      AsyncTaskService client, Map<String, User> users, Map<String, Group> groups) {
    Map<String, Object> vars = fillVariables(users, groups);

    // One potential owner, should go straight to state Reserved
    String str =
        "(with (new Task()) { priority = 55, taskData = (with( new TaskData()) { workItemId = 1 } ), ";
    str +=
        "peopleAssignments = (with ( new PeopleAssignments() ) { potentialOwners = [users['bobba']], }),";
    //        str += "descriptions = [ new I18NText( 'en-UK', 'This is my description')], ";
    //        str += "subjects = [ new I18NText( 'en-UK', 'This is my subject')], ";
    str += "names = [ new I18NText( 'en-UK', 'This is my task name')] })";

    BlockingAddTaskResponseHandler addTaskResponseHandler = new BlockingAddTaskResponseHandler();
    Task task = (Task) eval(new StringReader(str), vars);
    client.addTask(task, null, addTaskResponseHandler);

    long taskId = addTaskResponseHandler.getTaskId();

    EventKey key = new TaskEventKey(TaskCompletedEvent.class, taskId);
    BlockingEventResponseHandler handler = new BlockingEventResponseHandler();
    client.registerForEvent(key, false, handler);

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner(
        users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
    List<TaskSummary> tasks = taskSummaryResponseHandler.getResults();
    assertEquals(1, tasks.size());
    assertEquals(Status.Reserved, tasks.get(0).getStatus());

    BlockingTaskOperationResponseHandler responseHandler =
        new BlockingTaskOperationResponseHandler();
    client.start(taskId, users.get("bobba").getId(), responseHandler);

    taskSummaryResponseHandler = new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner(
        users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
    tasks = taskSummaryResponseHandler.getResults();
    assertEquals(1, tasks.size());
    assertEquals(Status.InProgress, tasks.get(0).getStatus());

    responseHandler = new BlockingTaskOperationResponseHandler();
    client.complete(taskId, users.get("bobba").getId(), null, responseHandler);

    taskSummaryResponseHandler = new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner(
        users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
    tasks = taskSummaryResponseHandler.getResults();
    assertEquals(0, tasks.size());

    Payload payload = handler.getPayload();
    TaskCompletedEvent event = (TaskCompletedEvent) payload.get();
    assertNotNull(event);

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    Task task1 = getTaskResponseHandler.getTask();
    assertEquals(Status.Completed, task1.getTaskData().getStatus());
  }
  @Transactional(readOnly = true)
  @Override
  public List<Task> findPersonalTasks(String assignee) {
    List<TaskSummary> tempTasks = new ArrayList<TaskSummary>();
    List<TaskSummary> tasks = new ArrayList<TaskSummary>();

    // first check to see if the user is valid, otherwise JBPM is not happy
    org.wiredwidgets.cow.server.api.service.User user = usersService.findUser(assignee);
    if (user == null) {
      // not a user in the system, so cannot have any tasks!
      return new ArrayList<Task>();
    }

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    taskClient.getTasksAssignedAsPotentialOwner(assignee, "en-UK", taskSummaryResponseHandler);
    tempTasks.addAll(taskSummaryResponseHandler.getResults());

    for (TaskSummary task : tempTasks) {
      if (task.getStatus() == Status.Reserved
          && (task.getActualOwner() != null && task.getActualOwner().getId().equals(assignee))) {
        tasks.add(task);
      }
    }

    return this.convertTaskSummarys(tasks);
  }
  private void doControlTask() throws IOException, ClassNotFoundException {
    BlockingTaskSummaryResponseHandler handler = new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner("control", "en-UK", handler);
    List<TaskSummary> sums = handler.getResults();
    assertNotNull(sums);
    assertEquals(1, sums.size());

    BlockingTaskOperationResponseHandler startTaskOperationHandler =
        new BlockingTaskOperationResponseHandler();
    client.start(sums.get(0).getId(), "control", startTaskOperationHandler);

    BlockingGetTaskResponseHandler getTaskHandler = new BlockingGetTaskResponseHandler();
    client.getTask(sums.get(0).getId(), getTaskHandler);
    Task controlTask = getTaskHandler.getTask();

    BlockingGetContentResponseHandler getContentHandler = new BlockingGetContentResponseHandler();
    client.getContent(controlTask.getTaskData().getDocumentContentId(), getContentHandler);
    Content content = getContentHandler.getContent();

    assertNotNull(content);

    ByteArrayInputStream bais = new ByteArrayInputStream(content.getContent());
    ObjectInputStream ois = new ObjectInputStream(bais);
    Map<String, Object> deserializedContent = (Map<String, Object>) ois.readObject();
    Emergency retrivedEmergency = (Emergency) deserializedContent.get("emergency");
    assertNotNull(retrivedEmergency);
    ActivePatients retrivedActivePatients =
        (ActivePatients) deserializedContent.get("activePatients");
    assertNotNull(retrivedActivePatients);
    assertEquals(1, retrivedActivePatients.size());
    SuggestedProcedures retrivedSuggestedProcedures =
        (SuggestedProcedures) deserializedContent.get("suggestedProcedures");
    assertNotNull(retrivedSuggestedProcedures);
    assertEquals(
        "[DefaultHeartAttackProcedure: ]",
        retrivedSuggestedProcedures.getSuggestedProceduresString());

    Map<String, Object> info = new HashMap<String, Object>();
    SelectedProcedures selectedProcedures = new SelectedProcedures(retrivedEmergency.getId());

    selectedProcedures.addSelectedProcedureName("DefaultHeartAttackProcedure");
    info.put("selectedProcedures", selectedProcedures);

    ContentData result = new ContentData();
    result.setAccessType(AccessType.Inline);
    result.setType("java.util.Map");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(info);
    out.close();
    result.setContent(bos.toByteArray());

    BlockingTaskOperationResponseHandler completeTaskOperationHandler =
        new BlockingTaskOperationResponseHandler();
    client.complete(sums.get(0).getId(), "control", result, completeTaskOperationHandler);
  }
  private void doGarageTask() {
    BlockingTaskSummaryResponseHandler handler = new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner("garage_emergency_service", "en-UK", handler);
    List<TaskSummary> sums = handler.getResults();
    assertNotNull(sums);
    assertEquals(1, sums.size());

    BlockingTaskOperationResponseHandler startTaskOperationHandler =
        new BlockingTaskOperationResponseHandler();
    client.start(sums.get(0).getId(), "garage_emergency_service", startTaskOperationHandler);
  }
  private void doOperatorTask() throws ClassNotFoundException, IOException {
    BlockingTaskSummaryResponseHandler handler = new BlockingTaskSummaryResponseHandler();
    client.getTasksAssignedAsPotentialOwner("operator", "en-UK", handler);
    List<TaskSummary> sums = handler.getResults();
    assertNotNull(sums);
    assertEquals(1, sums.size());

    BlockingTaskOperationResponseHandler startTaskOperationHandler =
        new BlockingTaskOperationResponseHandler();
    client.start(sums.get(0).getId(), "operator", startTaskOperationHandler);

    BlockingGetTaskResponseHandler getTaskHandler = new BlockingGetTaskResponseHandler();
    client.getTask(sums.get(0).getId(), getTaskHandler);
    Task operatorTask = getTaskHandler.getTask();

    BlockingGetContentResponseHandler getContentHandler = new BlockingGetContentResponseHandler();
    client.getContent(operatorTask.getTaskData().getDocumentContentId(), getContentHandler);
    Content content = getContentHandler.getContent();

    assertNotNull(content);

    ByteArrayInputStream bais = new ByteArrayInputStream(content.getContent());
    ObjectInputStream ois = new ObjectInputStream(bais);
    Map<String, Object> deserializedContent = (Map<String, Object>) ois.readObject();
    Call restoredCall = (Call) deserializedContent.get("call");
    persistenceService.storeCall(restoredCall);

    Emergency emergency = new Emergency();

    emergency.setCall(restoredCall);

    emergency.setLocation(new Location(1, 2));
    emergency.setType(Emergency.EmergencyType.HEART_ATTACK);
    emergency.setNroOfPeople(1);
    persistenceService.storeEmergency(emergency);

    trackingService.attachEmergency(restoredCall.getId(), emergency.getId());

    Map<String, Object> info = new HashMap<String, Object>();
    info.put("emergency", emergency);

    ContentData result = new ContentData();
    result.setAccessType(AccessType.Inline);
    result.setType("java.util.Map");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(bos);
    out.writeObject(info);
    out.close();
    result.setContent(bos.toByteArray());

    BlockingTaskOperationResponseHandler completeTaskOperationHandler =
        new BlockingTaskOperationResponseHandler();
    client.complete(sums.get(0).getId(), "operator", result, completeTaskOperationHandler);
  }
  @Transactional(readOnly = true)
  @Override
  public List<Task> findGroupTasks(String user) {
    List<TaskSummary> tempTasks = new ArrayList<TaskSummary>();
    List<TaskSummary> tasks = new ArrayList<TaskSummary>();

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    taskClient.getTasksAssignedAsPotentialOwner(user, "en-UK", taskSummaryResponseHandler);
    tempTasks.addAll(taskSummaryResponseHandler.getResults());

    for (TaskSummary task : tempTasks) {
      if (task.getStatus() == Status.Ready) {
        tasks.add(task);
      }
    }

    return this.convertTaskSummarys(tasks);
  }
  @Transactional(readOnly = true)
  @Override
  public List<Task> findAllTasksByProcessInstance(Long id) {
    List<Status> status =
        Arrays.asList(
            Status.Completed,
            Status.Created,
            Status.Error,
            Status.Exited,
            Status.Failed,
            Status.InProgress,
            Status.Obsolete,
            Status.Ready,
            Status.Reserved,
            Status.Suspended);

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    taskClient.getTasksByStatusByProcessId(id, status, "en-UK", taskSummaryResponseHandler);
    return this.convertTaskSummarys(taskSummaryResponseHandler.getResults());
  }
  public static final void main(String[] args) {
    try {
      setupTaskServer();
      // load up the knowledge base
      KnowledgeBase kbase = readKnowledgeBase();
      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
      KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
      ksession
          .getWorkItemManager()
          .registerWorkItemHandler("Human Task", new CommandBasedWSHumanTaskHandler(ksession));
      // start a new process instance
      Map<String, Object> params = new HashMap<String, Object>();
      params.put("userId", "krisv");
      params.put("s", "Need a new laptop computer");
      ksession.startProcess("UserTask", params);

      SystemEventListenerFactory.setSystemEventListener(new SystemEventListener());
      TaskClient taskClient =
          new TaskClient(
              new MinaTaskClientConnector(
                  "MinaConnector",
                  new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));
      taskClient.connect("127.0.0.1", 9123);
      Thread.sleep(1000);

      // sleep to allow notification to be sent for deadline start
      Thread.sleep(6000);
      //            Assert.assertEquals(4, wiser.getMessages().size());
      //            Assert.assertEquals("*****@*****.**",
      // wiser.getMessages().get(0).getEnvelopeReceiver());
      //            Assert.assertEquals("*****@*****.**",
      // wiser.getMessages().get(1).getEnvelopeReceiver());
      //            Assert.assertEquals("Task is ready for mike",
      // wiser.getMessages().get(0).getMimeMessage().getSubject());

      // wait another few seconds to trigger complete deadline
      Thread.sleep(4000);
      //            Assert.assertEquals(6, wiser.getMessages().size());
      //            Assert.assertEquals("*****@*****.**",
      // wiser.getMessages().get(2).getEnvelopeReceiver());
      //            Assert.assertEquals("*****@*****.**",
      // wiser.getMessages().get(3).getEnvelopeReceiver());
      //            Assert.assertEquals("Not completedTask is ready for mike",
      // wiser.getMessages().get(4).getMimeMessage().getSubject());

      BlockingTaskSummaryResponseHandler taskSummaryHandler =
          new BlockingTaskSummaryResponseHandler();
      taskClient.getTasksAssignedAsPotentialOwner("mike", "en-UK", taskSummaryHandler);
      TaskSummary task1 = taskSummaryHandler.getResults().get(0);

      BlockingTaskOperationResponseHandler taskOperationHandler =
          new BlockingTaskOperationResponseHandler();
      taskClient.start(task1.getId(), "mike", taskOperationHandler);
      taskOperationHandler.waitTillDone(1000);
      taskOperationHandler = new BlockingTaskOperationResponseHandler();
      Map<String, Object> results = new HashMap<String, Object>();
      results.put("comment", "Agreed, existing laptop needs replacing");
      results.put("outcome", "Accept");
      ContentData contentData = new ContentData();
      contentData.setAccessType(AccessType.Inline);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream out;
      try {
        out = new ObjectOutputStream(bos);
        out.writeObject(results);
        out.close();
        contentData = new ContentData();
        contentData.setContent(bos.toByteArray());
        contentData.setAccessType(AccessType.Inline);
      } catch (IOException e) {
        e.printStackTrace();
      }
      taskClient.complete(task1.getId(), "mike", contentData, taskOperationHandler);
      taskOperationHandler.waitTillDone(1000);
      Thread.sleep(1000);

      logger.close();
    } catch (Throwable t) {
      t.printStackTrace();
    }
    wiser.stop();
    System.exit(0);
  }
  @Test
  public void testTaskDataWithVPSandMAPWithDeadline() throws Exception {

    taskService.setEscalatedDeadlineHandler(buildDeadlineHandler(env));
    // JPA Entity
    EntityManager em = domainEmf.createEntityManager();
    em.getTransaction().begin();
    MyEntity myEntity = new MyEntity("This is a JPA Entity");
    em.persist(myEntity);
    em.getTransaction().commit();

    // Serializable Object
    MyObject myObject = new MyObject("This is a Serializable Object");

    Map<String, Object> content = new HashMap<String, Object>();
    content.put("myJPAEntity", myEntity);
    content.put("mySerializableObject", myObject);

    TestWorkItemManager manager = new TestWorkItemManager();
    ksession.setWorkItemManager(manager);
    WorkItemImpl workItem = new WorkItemImpl();
    workItem.setName("Human Task");
    workItem.setParameter("TaskName", "TaskName");
    workItem.setParameter("Comment", "Comment");
    workItem.setParameter("Priority", "10");
    workItem.setParameter("ActorId", "Darth Vader");
    workItem.setParameter("Content", content);
    workItem.setParameter(
        "NotStartedNotify",
        "[tousers:john|subject:${doc['myJPAEntity'].test}|body:${doc['mySerializableObject'].value}]@[2s]");
    getHandler().executeWorkItem(workItem, manager);

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    getClient()
        .getTasksAssignedAsPotentialOwner("Darth Vader", "en-UK", taskSummaryResponseHandler);
    List<TaskSummary> tasks = taskSummaryResponseHandler.getResults();
    assertEquals(1, tasks.size());
    TaskSummary taskSummary = tasks.get(0);
    assertEquals("TaskName", taskSummary.getName());
    assertEquals(10, taskSummary.getPriority());
    assertEquals("Comment", taskSummary.getDescription());
    assertEquals(Status.Reserved, taskSummary.getStatus());
    assertEquals("Darth Vader", taskSummary.getActualOwner().getId());

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    getClient().getTask(taskSummary.getId(), getTaskResponseHandler);
    Task task = getTaskResponseHandler.getTask();
    assertEquals(AccessType.Inline, task.getTaskData().getDocumentAccessType());
    assertEquals(task.getTaskData().getProcessSessionId(), ksession.getId());
    long contentId = task.getTaskData().getDocumentContentId();
    assertTrue(contentId != -1);

    BlockingGetContentResponseHandler getContentResponseHandler =
        new BlockingGetContentResponseHandler();
    getClient().getContent(contentId, getContentResponseHandler);
    Object data =
        ContentMarshallerHelper.unmarshall(
            getContentResponseHandler.getContent().getContent(), ksession.getEnvironment());
    Map<String, Object> dataMap = (Map<String, Object>) data;

    assertEquals(myEntity.getTest(), ((MyEntity) dataMap.get("myJPAEntity")).getTest());
    assertEquals(myObject.getValue(), ((MyObject) dataMap.get("mySerializableObject")).getValue());

    Thread.sleep(5000);
    assertEquals(2, wiser.getMessages().size());
    assertEquals("*****@*****.**", wiser.getMessages().get(0).getEnvelopeReceiver());
    assertEquals("*****@*****.**", wiser.getMessages().get(1).getEnvelopeReceiver());
    assertEquals(myEntity.getTest(), wiser.getMessages().get(0).getMimeMessage().getSubject());
    assertEquals(myObject.getValue(), wiser.getMessages().get(0).getMimeMessage().getContent());

    BlockingTaskOperationResponseHandler startResponseHandler =
        new BlockingTaskOperationResponseHandler();
    getClient().start(task.getId(), "Darth Vader", startResponseHandler);

    Map<String, Object> results = new HashMap<String, Object>();
    em.getTransaction().begin();
    MyEntity myEntity2 = new MyEntity("This is a JPA Entity 2");
    em.persist(myEntity2);
    em.getTransaction().commit();
    results.put("myEntity2", myEntity2);
    MyObject myObject2 = new MyObject("This is a Serializable Object 2");
    results.put("myObject2", myObject2);

    ContentData result = ContentMarshallerHelper.marshal(results, ksession.getEnvironment());

    BlockingTaskOperationResponseHandler completeResponseHandler =
        new BlockingTaskOperationResponseHandler();
    getClient().complete(task.getId(), "Darth Vader", result, completeResponseHandler);

    assertTrue(manager.waitTillCompleted(MANAGER_COMPLETION_WAIT_TIME));
    Map<String, Object> managerResults = manager.getResults();
    assertNotNull(managerResults);
    assertEquals("Darth Vader", managerResults.get("ActorId"));
    assertEquals(
        myEntity2.getTest(),
        ((MyEntity) ((Map) managerResults.get("Result")).get("myEntity2")).getTest());
    assertEquals(myEntity2.getTest(), ((MyEntity) managerResults.get("myEntity2")).getTest());
    assertEquals(
        myObject2.getValue(),
        ((MyObject) ((Map) managerResults.get("Result")).get("myObject2")).getValue());
    assertEquals(myObject2.getValue(), ((MyObject) managerResults.get("myObject2")).getValue());
  }
  @Test
  public void testTaskDataWithVPSSerializableObjectWithMarshal() throws Exception {
    // Serializable Object
    MyObject myObject = new MyObject("This is a Serializable Object");

    TestWorkItemManager manager = new TestWorkItemManager();
    ksession.setWorkItemManager(manager);
    WorkItemImpl workItem = new WorkItemImpl();
    workItem.setName("Human Task");
    workItem.setParameter("TaskName", "TaskName");
    workItem.setParameter("Comment", "Comment");
    workItem.setParameter("Priority", "10");
    workItem.setParameter("ActorId", "Darth Vader");
    workItem.setParameter("Content", myObject);
    getHandler().executeWorkItem(workItem, manager);

    BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
        new BlockingTaskSummaryResponseHandler();
    getClient()
        .getTasksAssignedAsPotentialOwner("Darth Vader", "en-UK", taskSummaryResponseHandler);
    List<TaskSummary> tasks = taskSummaryResponseHandler.getResults();
    assertEquals(1, tasks.size());
    TaskSummary taskSummary = tasks.get(0);
    assertEquals("TaskName", taskSummary.getName());
    assertEquals(10, taskSummary.getPriority());
    assertEquals("Comment", taskSummary.getDescription());
    assertEquals(Status.Reserved, taskSummary.getStatus());
    assertEquals("Darth Vader", taskSummary.getActualOwner().getId());

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    getClient().getTask(taskSummary.getId(), getTaskResponseHandler);
    Task task = getTaskResponseHandler.getTask();
    assertEquals(AccessType.Inline, task.getTaskData().getDocumentAccessType());

    assertEquals(task.getTaskData().getProcessSessionId(), ksession.getId());
    long contentId = task.getTaskData().getDocumentContentId();
    assertTrue(contentId != -1);

    BlockingGetContentResponseHandler getContentResponseHandler =
        new BlockingGetContentResponseHandler();
    getClient().getContent(contentId, getContentResponseHandler);
    Object data =
        ContentMarshallerHelper.unmarshall(
            getContentResponseHandler.getContent().getContent(), ksession.getEnvironment());
    assertEquals(myObject.getValue(), ((MyObject) data).getValue());

    BlockingTaskOperationResponseHandler startResponseHandler =
        new BlockingTaskOperationResponseHandler();
    getClient().start(task.getId(), "Darth Vader", startResponseHandler);

    MyObject myObject2 = new MyObject("This is a Serializable Object 2");

    ContentData result = ContentMarshallerHelper.marshal(myObject2, ksession.getEnvironment());
    BlockingTaskOperationResponseHandler completeResponseHandler =
        new BlockingTaskOperationResponseHandler();
    getClient().complete(task.getId(), "Darth Vader", result, completeResponseHandler);

    assertTrue(manager.waitTillCompleted(MANAGER_COMPLETION_WAIT_TIME));
    Map<String, Object> results = manager.getResults();
    assertNotNull(results);
    assertEquals("Darth Vader", results.get("ActorId"));
    assertEquals(myObject2.getValue(), ((MyObject) results.get("Result")).getValue());
  }
  @Test
  public void testCompleteTaskMultipleSessionsASync() throws Exception {
    TestStatefulKnowledgeSession ksession = new TestStatefulKnowledgeSession();

    AsyncHornetQHTWorkItemHandler handler = new AsyncHornetQHTWorkItemHandler(ksession, true);
    clientAsync = handler.getClient();
    HornetQTestWorkItemManager manager = new HornetQTestWorkItemManager();
    ksession.setWorkItemManager(manager);
    WorkItemImpl workItem = new WorkItemImpl();
    workItem.setName("Human Task");
    workItem.setParameter("TaskName", "TaskName");
    workItem.setParameter("Comment", "Comment");
    workItem.setParameter("Priority", "10");
    workItem.setParameter("ActorId", "Darth Vader");
    workItem.setProcessInstanceId(10);
    handler.executeWorkItem(workItem, manager);

    TestStatefulKnowledgeSession ksession2 = new TestStatefulKnowledgeSession(10);
    AsyncHornetQHTWorkItemHandler handler2 =
        new AsyncHornetQHTWorkItemHandler("testConnector", null, ksession2, OnErrorAction.LOG);
    handler2.setOwningSessionOnly(true);

    HornetQTestWorkItemManager manager2 = new HornetQTestWorkItemManager();
    ksession2.setWorkItemManager(manager2);
    WorkItemImpl workItem2 = new WorkItemImpl();
    workItem2.setName("Human Task");
    workItem2.setParameter("TaskName", "TaskName");
    workItem2.setParameter("Comment", "Comment");
    workItem2.setParameter("Priority", "10");
    workItem2.setParameter("ActorId", "Darth Vader");
    workItem2.setProcessInstanceId(10);
    handler2.executeWorkItem(workItem2, manager2);

    Thread.sleep(1000);

    BlockingTaskSummaryResponseHandler reshanlder = new BlockingTaskSummaryResponseHandler();
    clientAsync.getTasksAssignedAsPotentialOwner("Darth Vader", "en-UK", reshanlder);
    List<TaskSummary> tasks = reshanlder.getResults();
    assertEquals(2, tasks.size());
    TaskSummary task = tasks.get(0);
    // ensure we get first task
    if (task.getProcessSessionId() == 10) {
      task = tasks.get(1);
    }
    assertEquals("TaskName", task.getName());
    assertEquals(10, task.getPriority());
    assertEquals("Comment", task.getDescription());
    assertEquals(Status.Reserved, task.getStatus());
    assertEquals("Darth Vader", task.getActualOwner().getId());
    assertEquals(10, task.getProcessInstanceId());

    BlockingTaskOperationResponseHandler resOpHandler = new BlockingTaskOperationResponseHandler();
    clientAsync.start(task.getId(), "Darth Vader", resOpHandler);
    resOpHandler.waitTillDone(5000);

    resOpHandler = new BlockingTaskOperationResponseHandler();
    clientAsync.complete(task.getId(), "Darth Vader", null, resOpHandler);
    resOpHandler.waitTillDone(5000);

    Thread.sleep(1000);

    assertEquals(1, manager.getCompleteCounter());
    assertEquals(0, manager2.getCompleteCounter());

    handler.dispose();
    handler2.dispose();
  }
  public static void runTestLifeCycleMultipleTasks(
      AsyncTaskService client, Map<String, User> users, Map<String, Group> groups) {
    Map<String, Object> vars = fillVariables(users, groups);

    // One potential owner, should go straight to state Reserved
    String str =
        "(with (new Task()) { priority = 55, taskData = (with( new TaskData()) { workItemId = 1 } ), ";
    str +=
        "peopleAssignments = (with ( new PeopleAssignments() ) { potentialOwners = [users['bobba']], }),";
    str += "descriptions = [ new I18NText( 'en-UK', 'This is my description')], ";
    str += "subjects = [ new I18NText( 'en-UK', 'This is my subject')], ";
    str += "names = [ new I18NText( 'en-UK', 'This is my task name')] })";

    // First task
    // In own scope to make sure that no objects in scope can be used in second task
    long taskId = 0;
    BlockingEventResponseHandler handler = new BlockingEventResponseHandler();
    {
      BlockingAddTaskResponseHandler addTaskResponseHandler = new BlockingAddTaskResponseHandler();
      Task task = (Task) eval(new StringReader(str), vars);
      client.addTask(task, null, addTaskResponseHandler);
      taskId = addTaskResponseHandler.getTaskId();
      assertTrue(taskId != 0);

      EventKey key = new TaskEventKey(TaskCompletedEvent.class, taskId);
      client.registerForEvent(key, false, handler);

      BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
          new BlockingTaskSummaryResponseHandler();
      client.getTasksAssignedAsPotentialOwner(
          users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
      List<TaskSummary> tasks = taskSummaryResponseHandler.getResults();
      assertEquals(1, tasks.size());
      assertEquals(Status.Reserved, tasks.get(0).getStatus());

      BlockingTaskOperationResponseHandler responseHandler =
          new BlockingTaskOperationResponseHandler();
      client.start(taskId, users.get("bobba").getId(), responseHandler);

      taskSummaryResponseHandler = new BlockingTaskSummaryResponseHandler();
      client.getTasksAssignedAsPotentialOwner(
          users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
      tasks = taskSummaryResponseHandler.getResults();
      assertEquals(1, tasks.size());
      assertEquals(Status.InProgress, tasks.get(0).getStatus());
    }

    // Second task
    // In own scope to make sure that no objects in scope can be used elsewhere
    long taskId2 = 0;
    BlockingEventResponseHandler handler2 = new BlockingEventResponseHandler();
    {
      BlockingAddTaskResponseHandler addTaskResponseHandler2 = new BlockingAddTaskResponseHandler();
      Task task2 = (Task) eval(new StringReader(str), vars);
      client.addTask(task2, null, addTaskResponseHandler2);
      taskId2 = addTaskResponseHandler2.getTaskId();
      assertTrue(taskId2 != 0);
      assertTrue("Tasks should have different ids.", taskId != taskId2);

      EventKey key2 = new TaskEventKey(TaskCompletedEvent.class, taskId2);
      client.registerForEvent(key2, false, handler2);

      BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
          new BlockingTaskSummaryResponseHandler();
      client.getTasksAssignedAsPotentialOwner(
          users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
      List<TaskSummary> tasks = taskSummaryResponseHandler.getResults();
      assertEquals(2, tasks.size());

      BlockingTaskOperationResponseHandler responseHandler =
          new BlockingTaskOperationResponseHandler();
      client.complete(taskId, users.get("bobba").getId(), null, responseHandler);

      responseHandler = new BlockingTaskOperationResponseHandler();
      client.start(taskId2, users.get("bobba").getId(), responseHandler);

      taskSummaryResponseHandler = new BlockingTaskSummaryResponseHandler();
      client.getTasksAssignedAsPotentialOwner(
          users.get("bobba").getId(), "en-UK", taskSummaryResponseHandler);
      tasks = taskSummaryResponseHandler.getResults();
      assertEquals(1, tasks.size());
    }

    Payload payload = handler.getPayload();
    TaskCompletedEvent event = (TaskCompletedEvent) payload.get();
    assertNotNull(event);

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    Task task = getTaskResponseHandler.getTask();
    assertEquals(Status.Completed, task.getTaskData().getStatus());

    BlockingTaskOperationResponseHandler responseHandler =
        new BlockingTaskOperationResponseHandler();
    client.complete(taskId2, users.get("bobba").getId(), null, responseHandler);

    payload = handler2.getPayload();
    event = (TaskCompletedEvent) payload.get();
    assertNotNull(event);

    BlockingGetTaskResponseHandler getTaskResponseHandler2 = new BlockingGetTaskResponseHandler();
    client.getTask(taskId2, getTaskResponseHandler2);
    Task task2 = getTaskResponseHandler2.getTask();
    assertEquals(Status.Completed, task2.getTaskData().getStatus());
  }