@Test
  public void testSessionPerProcessInstance() throws Exception {
    RuntimeEnvironment environment =
        RuntimeEnvironmentBuilder.Factory.get()
            .newDefaultBuilder()
            .entityManagerFactory(emf)
            .userGroupCallback(userGroupCallback)
            .addAsset(
                ResourceFactory.newClassPathResource(
                    "org/jbpm/test/functional/timer/IntermediateCatchEventTimerCycleWithHT.bpmn2"),
                ResourceType.BPMN2)
            .schedulerService(globalScheduler)
            .get();

    long startTimeStamp = System.currentTimeMillis();
    long maxEndTime = startTimeStamp + maxWaitTime;

    manager = RuntimeManagerFactory.Factory.get().newPerProcessInstanceRuntimeManager(environment);
    // prepare task service with users and groups
    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    TaskService taskService = engine.getTaskService();

    Group grouphr = TaskModelProvider.getFactory().newGroup();
    ((InternalOrganizationalEntity) grouphr).setId("HR");

    User mary = TaskModelProvider.getFactory().newUser();
    ((InternalOrganizationalEntity) mary).setId("mary");
    User john = TaskModelProvider.getFactory().newUser();
    ((InternalOrganizationalEntity) john).setId("john");

    ((InternalTaskService) taskService).addGroup(grouphr);
    ((InternalTaskService) taskService).addUser(mary);
    ((InternalTaskService) taskService).addUser(john);

    manager.disposeRuntimeEngine(engine);

    completedStart = 0;
    for (int i = 0; i < nbThreadsProcess; i++) {
      new StartProcessPerProcessInstanceRunnable(manager, i).run();
    }
    completedTask = 0;
    for (int i = 0; i < nbThreadsTask; i++) {
      new Thread(new CompleteTaskPerProcessInstanceRunnable(manager, i)).start();
    }
    while (completedStart < nbThreadsProcess || completedTask < nbThreadsTask) {
      Thread.sleep(100);
      if (System.currentTimeMillis() > maxEndTime) {
        fail("Failure, did not finish in time most likely hanging");
      }
    }
    // make sure all process instance were completed
    engine = manager.getRuntimeEngine(EmptyContext.get());
    AuditService logService = engine.getAuditService();
    // active
    List<? extends ProcessInstanceLog> logs =
        logService.findActiveProcessInstances("IntermediateCatchEvent");
    assertNotNull(logs);
    for (ProcessInstanceLog log : logs) {
      logger.debug("Left over {}", log.getProcessInstanceId());
    }
    assertEquals(0, logs.size());

    // completed
    logs = logService.findProcessInstances("IntermediateCatchEvent");
    assertNotNull(logs);
    assertEquals(nbThreadsProcess, logs.size());
    manager.disposeRuntimeEngine(engine);

    logger.debug("Done");
  }
 @Override
 public void addGroup(Group group) {
   synchronized (ksession) {
     taskService.addGroup(group);
   }
 }