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());
  }
  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 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);
  }
  @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());
  }