@SuppressWarnings("unchecked")
  public void deleteHistoricProcessInstanceById(String historicProcessInstanceId) {
    if (getHistoryManager().isHistoryEnabled()) {
      CommandContext commandContext = Context.getCommandContext();
      HistoricProcessInstanceEntity historicProcessInstance =
          findHistoricProcessInstance(historicProcessInstanceId);

      commandContext
          .getHistoricDetailEntityManager()
          .deleteHistoricDetailsByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricVariableInstanceEntityManager()
          .deleteHistoricVariableInstanceByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricActivityInstanceEntityManager()
          .deleteHistoricActivityInstancesByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricTaskInstanceEntityManager()
          .deleteHistoricTaskInstancesByProcessInstanceId(historicProcessInstanceId);

      commandContext
          .getHistoricIdentityLinkEntityManager()
          .deleteHistoricIdentityLinksByProcInstance(historicProcessInstanceId);

      commandContext
          .getCommentEntityManager()
          .deleteCommentsByProcessInstanceId(historicProcessInstanceId);

      getDbSqlSession().delete(historicProcessInstance);

      // Also delete any sub-processes that may be active (ACT-821)
      HistoricProcessInstanceQueryImpl subProcessesQueryImpl =
          new HistoricProcessInstanceQueryImpl();
      subProcessesQueryImpl.superProcessInstanceId(historicProcessInstanceId);

      List<HistoricProcessInstance> selectList =
          getDbSqlSession()
              .selectList("selectHistoricProcessInstancesByQueryCriteria", subProcessesQueryImpl);
      for (HistoricProcessInstance child : selectList) {
        deleteHistoricProcessInstanceById(child.getId());
      }
    }
  }
  @SuppressWarnings("unchecked")
  public List<HistoricProcessInstance> findHistoricProcessInstancesAndVariablesByQueryCriteria(
      HistoricProcessInstanceQueryImpl historicProcessInstanceQuery) {
    if (getHistoryManager().isHistoryEnabled()) {
      // paging doesn't work for combining process instances and variables due to an outer join, so
      // doing it in-memory
      if (historicProcessInstanceQuery.getFirstResult() < 0
          || historicProcessInstanceQuery.getMaxResults() <= 0) {
        return Collections.EMPTY_LIST;
      }

      int firstResult = historicProcessInstanceQuery.getFirstResult();
      int maxResults = historicProcessInstanceQuery.getMaxResults();

      // setting max results, limit to 20000 results for performance reasons
      historicProcessInstanceQuery.setMaxResults(20000);
      historicProcessInstanceQuery.setFirstResult(0);

      List<HistoricProcessInstance> instanceList =
          getDbSqlSession()
              .selectListWithRawParameterWithoutFilter(
                  "selectHistoricProcessInstancesWithVariablesByQueryCriteria",
                  historicProcessInstanceQuery,
                  historicProcessInstanceQuery.getFirstResult(),
                  historicProcessInstanceQuery.getMaxResults());

      if (instanceList != null && !instanceList.isEmpty()) {
        if (firstResult > 0) {
          if (firstResult <= instanceList.size()) {
            int toIndex = firstResult + Math.min(maxResults, instanceList.size() - firstResult);
            return instanceList.subList(firstResult, toIndex);
          } else {
            return Collections.EMPTY_LIST;
          }
        } else {
          int toIndex = Math.min(maxResults, instanceList.size());
          return instanceList.subList(0, toIndex);
        }
      }
    }
    return Collections.EMPTY_LIST;
  }