@Post
  public MembershipResponse createMembership(MembershipRequest memberShip) {
    if (authenticate() == false) return null;

    Group group = getGroupFromRequest();

    if (memberShip.getUserId() == null) {
      throw new ActivitiIllegalArgumentException("UserId cannot be null.");
    }

    // Check if user is member of group since API doesn't return typed exception
    if (ActivitiUtil.getIdentityService()
            .createUserQuery()
            .memberOfGroup(group.getId())
            .userId(memberShip.getUserId())
            .count()
        > 0) {
      throw new ResourceException(
          Status.CLIENT_ERROR_CONFLICT.getCode(),
          "User '" + memberShip.getUserId() + "' is already part of group '" + group.getId() + "'.",
          null,
          null);
    }

    ActivitiUtil.getIdentityService().createMembership(memberShip.getUserId(), group.getId());
    setStatus(Status.SUCCESS_CREATED);

    return getApplication(ActivitiRestServicesApplication.class)
        .getRestResponseFactory()
        .createMembershipResponse(this, memberShip.getUserId(), group.getId());
  }
  @Post
  public ObjectNode startProcessInstance(Representation entity) {
    try {
      if (authenticate(SecuredResource.ADMIN) == false) return null;

      String startParams = entity.getText();
      JsonNode startJSON = new ObjectMapper().readTree(startParams);
      ArrayNode jobIdsJSON = (ArrayNode) startJSON.get("jobIds");
      for (JsonNode jobId : jobIdsJSON) {
        ActivitiUtil.getManagementService().executeJob(jobId.textValue());
      }

      ObjectNode successNode = new ObjectMapper().createObjectNode();
      successNode.put("success", true);
      return successNode;

    } catch (Exception e) {
      if (e instanceof ActivitiException) {
        throw (ActivitiException) e;
      } else {
        throw new ActivitiException("Failed to execute jobs", e);
      }
    }
  }
  protected DataResponse getQueryResponse(
      HistoricProcessInstanceQueryRequest queryRequest, Form urlQuery) {
    HistoricProcessInstanceQuery query =
        ActivitiUtil.getHistoryService().createHistoricProcessInstanceQuery();

    // Populate query based on request
    if (queryRequest.getProcessInstanceId() != null) {
      query.processInstanceId(queryRequest.getProcessInstanceId());
    }
    if (queryRequest.getProcessInstanceIds() != null
        && !queryRequest.getProcessInstanceIds().isEmpty()) {
      query.processInstanceIds(new HashSet<String>(queryRequest.getProcessInstanceIds()));
    }
    if (queryRequest.getProcessDefinitionKey() != null) {
      query.processDefinitionKey(queryRequest.getProcessDefinitionKey());
    }
    if (queryRequest.getProcessDefinitionId() != null) {
      query.processDefinitionId(queryRequest.getProcessDefinitionId());
    }
    if (queryRequest.getProcessBusinessKey() != null) {
      query.processInstanceBusinessKey(queryRequest.getProcessBusinessKey());
    }
    if (queryRequest.getInvolvedUser() != null) {
      query.involvedUser(queryRequest.getInvolvedUser());
    }
    if (queryRequest.getSuperProcessInstanceId() != null) {
      query.superProcessInstanceId(queryRequest.getSuperProcessInstanceId());
    }
    if (queryRequest.getExcludeSubprocesses() != null) {
      query.excludeSubprocesses(queryRequest.getExcludeSubprocesses());
    }
    if (queryRequest.getFinishedAfter() != null) {
      query.finishedAfter(queryRequest.getFinishedAfter());
    }
    if (queryRequest.getFinishedBefore() != null) {
      query.finishedBefore(queryRequest.getFinishedBefore());
    }
    if (queryRequest.getStartedAfter() != null) {
      query.startedAfter(queryRequest.getStartedAfter());
    }
    if (queryRequest.getStartedBefore() != null) {
      query.startedBefore(queryRequest.getStartedBefore());
    }
    if (queryRequest.getStartedBy() != null) {
      query.startedBy(queryRequest.getStartedBy());
    }
    if (queryRequest.getFinished() != null) {
      if (queryRequest.getFinished()) {
        query.finished();
      } else {
        query.unfinished();
      }
    }
    if (queryRequest.getIncludeProcessVariables() != null) {
      if (queryRequest.getIncludeProcessVariables()) {
        query.includeProcessVariables();
      }
    }
    if (queryRequest.getVariables() != null) {
      addVariables(query, queryRequest.getVariables());
    }

    if (queryRequest.getTenantId() != null) {
      query.processInstanceTenantId(queryRequest.getTenantId());
    }

    if (queryRequest.getTenantIdLike() != null) {
      query.processInstanceTenantIdLike(queryRequest.getTenantIdLike());
    }

    if (Boolean.TRUE.equals(queryRequest.getWithoutTenantId())) {
      query.processInstanceWithoutTenantId();
    }

    return new HistoricProcessInstancePaginateList(this)
        .paginateList(urlQuery, queryRequest, query, "processInstanceId", allowedSortProperties);
  }