@Override
  public void addClaimedUser(Context context, XmlWorkflowItem wfi, Step step, EPerson user)
      throws SQLException, AuthorizeException, IOException {

    // Make sure we delete the pooled task for our current user if the task is not a group pooltask
    PoolTask task = poolTaskService.findByWorkflowIdAndEPerson(context, wfi, user);
    if (task != null && task.getEperson() != null) {
      xmlWorkflowService.deletePooledTask(context, wfi, task);
    }

    InProgressUser ipu = inProgressUserService.create(context);
    ipu.setWorkflowItem(wfi);
    ipu.setUser(user);
    ipu.setFinished(false);
    inProgressUserService.update(context, ipu);
    int totalUsers =
        inProgressUserService.getNumberOfInProgressUsers(context, wfi)
            + inProgressUserService.getNumberOfFinishedUsers(context, wfi);

    if (totalUsers == step.getRequiredUsers()) {
      // If enough users have claimed/finished this step then remove the tasks
      xmlWorkflowService.deleteAllPooledTasks(context, wfi);
    }
    xmlWorkflowItemService.update(context, wfi);
  }
 /*
  * Deletes an eperson from the taskpool of a step
  */
 @Override
 public void deletePooledTask(Context context, XmlWorkflowItem wi, PoolTask task)
     throws SQLException, AuthorizeException {
   if (task != null) {
     if (task.getEperson() != null) {
       removeUserItemPolicies(context, wi.getItem(), task.getEperson());
     } else {
       removeGroupItemPolicies(context, wi.getItem(), task.getGroup());
     }
     poolTaskService.delete(context, task);
   }
 }
 /*
  * Creates a task pool for a given step
  */
 @Override
 public void createPoolTasks(
     Context context,
     XmlWorkflowItem wi,
     RoleMembers assignees,
     Step step,
     WorkflowActionConfig action)
     throws SQLException, AuthorizeException {
   // create a tasklist entry for each eperson
   for (EPerson anEpa : assignees.getEPersons()) {
     PoolTask task = poolTaskService.create(context);
     task.setStepID(step.getId());
     task.setWorkflowID(step.getWorkflow().getID());
     task.setEperson(anEpa);
     task.setActionID(action.getId());
     task.setWorkflowItem(wi);
     poolTaskService.update(context, task);
     // Make sure this user has a task
     grantUserAllItemPolicies(context, wi.getItem(), anEpa);
   }
   for (Group group : assignees.getGroups()) {
     PoolTask task = poolTaskService.create(context);
     task.setStepID(step.getId());
     task.setWorkflowID(step.getWorkflow().getID());
     task.setGroup(group);
     task.setActionID(action.getId());
     task.setWorkflowItem(wi);
     poolTaskService.update(context, task);
     // Make sure this user has a task
     grantGroupAllItemPolicies(context, wi.getItem(), group);
   }
 }
  protected void logWorkflowEvent(
      Context c,
      String workflowId,
      String previousStepId,
      String previousActionConfigId,
      XmlWorkflowItem wfi,
      EPerson actor,
      Step newStep,
      WorkflowActionConfig newActionConfig)
      throws SQLException {
    try {
      // Fire an event so we can log our action !
      Item item = wfi.getItem();
      Collection myCollection = wfi.getCollection();
      String workflowStepString = null;

      List<EPerson> currentEpersonOwners = new ArrayList<EPerson>();
      List<Group> currentGroupOwners = new ArrayList<Group>();
      // These are only null if our item is sent back to the submission
      if (newStep != null && newActionConfig != null) {
        workflowStepString = workflowId + "." + newStep.getId() + "." + newActionConfig.getId();

        // Retrieve the current owners of the task
        List<ClaimedTask> claimedTasks = claimedTaskService.find(c, wfi, newStep.getId());
        List<PoolTask> pooledTasks = poolTaskService.find(c, wfi);
        for (PoolTask poolTask : pooledTasks) {
          if (poolTask.getEperson() != null) {
            currentEpersonOwners.add(poolTask.getEperson());
          } else {
            currentGroupOwners.add(poolTask.getGroup());
          }
        }
        for (ClaimedTask claimedTask : claimedTasks) {
          currentEpersonOwners.add(claimedTask.getOwner());
        }
      }
      String previousWorkflowStepString = null;
      if (previousStepId != null && previousActionConfigId != null) {
        previousWorkflowStepString =
            workflowId + "." + previousStepId + "." + previousActionConfigId;
      }

      // Fire our usage event !
      UsageWorkflowEvent usageWorkflowEvent =
          new UsageWorkflowEvent(
              c, item, wfi, workflowStepString, previousWorkflowStepString, myCollection, actor);

      usageWorkflowEvent.setEpersonOwners(
          currentEpersonOwners.toArray(new EPerson[currentEpersonOwners.size()]));
      usageWorkflowEvent.setGroupOwners(
          currentGroupOwners.toArray(new Group[currentGroupOwners.size()]));

      DSpaceServicesFactory.getInstance().getEventService().fireEvent(usageWorkflowEvent);
    } catch (Exception e) {
      // Catch all errors we do not want our workflow to crash because the logging threw an
      // exception
      log.error(
          LogManager.getHeader(
              c, "Error while logging workflow event", "Workflow Item: " + wfi.getID()),
          e);
    }
  }