content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.activiti.engine.test.api.history;
  
  import static java.util.Arrays.asList;
  import static java.util.Collections.emptyMap;
  import static java.util.Collections.singletonMap;
  import static org.activiti.engine.impl.util.CollectionUtil.map;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
  
  import com.fasterxml.jackson.databind.node.ObjectNode;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import org.activiti.engine.ActivitiIllegalArgumentException;
  import org.activiti.engine.history.DeleteReason;
  import org.activiti.engine.history.HistoricProcessInstance;
  import org.activiti.engine.history.HistoricProcessInstanceQuery;
  import org.activiti.engine.history.HistoricTaskInstance;
  import org.activiti.engine.history.HistoricTaskInstanceQuery;
  import org.activiti.engine.impl.identity.Authentication;
  import org.activiti.engine.impl.test.PluggableActivitiTestCase;
  import org.activiti.engine.runtime.ProcessInstance;
  import org.activiti.engine.task.Task;
  import org.activiti.engine.task.TaskQuery;
  import org.activiti.engine.test.Deployment;
  import org.activiti.engine.test.api.runtime.ProcessInstanceQueryTest;
  
  /**
   */
  public class HistoryServiceTest extends PluggableActivitiTestCase {
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceQuery() {
          // With a clean ProcessEngine, no instances should be available
          assertThat(historyService.createHistoricProcessInstanceQuery().count() == 0).isTrue();
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
          assertThat(historyService.createHistoricProcessInstanceQuery().count() == 1).isTrue();
  
          // Complete the task and check if the size is count 1
          List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
          assertThat(tasks).hasSize(1);
          taskService.complete(tasks.get(0).getId());
          assertThat(historyService.createHistoricProcessInstanceQuery().count() == 1).isTrue();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceQueryOrderBy() {
          // With a clean ProcessEngine, no instances should be available
          assertThat(historyService.createHistoricProcessInstanceQuery().count() == 0).isTrue();
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
  
          List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
          assertThat(tasks).hasSize(1);
          taskService.complete(tasks.get(0).getId());
  
          historyService.createHistoricTaskInstanceQuery().orderByDeleteReason().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByExecutionId().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByHistoricActivityInstanceId().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskCreateTime().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByHistoricTaskInstanceDuration().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByHistoricTaskInstanceEndTime().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByProcessDefinitionId().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByProcessInstanceId().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskAssignee().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskDefinitionKey().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskDescription().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskId().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskName().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskOwner().asc().list();
          historyService.createHistoricTaskInstanceQuery().orderByTaskPriority().asc().list();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceUserIdAndActivityId() {
          Authentication.setAuthenticatedUserId("johndoe");
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
          HistoricProcessInstance historicProcessInstance = historyService
              .createHistoricProcessInstanceQuery()
              .singleResult();
          assertThat(historicProcessInstance.getStartUserId()).isEqualTo("johndoe");
          assertThat(historicProcessInstance.getStartActivityId()).isEqualTo("theStart");
  
          List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
          assertThat(tasks).hasSize(1);
          taskService.complete(tasks.get(0).getId());
  
          historicProcessInstance = historyService.createHistoricProcessInstanceQuery().singleResult();
          assertThat(historicProcessInstance.getEndActivityId()).isEqualTo("theEnd");
      }
  
      @Deployment(
          resources = {
              "org/activiti/examples/bpmn/callactivity/orderProcess.bpmn20.xml",
              "org/activiti/examples/bpmn/callactivity/checkCreditProcess.bpmn20.xml",
          }
      )
      public void testOrderProcessWithCallActivity() {
          // After the process has started, the 'verify credit history' task
          // should be
          // active
          ProcessInstance pi = runtimeService.startProcessInstanceByKey("orderProcess");
          TaskQuery taskQuery = taskService.createTaskQuery();
          Task verifyCreditTask = taskQuery.singleResult();
  
          // Completing the task with approval, will end the subprocess and
          // continue
          // the original process
          taskService.complete(verifyCreditTask.getId(), singletonMap("creditApproved", true));
          Task prepareAndShipTask = taskQuery.singleResult();
          assertThat(prepareAndShipTask.getName()).isEqualTo("Prepare and Ship");
  
          // verify
          HistoricProcessInstance historicProcessInstance = historyService
              .createHistoricProcessInstanceQuery()
              .superProcessInstanceId(pi.getId())
              .singleResult();
          assertThat(historicProcessInstance).isNotNull();
          assertThat(historicProcessInstance.getProcessDefinitionId().contains("checkCreditProcess")).isTrue();
      }
  
      @Deployment(
          resources = {
              "org/activiti/examples/bpmn/callactivity/orderProcess.bpmn20.xml",
              "org/activiti/examples/bpmn/callactivity/checkCreditProcess.bpmn20.xml",
          }
      )
      public void testExcludeSubprocesses() {
          ProcessInstance pi = runtimeService.startProcessInstanceByKey("orderProcess");
  
          HistoricProcessInstance historicProcessInstance = historyService
              .createHistoricProcessInstanceQuery()
              .excludeSubprocesses(true)
              .singleResult();
          assertThat(historicProcessInstance).isNotNull();
          assertThat(historicProcessInstance.getId()).isEqualTo(pi.getId());
  
          List<HistoricProcessInstance> instanceList = historyService
              .createHistoricProcessInstanceQuery()
              .excludeSubprocesses(false)
              .list();
          assertThat(instanceList).hasSize(2);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/examples/bpmn/callactivity/orderProcess.bpmn20.xml",
              "org/activiti/examples/bpmn/callactivity/checkCreditProcess.bpmn20.xml",
          }
      )
      public void testHistoricProcessInstanceQueryByProcessDefinitionKey() {
          String processDefinitionKey = "oneTaskProcess";
          runtimeService.startProcessInstanceByKey(processDefinitionKey);
          runtimeService.startProcessInstanceByKey("orderProcess");
          HistoricProcessInstance historicProcessInstance = historyService
              .createHistoricProcessInstanceQuery()
              .processDefinitionKey(processDefinitionKey)
              .singleResult();
          assertThat(historicProcessInstance).isNotNull();
          assertThat(historicProcessInstance.getProcessDefinitionKey().equals(processDefinitionKey)).isTrue();
          assertThat(historicProcessInstance.getStartActivityId()).isEqualTo("theStart");
  
          // now complete the task to end the process instance
          Task task = taskService.createTaskQuery().processDefinitionKey("checkCreditProcess").singleResult();
          taskService.complete(task.getId(), singletonMap("creditApproved", true));
  
          // and make sure the super process instance is set correctly on the
          // HistoricProcessInstance
          HistoricProcessInstance historicProcessInstanceSub = historyService
              .createHistoricProcessInstanceQuery()
              .processDefinitionKey("checkCreditProcess")
              .singleResult();
          HistoricProcessInstance historicProcessInstanceSuper = historyService
              .createHistoricProcessInstanceQuery()
              .processDefinitionKey("orderProcess")
              .singleResult();
          assertThat(historicProcessInstanceSub.getSuperProcessInstanceId()).isEqualTo(
              historicProcessInstanceSuper.getId()
          );
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricProcessInstanceQueryByProcessInstanceIds() {
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          // start an instance that will not be part of the query
          runtimeService.startProcessInstanceByKey("oneTaskProcess2", "2");
  
          HistoricProcessInstanceQuery processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceIds(processInstanceIds);
          assertThat(processInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricProcessInstance> processInstances = processInstanceQuery.list();
          assertThat(processInstances).isNotNull();
          assertThat(processInstances).hasSize(5);
  
          for (HistoricProcessInstance historicProcessInstance : processInstances) {
              assertThat(processInstanceIds.contains(historicProcessInstance.getId())).isTrue();
          }
      }
  
      public void testHistoricProcessInstanceQueryByProcessInstanceIdsEmpty() {
          assertThatExceptionOfType(ActivitiIllegalArgumentException.class)
              .as("ActivitiException expected")
              .isThrownBy(() -> historyService.createHistoricProcessInstanceQuery().processInstanceIds(new HashSet<>()))
              .withMessageContaining("Set of process instance ids is empty");
      }
  
      public void testHistoricProcessInstanceQueryByProcessInstanceIdsNull() {
          assertThatExceptionOfType(ActivitiIllegalArgumentException.class)
              .as("ActivitiException expected")
              .isThrownBy(() -> historyService.createHistoricProcessInstanceQuery().processInstanceIds(null))
              .withMessageContaining("Set of process instance ids is null");
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceQueryForDelete() {
          String processInstanceId = runtimeService.startProcessInstanceByKey("oneTaskProcess").getId();
          runtimeService.deleteProcessInstance(processInstanceId, null);
  
          HistoricProcessInstanceQuery processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId);
          assertThat(processInstanceQuery.count()).isEqualTo(1);
          HistoricProcessInstance processInstance = processInstanceQuery.singleResult();
          assertThat(processInstance.getId()).isEqualTo(processInstanceId);
          assertThat(processInstance.getDeleteReason()).isEqualTo(DeleteReason.PROCESS_INSTANCE_DELETED);
  
          processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId)
              .deleted();
          assertThat(processInstanceQuery.count()).isEqualTo(1);
          processInstance = processInstanceQuery.singleResult();
          assertThat(processInstance.getId()).isEqualTo(processInstanceId);
          assertThat(processInstance.getDeleteReason()).isEqualTo(DeleteReason.PROCESS_INSTANCE_DELETED);
  
          processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId)
              .notDeleted();
          assertThat(processInstanceQuery.count()).isEqualTo(0);
  
          historyService.deleteHistoricProcessInstance(processInstanceId);
          processInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId);
          assertThat(processInstanceQuery.count()).isEqualTo(0);
  
          processInstanceId = runtimeService.startProcessInstanceByKey("oneTaskProcess").getId();
          runtimeService.deleteProcessInstance(processInstanceId, "custom message");
  
          processInstanceQuery = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId);
          assertThat(processInstanceQuery.count()).isEqualTo(1);
          processInstance = processInstanceQuery.singleResult();
          assertThat(processInstance.getId()).isEqualTo(processInstanceId);
          assertThat(processInstance.getDeleteReason()).isEqualTo("custom message");
  
          processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId)
              .deleted();
          assertThat(processInstanceQuery.count()).isEqualTo(1);
          processInstance = processInstanceQuery.singleResult();
          assertThat(processInstance.getId()).isEqualTo(processInstanceId);
          assertThat(processInstance.getDeleteReason()).isEqualTo("custom message");
  
          processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .processInstanceId(processInstanceId)
              .notDeleted();
          assertThat(processInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricProcessInstanceQueryByDeploymentId() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          HistoricProcessInstanceQuery processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .deploymentId(deployment.getId());
          assertThat(processInstanceQuery.count()).isEqualTo(5);
          assertThat(processInstanceQuery.list().get(0).getDeploymentId()).isEqualTo(deployment.getId());
  
          List<HistoricProcessInstance> processInstances = processInstanceQuery.list();
          assertThat(processInstances).isNotNull();
          assertThat(processInstances).hasSize(5);
  
          processInstanceQuery = historyService.createHistoricProcessInstanceQuery().deploymentId("invalid");
          assertThat(processInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricProcessInstanceQueryByDeploymentIdIn() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          List<String> deploymentIds = new ArrayList<String>();
          deploymentIds.add(deployment.getId());
          deploymentIds.add("invalid");
          HistoricProcessInstanceQuery processInstanceQuery = historyService
              .createHistoricProcessInstanceQuery()
              .deploymentIdIn(deploymentIds);
          assertThat(processInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricProcessInstance> processInstances = processInstanceQuery.list();
          assertThat(processInstances).isNotNull();
          assertThat(processInstances).hasSize(5);
  
          deploymentIds = new ArrayList<String>();
          deploymentIds.add("invalid");
          processInstanceQuery = historyService.createHistoricProcessInstanceQuery().deploymentIdIn(deploymentIds);
          assertThat(processInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricTaskInstanceQueryByDeploymentId() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          HistoricTaskInstanceQuery taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .deploymentId(deployment.getId());
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();
          assertThat(taskInstances).isNotNull();
          assertThat(taskInstances).hasSize(5);
  
          taskInstanceQuery = historyService.createHistoricTaskInstanceQuery().deploymentId("invalid");
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricTaskInstanceQueryByDeploymentIdIn() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          List<String> deploymentIds = new ArrayList<String>();
          deploymentIds.add(deployment.getId());
          HistoricTaskInstanceQuery taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .deploymentIdIn(deploymentIds);
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();
          assertThat(taskInstances).isNotNull();
          assertThat(taskInstances).hasSize(5);
  
          deploymentIds.add("invalid");
          taskInstanceQuery = historyService.createHistoricTaskInstanceQuery().deploymentIdIn(deploymentIds);
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          deploymentIds = new ArrayList<String>();
          deploymentIds.add("invalid");
          taskInstanceQuery = historyService.createHistoricTaskInstanceQuery().deploymentIdIn(deploymentIds);
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricTaskInstanceOrQueryByDeploymentId() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          HistoricTaskInstanceQuery taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .deploymentId(deployment.getId())
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();
          assertThat(taskInstances).isNotNull();
          assertThat(taskInstances).hasSize(5);
  
          taskInstanceQuery = historyService.createHistoricTaskInstanceQuery().or().deploymentId("invalid").endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .taskDefinitionKey("theTask")
              .or()
              .deploymentId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr()
              .or()
              .processDefinitionKey("oneTaskProcess")
              .processDefinitionId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(4);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr()
              .or()
              .processDefinitionKey("oneTaskProcess2")
              .processDefinitionId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(1);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr()
              .or()
              .processDefinitionKey("oneTaskProcess")
              .processDefinitionId("invalid")
              .endOr()
              .processInstanceBusinessKey("1");
          assertThat(taskInstanceQuery.count()).isEqualTo(1);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr()
              .or()
              .processDefinitionKey("oneTaskProcess2")
              .processDefinitionId("invalid")
              .endOr()
              .processInstanceBusinessKey("1");
          assertThat(taskInstanceQuery.count()).isEqualTo(1);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentId("invalid")
              .endOr()
              .or()
              .processDefinitionKey("oneTaskProcess2")
              .processDefinitionId("invalid")
              .endOr()
              .processInstanceBusinessKey("2");
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(
          resources = {
              "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml",
              "org/activiti/engine/test/api/runtime/oneTaskProcess2.bpmn20.xml",
          }
      )
      public void testHistoricTaskInstanceOrQueryByDeploymentIdIn() {
          org.activiti.engine.repository.Deployment deployment = repositoryService.createDeploymentQuery().singleResult();
          HashSet<String> processInstanceIds = new HashSet<String>();
          for (int i = 0; i < 4; i++) {
              processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess", i + "").getId());
          }
          processInstanceIds.add(runtimeService.startProcessInstanceByKey("oneTaskProcess2", "1").getId());
  
          List<String> deploymentIds = new ArrayList<String>();
          deploymentIds.add(deployment.getId());
          HistoricTaskInstanceQuery taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .deploymentIdIn(deploymentIds)
              .processDefinitionId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          List<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();
          assertThat(taskInstances).isNotNull();
          assertThat(taskInstances).hasSize(5);
  
          deploymentIds.add("invalid");
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .deploymentIdIn(deploymentIds)
              .processDefinitionId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          deploymentIds = new ArrayList<String>();
          deploymentIds.add("invalid");
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .deploymentIdIn(deploymentIds)
              .processDefinitionId("invalid")
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .or()
              .taskDefinitionKey("theTask")
              .deploymentIdIn(deploymentIds)
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(5);
  
          taskInstanceQuery = historyService
              .createHistoricTaskInstanceQuery()
              .taskDefinitionKey("theTask")
              .or()
              .deploymentIdIn(deploymentIds)
              .endOr();
          assertThat(taskInstanceQuery.count()).isEqualTo(0);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testLocalizeTasks() throws Exception {
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
  
          List<HistoricTaskInstance> tasks = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .list();
          assertThat(tasks).hasSize(1);
          assertThat(tasks.get(0).getName()).isEqualTo("my task");
          assertThat(tasks.get(0).getDescription()).isNull();
  
          ObjectNode infoNode = dynamicBpmnService.changeLocalizationName("en-GB", "theTask", "My localized name");
          dynamicBpmnService.changeLocalizationDescription(
              "en-GB".toString(),
              "theTask",
              "My localized description",
              infoNode
          );
          dynamicBpmnService.saveProcessDefinitionInfo(processInstance.getProcessDefinitionId(), infoNode);
  
          tasks = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .list();
          assertThat(tasks).hasSize(1);
          assertThat(tasks.get(0).getName()).isEqualTo("my task");
          assertThat(tasks.get(0).getDescription()).isNull();
  
          tasks = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .locale("en-GB")
              .list();
          assertThat(tasks).hasSize(1);
          assertThat(tasks.get(0).getName()).isEqualTo("My localized name");
          assertThat(tasks.get(0).getDescription()).isEqualTo("My localized description");
  
          tasks = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .listPage(0, 10);
          assertThat(tasks).hasSize(1);
          assertThat(tasks.get(0).getName()).isEqualTo("my task");
          assertThat(tasks.get(0).getDescription()).isNull();
  
          tasks = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .locale("en-GB")
              .listPage(0, 10);
          assertThat(tasks).hasSize(1);
          assertThat(tasks.get(0).getName()).isEqualTo("My localized name");
          assertThat(tasks.get(0).getDescription()).isEqualTo("My localized description");
  
          HistoricTaskInstance task = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .singleResult();
          assertThat(task.getName()).isEqualTo("my task");
          assertThat(task.getDescription()).isNull();
  
          task = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .locale("en-GB")
              .singleResult();
          assertThat(task.getName()).isEqualTo("My localized name");
          assertThat(task.getDescription()).isEqualTo("My localized description");
  
          task = historyService
              .createHistoricTaskInstanceQuery()
              .processDefinitionId(processInstance.getProcessDefinitionId())
              .singleResult();
          assertThat(task.getName()).isEqualTo("my task");
          assertThat(task.getDescription()).isNull();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/runtime/concurrentExecution.bpmn20.xml" })
      public void testHistoricVariableInstancesOnParallelExecution() {
          ProcessInstance pi = runtimeService.startProcessInstanceByKey("concurrent", singletonMap("rootValue", "test"));
  
          List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
          for (Task task : tasks) {
              // set token local variable
              log.debug("setting variables on task {}, execution {}", task.getId(), task.getExecutionId());
              runtimeService.setVariableLocal(task.getExecutionId(), "parallelValue1", task.getName());
              runtimeService.setVariableLocal(task.getExecutionId(), "parallelValue2", "test");
              taskService.complete(task.getId(), emptyMap());
          }
          taskService.complete(taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult().getId());
  
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueEquals("rootValue", "test").count()
          ).isEqualTo(1);
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueEquals("parallelValue1", "Receive Payment")
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueEquals("parallelValue1", "Ship Order")
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueEquals("parallelValue2", "test").count()
          ).isEqualTo(1);
      }
  
      /**
       * basically copied from {@link ProcessInstanceQueryTest}
       */
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testQueryStringVariable() {
          ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              singletonMap("stringVar", "abcdef")
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance1.getId()).singleResult().getId()
          );
  
          ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              map("stringVar", "abcdef", "stringVar2", "ghijkl")
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance2.getId()).singleResult().getId()
          );
  
          ProcessInstance processInstance3 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              singletonMap("stringVar", "azerty")
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance3.getId()).singleResult().getId()
          );
  
          // Test EQUAL on single string variable, should result in 2 matches
          HistoricProcessInstanceQuery query = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("stringVar", "abcdef");
          List<HistoricProcessInstance> processInstances = query.list();
          assertThat(processInstances).isNotNull();
          assertThat(processInstances).hasSize(2);
  
          // Test EQUAL on two string variables, should result in single match
          query = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("stringVar", "abcdef")
              .variableValueEquals("stringVar2", "ghijkl");
          HistoricProcessInstance resultInstance = query.singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance2.getId());
  
          // Test NOT_EQUAL, should return only 1 resultInstance
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueNotEquals("stringVar", "abcdef")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          // Test GREATER_THAN, should return only matching 'azerty'
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueGreaterThan("stringVar", "abcdef")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueGreaterThan("stringVar", "z")
              .singleResult();
          assertThat(resultInstance).isNull();
  
          // Test GREATER_THAN_OR_EQUAL, should return 3 results
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueGreaterThanOrEqual("stringVar", "abcdef")
                  .count()
          ).isEqualTo(3);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueGreaterThanOrEqual("stringVar", "z")
                  .count()
          ).isEqualTo(0);
  
          // Test LESS_THAN, should return 2 results
          processInstances = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLessThan("stringVar", "abcdeg")
              .list();
          assertThat(processInstances).hasSize(2);
          List<String> expectedIds = asList(processInstance1.getId(), processInstance2.getId());
          List<String> ids = new ArrayList<String>(
              asList(processInstances.get(0).getId(), processInstances.get(1).getId())
          );
          ids.removeAll(expectedIds);
          assertThat(ids.isEmpty()).isTrue();
  
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLessThan("stringVar", "abcdef").count()
          ).isEqualTo(0);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLessThanOrEqual("stringVar", "z").count()
          ).isEqualTo(3);
  
          // Test LESS_THAN_OR_EQUAL
          processInstances = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLessThanOrEqual("stringVar", "abcdef")
              .list();
          assertThat(processInstances).hasSize(2);
          expectedIds = asList(processInstance1.getId(), processInstance2.getId());
          ids = new ArrayList<String>(asList(processInstances.get(0).getId(), processInstances.get(1).getId()));
          ids.removeAll(expectedIds);
          assertThat(ids.isEmpty()).isTrue();
  
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLessThanOrEqual("stringVar", "z").count()
          ).isEqualTo(3);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLessThanOrEqual("stringVar", "aa").count()
          ).isEqualTo(0);
  
          // Test LIKE
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLike("stringVar", "azert%")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLike("stringVar", "%y")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLike("stringVar", "%zer%")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLike("stringVar", "a%").count()
          ).isEqualTo(3);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLike("stringVar", "%x%").count()
          ).isEqualTo(0);
  
          // Test value-only matching
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("azerty")
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          processInstances = historyService.createHistoricProcessInstanceQuery().variableValueEquals("abcdef").list();
          assertThat(processInstances).hasSize(2);
          expectedIds = asList(processInstance1.getId(), processInstance2.getId());
          ids = new ArrayList<String>(asList(processInstances.get(0).getId(), processInstances.get(1).getId()));
          ids.removeAll(expectedIds);
          assertThat(ids.isEmpty()).isTrue();
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("notmatchinganyvalues")
              .singleResult();
          assertThat(resultInstance).isNull();
  
          historyService.deleteHistoricProcessInstance(processInstance1.getId());
          historyService.deleteHistoricProcessInstance(processInstance2.getId());
          historyService.deleteHistoricProcessInstance(processInstance3.getId());
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testQueryEqualsIgnoreCase() {
          Map<String, Object> vars = new HashMap<String, Object>();
          vars.put("mixed", "AbCdEfG");
          vars.put("lower", "ABCDEFG");
          vars.put("upper", "abcdefg");
          ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey("oneTaskProcess", vars);
  
          HistoricProcessInstance instance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEqualsIgnoreCase("mixed", "abcdefg")
              .singleResult();
          assertThat(instance).isNotNull();
          assertThat(instance.getId()).isEqualTo(processInstance1.getId());
  
          instance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEqualsIgnoreCase("lower", "abcdefg")
              .singleResult();
          assertThat(instance).isNotNull();
          assertThat(instance.getId()).isEqualTo(processInstance1.getId());
  
          instance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEqualsIgnoreCase("upper", "abcdefg")
              .singleResult();
          assertThat(instance).isNotNull();
          assertThat(instance.getId()).isEqualTo(processInstance1.getId());
  
          // Pass in non-lower-case string
          instance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEqualsIgnoreCase("upper", "ABCdefg")
              .singleResult();
          assertThat(instance).isNotNull();
          assertThat(instance.getId()).isEqualTo(processInstance1.getId());
  
          // Pass in null-value, should cause exception
          assertThatExceptionOfType(ActivitiIllegalArgumentException.class)
              .as("Exception expected")
              .isThrownBy(() ->
                  historyService
                      .createHistoricProcessInstanceQuery()
                      .variableValueEqualsIgnoreCase("upper", null)
                      .singleResult()
              )
              .withMessage("value is null");
  
          // Pass in null name, should cause exception
          assertThatExceptionOfType(ActivitiIllegalArgumentException.class)
              .as("Exception expected")
              .isThrownBy(() ->
                  historyService
                      .createHistoricProcessInstanceQuery()
                      .variableValueEqualsIgnoreCase(null, "abcdefg")
                      .singleResult()
              )
              .withMessage("name is null");
      }
  
      /**
       * Only do one second type, as the logic is same as in {@link ProcessInstanceQueryTest} and I do not want to duplicate all test case logic here. Basically copied from
       * {@link ProcessInstanceQueryTest}
       */
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testQueryDateVariable() throws Exception {
          Date date1 = Calendar.getInstance().getTime();
  
          ProcessInstance processInstance1 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              singletonMap("dateVar", date1)
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance1.getId()).singleResult().getId()
          );
  
          Date date2 = Calendar.getInstance().getTime();
          ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              map("dateVar", date1, "dateVar2", date2)
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance2.getId()).singleResult().getId()
          );
  
          Calendar nextYear = Calendar.getInstance();
          nextYear.add(Calendar.YEAR, 1);
          ProcessInstance processInstance3 = runtimeService.startProcessInstanceByKey(
              "oneTaskProcess",
              singletonMap("dateVar", nextYear.getTime())
          );
          taskService.complete(
              taskService.createTaskQuery().processInstanceId(processInstance3.getId()).singleResult().getId()
          );
  
          Calendar nextMonth = Calendar.getInstance();
          nextMonth.add(Calendar.MONTH, 1);
  
          Calendar twoYearsLater = Calendar.getInstance();
          twoYearsLater.add(Calendar.YEAR, 2);
  
          Calendar oneYearAgo = Calendar.getInstance();
          oneYearAgo.add(Calendar.YEAR, -1);
  
          // Query on single short variable, should result in 2 matches
          HistoricProcessInstanceQuery query = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("dateVar", date1);
          List<HistoricProcessInstance> processInstances = query.list();
          assertThat(processInstances).isNotNull();
          assertThat(processInstances).hasSize(2);
  
          // Query on two short variables, should result in single value
          query = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("dateVar", date1)
              .variableValueEquals("dateVar2", date2);
          HistoricProcessInstance resultInstance = query.singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance2.getId());
  
          // Query with unexisting variable value
          Date unexistingDate = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss").parse("01/01/1989 12:00:00");
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals("dateVar", unexistingDate)
              .singleResult();
          assertThat(resultInstance).isNull();
  
          // Test NOT_EQUALS
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueNotEquals("dateVar", date1)
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          // Test GREATER_THAN
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueGreaterThan("dateVar", nextMonth.getTime())
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueGreaterThan("dateVar", nextYear.getTime())
                  .count()
          ).isEqualTo(0);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueGreaterThan("dateVar", oneYearAgo.getTime())
                  .count()
          ).isEqualTo(3);
  
          // Test GREATER_THAN_OR_EQUAL
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueGreaterThanOrEqual("dateVar", nextMonth.getTime())
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueGreaterThanOrEqual("dateVar", nextYear.getTime())
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueGreaterThanOrEqual("dateVar", oneYearAgo.getTime())
                  .count()
          ).isEqualTo(3);
  
          // Test LESS_THAN
          processInstances = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLessThan("dateVar", nextYear.getTime())
              .list();
          assertThat(processInstances).hasSize(2);
  
          List<String> expectedIds = asList(processInstance1.getId(), processInstance2.getId());
          List<String> ids = new ArrayList<String>(
              asList(processInstances.get(0).getId(), processInstances.get(1).getId())
          );
          ids.removeAll(expectedIds);
          assertThat(ids.isEmpty()).isTrue();
  
          assertThat(
              historyService.createHistoricProcessInstanceQuery().variableValueLessThan("dateVar", date1).count()
          ).isEqualTo(0);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueLessThan("dateVar", twoYearsLater.getTime())
                  .count()
          ).isEqualTo(3);
  
          // Test LESS_THAN_OR_EQUAL
          processInstances = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueLessThanOrEqual("dateVar", nextYear.getTime())
              .list();
          assertThat(processInstances).hasSize(3);
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .variableValueLessThanOrEqual("dateVar", oneYearAgo.getTime())
                  .count()
          ).isEqualTo(0);
  
          // Test value-only matching
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals(nextYear.getTime())
              .singleResult();
          assertThat(resultInstance).isNotNull();
          assertThat(resultInstance.getId()).isEqualTo(processInstance3.getId());
  
          processInstances = historyService.createHistoricProcessInstanceQuery().variableValueEquals(date1).list();
          assertThat(processInstances).hasSize(2);
          expectedIds = asList(processInstance1.getId(), processInstance2.getId());
          ids = new ArrayList<String>(asList(processInstances.get(0).getId(), processInstances.get(1).getId()));
          ids.removeAll(expectedIds);
          assertThat(ids.isEmpty()).isTrue();
  
          resultInstance = historyService
              .createHistoricProcessInstanceQuery()
              .variableValueEquals(twoYearsLater.getTime())
              .singleResult();
          assertThat(resultInstance).isNull();
  
          historyService.deleteHistoricProcessInstance(processInstance1.getId());
          historyService.deleteHistoricProcessInstance(processInstance2.getId());
          historyService.deleteHistoricProcessInstance(processInstance3.getId());
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testNativeHistoricProcessInstanceTest() {
          // just test that the query will be constructed and executed, details
          // are tested in the TaskQueryTest
          runtimeService.startProcessInstanceByKey("oneTaskProcess");
          assertThat(
              historyService
                  .createNativeHistoricProcessInstanceQuery()
                  .sql("SELECT count(*) FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService
                  .createNativeHistoricProcessInstanceQuery()
                  .sql("SELECT * FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .list()
          ).hasSize(1);
          // assertThat(1,
          // historyService.createNativeHistoricProcessInstanceQuery().sql("SELECT * FROM "
          // +
          // managementService.getTableName(HistoricProcessInstance.class)).listPage(0,
          // 1).size());
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testNativeHistoricTaskInstanceTest() {
          runtimeService.startProcessInstanceByKey("oneTaskProcess");
          assertThat(
              historyService
                  .createNativeHistoricTaskInstanceQuery()
                  .sql("SELECT count(*) FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService
                  .createNativeHistoricTaskInstanceQuery()
                  .sql("SELECT * FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .list()
          ).hasSize(1);
          assertThat(
              historyService
                  .createNativeHistoricTaskInstanceQuery()
                  .sql("SELECT * FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .listPage(0, 1)
          ).hasSize(1);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testNativeHistoricActivityInstanceTest() {
          runtimeService.startProcessInstanceByKey("oneTaskProcess");
          assertThat(
              historyService
                  .createNativeHistoricActivityInstanceQuery()
                  .sql("SELECT count(*) FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService
                  .createNativeHistoricActivityInstanceQuery()
                  .sql("SELECT * FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .list()
          ).hasSize(1);
          assertThat(
              historyService
                  .createNativeHistoricActivityInstanceQuery()
                  .sql("SELECT * FROM " + managementService.getTableName(HistoricProcessInstance.class))
                  .listPage(0, 1)
          ).hasSize(1);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceQueryByProcessDefinitionName() {
          String processDefinitionKey = "oneTaskProcess";
          String processDefinitionName = "The One Task Process";
          runtimeService.startProcessInstanceByKey(processDefinitionKey);
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .processDefinitionName(processDefinitionName)
                  .list()
                  .get(0)
                  .getProcessDefinitionName()
          ).isEqualTo(processDefinitionName);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().processDefinitionName(processDefinitionName).list()
          ).hasSize(1);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().processDefinitionName(processDefinitionName).count()
          ).isEqualTo(1);
          assertThat(historyService.createHistoricProcessInstanceQuery().processDefinitionName("invalid").list()).hasSize(
              0
          );
          assertThat(
              historyService.createHistoricProcessInstanceQuery().processDefinitionName("invalid").count()
          ).isEqualTo(0);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .or()
                  .processDefinitionName(processDefinitionName)
                  .processDefinitionId("invalid")
                  .endOr()
                  .list()
                  .get(0)
                  .getProcessDefinitionName()
          ).isEqualTo(processDefinitionName);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .or()
                  .processDefinitionName(processDefinitionName)
                  .processDefinitionId("invalid")
                  .endOr()
                  .list()
          ).hasSize(1);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .or()
                  .processDefinitionName(processDefinitionName)
                  .processDefinitionId("invalid")
                  .endOr()
                  .count()
          ).isEqualTo(1);
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
      public void testHistoricProcessInstanceQueryByProcessDefinitionCategory() {
          String processDefinitionKey = "oneTaskProcess";
          String processDefinitionCategory = "ExamplesCategory";
          runtimeService.startProcessInstanceByKey(processDefinitionKey);
  
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .processDefinitionCategory(processDefinitionCategory)
                  .list()
          ).hasSize(1);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .processDefinitionCategory(processDefinitionCategory)
                  .count()
          ).isEqualTo(1);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().processDefinitionCategory("invalid").list()
          ).hasSize(0);
          assertThat(
              historyService.createHistoricProcessInstanceQuery().processDefinitionCategory("invalid").count()
          ).isEqualTo(0);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .or()
                  .processDefinitionCategory(processDefinitionCategory)
                  .processDefinitionId("invalid")
                  .endOr()
                  .list()
          ).hasSize(1);
          assertThat(
              historyService
                  .createHistoricProcessInstanceQuery()
                  .or()
                  .processDefinitionCategory(processDefinitionCategory)
                  .processDefinitionId("invalid")
                  .endOr()
                  .count()
          ).isEqualTo(1);
      }
  }
  