@Override
  public String endTask(
      CoreSession coreSession,
      NuxeoPrincipal principal,
      Task task,
      String comment,
      String eventName,
      boolean isValidated)
      throws ClientException {

    // put user comment on the task
    if (!StringUtils.isEmpty(comment)) {
      task.addComment(principal.getName(), comment);
    }

    // end the task, adding boolean marker that task was validated or
    // rejected
    task.setVariable(TaskService.VariableName.validated.name(), String.valueOf(isValidated));
    task.end(coreSession);
    coreSession.saveDocument(task.getDocument());
    // notify
    Map<String, Serializable> eventProperties = new HashMap<String, Serializable>();
    ArrayList<String> notificationRecipients = new ArrayList<String>();
    notificationRecipients.add(task.getInitiator());
    notificationRecipients.addAll(task.getActors());
    eventProperties.put(NotificationConstants.RECIPIENTS_KEY, notificationRecipients);
    // try to resolve document when notifying
    DocumentModel document = null;
    String docId = task.getVariable(TaskService.VariableName.documentId.name());
    String docRepo = task.getVariable(TaskService.VariableName.documentRepositoryName.name());
    if (coreSession.getRepositoryName().equals(docRepo)) {
      try {
        document = coreSession.getDocument(new IdRef(docId));
      } catch (Exception e) {
        log.error(
            String.format(
                "Could not fetch document with id '%s:%s' for notification", docRepo, docId),
            e);
      }
    } else {
      log.error(
          String.format(
              "Could not resolve document for notification: "
                  + "document is on repository '%s' and given session is on "
                  + "repository '%s'",
              docRepo, coreSession.getRepositoryName()));
    }

    TaskEventNotificationHelper.notifyEvent(
        coreSession, document, principal, task, eventName, eventProperties, comment, null);

    String seamEventName =
        isValidated
            ? TaskEventNames.WORKFLOW_TASK_COMPLETED
            : TaskEventNames.WORKFLOW_TASK_REJECTED;
    return seamEventName;
  }