public void testAddRemoveComment() {
    Map vars = new HashMap();
    vars.put("users", users);
    vars.put("groups", groups);
    vars.put("now", new Date());

    String str =
        "(with (new Task()) { priority = 55, taskData = (with( new TaskData()) { createdOn = now, activationTime = now}), ";
    str += "deadlines = new Deadlines(),";
    str += "delegation = new Delegation(),";
    str += "peopleAssignments = new PeopleAssignments(),";
    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();

    Comment comment = new Comment();
    Date addedAt = new Date(System.currentTimeMillis());
    comment.setAddedAt(addedAt);
    comment.setAddedBy(users.get("luke"));
    comment.setText("This is my comment1!!!!!");

    BlockingAddCommentResponseHandler addCommentResponseHandler =
        new BlockingAddCommentResponseHandler();
    client.addComment(taskId, comment, addCommentResponseHandler);
    assertTrue(addCommentResponseHandler.getCommentId() != comment.getId());

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    Task task1 = getTaskResponseHandler.getTask();
    assertNotSame(task, task1);
    assertFalse(task.equals(task1));

    List<Comment> comments1 = task1.getTaskData().getComments();
    assertEquals(1, comments1.size());
    Comment returnedComment = comments1.get(0);
    assertEquals("This is my comment1!!!!!", returnedComment.getText());
    assertEquals(addedAt, returnedComment.getAddedAt());
    assertEquals(users.get("luke"), returnedComment.getAddedBy());

    assertEquals((long) addCommentResponseHandler.getCommentId(), (long) returnedComment.getId());

    // Make the same as the returned tasks, so we can test equals
    task.getTaskData().setComments(comments1);
    task.getTaskData().setStatus(Status.Created);
    assertEquals(task, task1);

    // test we can have multiple comments
    comment = new Comment();
    addedAt = new Date(System.currentTimeMillis());
    comment.setAddedAt(addedAt);
    comment.setAddedBy(users.get("tony"));
    comment.setText("This is my comment2!!!!!");

    addCommentResponseHandler = new BlockingAddCommentResponseHandler();
    client.addComment(taskId, comment, addCommentResponseHandler);

    getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    task1 = getTaskResponseHandler.getTask();
    List<Comment> comments2 = task1.getTaskData().getComments();
    assertEquals(2, comments2.size());

    // make two collections the same and compare
    comments1.add(comment);
    assertTrue(CollectionUtils.equals(comments1, comments2));

    BlockingDeleteCommentResponseHandler deleteCommentResponseHandler =
        new BlockingDeleteCommentResponseHandler();
    client.deleteComment(
        taskId, addCommentResponseHandler.getCommentId(), deleteCommentResponseHandler);
    deleteCommentResponseHandler.waitTillDone(3000);

    getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    task1 = getTaskResponseHandler.getTask();
    comments2 = task1.getTaskData().getComments();
    assertEquals(1, comments2.size());

    assertEquals("This is my comment1!!!!!", comments2.get(0).getText());
  }
  @Override
  public Task convert(org.jbpm.task.query.TaskSummary source) {

    Task target = new Task();

    target.setDescription(source.getDescription());

    if (source.getActualOwner() != null) {
      target.setAssignee(source.getActualOwner().getId());
    }

    if (source.getCreatedOn() != null) {
      target.setCreateTime(convert(source.getCreatedOn(), XMLGregorianCalendar.class));
    }

    if (source.getExpirationTime() != null) {
      target.setDueDate(convert(source.getExpirationTime(), XMLGregorianCalendar.class));
    }
    target.setId(String.valueOf(source.getId()));

    if (source.getName() != null) {
      String[] parts = source.getName().split("/");
      target.setActivityName(parts[0]);
      target.setName(parts[1]);
    }

    target.setState(source.getStatus().name());

    target.setPriority(new Integer(source.getPriority()));
    target.setProcessInstanceId(
        source.getProcessId() + "." + Long.toString(source.getProcessInstanceId()));

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    taskClient.getTask(source.getId(), getTaskResponseHandler);
    org.jbpm.task.Task task = getTaskResponseHandler.getTask();

    BlockingGetContentResponseHandler getContentResponseHandler =
        new BlockingGetContentResponseHandler();
    taskClient.getContent(task.getTaskData().getDocumentContentId(), getContentResponseHandler);
    Content content = getContentResponseHandler.getContent();

    Map<String, Object> map =
        (Map<String, Object>) ContentMarshallerHelper.unmarshall(content.getContent(), null);

    for (String key : map.keySet()) {
      log.debug("Key: " + key);
    }

    // add task outcomes using the "Options" variable from the task
    String optionsString = (String) map.get("Options");
    if (optionsString != null) {
      String[] options = ((String) map.get("Options")).split(",");
      target.getOutcomes().addAll(Arrays.asList(options));
    }

    // get ad-hoc variables map

    Map<String, Object> contentMap =
        (Map<String, Object>) map.get(Bpmn20UserTaskNodeBuilder.TASK_INPUT_VARIABLES_NAME);
    if (contentMap != null) {
      for (Entry<String, Object> entry : contentMap.entrySet()) {
        log.debug(entry.getKey() + "=" + entry.getValue());
        addVariable(target, entry.getKey(), entry.getValue());
      }
    } else {
      log.debug("No Content found for task");
    }

    // add variables
    /*Set<String> names = taskService.getVariableNames(source.getId());
    Map<String, Object> variables = taskService.getVariables(source.getId(), names);
    // remove process name var
    variables.remove("_name");
    for (String key : variables.keySet()) {
        Variable var = new Variable();
        var.setName(key);
        // Support strings only.  Other types will cause ClassCastException
        try {
            var.setValue((String) variables.get(key));
        } catch (ClassCastException e) {
            var.setValue("Variable type " + variables.get(key).getClass().getName() + " is not supported");
        }
        addVariable(target, var);
    }

    // Do this only if the task is not an ad-hoc task (as indicated by null executionId)
    if (source.getExecutionId() != null) {

        // name is the 'form' attribute in JPDL
        // this is used in the COW schema to store the display name, as distinct from the system-generated name
        target.setName(source.getFormResourceName());

        // activityName is the 'name' from JPDL
        target.setActivityName(source.getActivityName());

        Execution ex = executionService.findExecutionById(source.getExecutionId());
        target.setProcessInstanceId(ex.getProcessInstance().getId());

        // outcomes
        Set<String> outcomes = taskService.getOutcomes(source.getId());
        for (String outcome : outcomes) {
            target.getOutcomes().add(outcome);
        }

        // Workaround to the fact that we cannot use autowiring here
        if (this.cowTaskService == null) {
            this.cowTaskService = (org.wiredwidgets.cow.server.service.TaskService) this.factory.getBean("taskService");
        }

        // add process level task varibles (
        String executionId = getTopLevelExecutionId(source.getExecutionId());
        org.wiredwidgets.cow.server.api.model.v2.Activity activity = cowTaskService.getWorkflowActivity(executionId, source.getActivityName());
        if (activity != null && activity instanceof org.wiredwidgets.cow.server.api.model.v2.Task) {
            org.wiredwidgets.cow.server.api.model.v2.Task cowTask = (org.wiredwidgets.cow.server.api.model.v2.Task) activity;
            if (cowTask.getVariables() != null) {
                for (org.wiredwidgets.cow.server.api.model.v2.Variable var : cowTask.getVariables().getVariables()) {
                    Variable newVar = new Variable();
                    newVar.setName(var.getName());
                    newVar.setValue(var.getValue());
                    addVariable(target, newVar);
                }
            }
        }
    } else {
        // for ad-hoc tasks
        target.setName(source.getName());
    }*/

    return target;
  }
  public void testAddRemoveAttachment() throws Exception {
    Map vars = new HashMap();
    vars.put("users", users);
    vars.put("groups", groups);
    vars.put("now", new Date());

    String str =
        "(with (new Task()) { priority = 55, taskData = (with( new TaskData()) { createdOn = now, activationTime = now}), ";
    str += "deadlines = new Deadlines(),";
    str += "delegation = new Delegation(),";
    str += "peopleAssignments = new PeopleAssignments(),";
    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();

    Attachment attachment = new Attachment();
    Date attachedAt = new Date(System.currentTimeMillis());
    attachment.setAttachedAt(attachedAt);
    attachment.setAttachedBy(users.get("luke"));
    attachment.setName("file1.txt");
    attachment.setAccessType(AccessType.Inline);
    attachment.setContentType("txt");

    byte[] bytes = "Ths is my attachment text1".getBytes();
    Content content = new Content();
    content.setContent(bytes);

    BlockingAddAttachmentResponseHandler addAttachmentResponseHandler =
        new BlockingAddAttachmentResponseHandler();
    client.addAttachment(taskId, attachment, content, addAttachmentResponseHandler);
    assertTrue(addAttachmentResponseHandler.getAttachmentId() != attachment.getId());
    assertTrue(addAttachmentResponseHandler.getContentId() != attachment.getAttachmentContentId());

    BlockingGetTaskResponseHandler getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    Task task1 = getTaskResponseHandler.getTask();
    assertNotSame(task, task1);
    assertFalse(task.equals(task1));

    List<Attachment> attachments1 = task1.getTaskData().getAttachments();
    assertEquals(1, attachments1.size());
    Attachment returnedAttachment = attachments1.get(0);
    assertEquals(attachedAt, returnedAttachment.getAttachedAt());
    assertEquals(users.get("luke"), returnedAttachment.getAttachedBy());
    assertEquals(AccessType.Inline, returnedAttachment.getAccessType());
    assertEquals("txt", returnedAttachment.getContentType());
    assertEquals("file1.txt", returnedAttachment.getName());
    assertEquals(bytes.length, returnedAttachment.getSize());

    assertEquals(
        (long) addAttachmentResponseHandler.getAttachmentId(), (long) returnedAttachment.getId());
    assertEquals(
        (long) addAttachmentResponseHandler.getContentId(),
        (long) returnedAttachment.getAttachmentContentId());

    // Make the same as the returned tasks, so we can test equals
    task.getTaskData().setAttachments(attachments1);
    task.getTaskData().setStatus(Status.Created);
    assertEquals(task, task1);

    BlockingGetContentResponseHandler getResponseHandler = new BlockingGetContentResponseHandler();
    client.getContent(returnedAttachment.getAttachmentContentId(), getResponseHandler);
    content = getResponseHandler.getContent();
    assertEquals("Ths is my attachment text1", new String(content.getContent()));

    // test we can have multiple attachments

    attachment = new Attachment();
    attachedAt = new Date(System.currentTimeMillis());
    attachment.setAttachedAt(attachedAt);
    attachment.setAttachedBy(users.get("tony"));
    attachment.setName("file2.txt");
    attachment.setAccessType(AccessType.Inline);
    attachment.setContentType("txt");

    bytes = "Ths is my attachment text2".getBytes();
    content = new Content();
    content.setContent(bytes);

    addAttachmentResponseHandler = new BlockingAddAttachmentResponseHandler();
    client.addAttachment(taskId, attachment, content, addAttachmentResponseHandler);

    getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    task1 = getTaskResponseHandler.getTask();
    assertNotSame(task, task1);
    assertFalse(task.equals(task1));

    List<Attachment> attachments2 = task1.getTaskData().getAttachments();
    assertEquals(2, attachments2.size());

    getResponseHandler = new BlockingGetContentResponseHandler();
    client.getContent(addAttachmentResponseHandler.getContentId(), getResponseHandler);
    content = getResponseHandler.getContent();
    assertEquals("Ths is my attachment text2", new String(content.getContent()));

    // make two collections the same and compare
    attachment.setSize(26);
    attachment.setAttachmentContentId(addAttachmentResponseHandler.getContentId());
    attachments1.add(attachment);
    assertTrue(CollectionUtils.equals(attachments2, attachments1));

    BlockingDeleteAttachmentResponseHandler deleteCommentResponseHandler =
        new BlockingDeleteAttachmentResponseHandler();
    client.deleteAttachment(
        taskId,
        addAttachmentResponseHandler.getAttachmentId(),
        addAttachmentResponseHandler.getContentId(),
        deleteCommentResponseHandler);
    deleteCommentResponseHandler.waitTillDone(3000);

    Thread.sleep(3000);

    getTaskResponseHandler = new BlockingGetTaskResponseHandler();
    client.getTask(taskId, getTaskResponseHandler);
    task1 = getTaskResponseHandler.getTask();
    attachments2 = task1.getTaskData().getAttachments();
    assertEquals(1, attachments2.size());

    assertEquals("file1.txt", attachments2.get(0).getName());
  }