text:
/* 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.flowable.cmmn.test.runtime;

import static org.assertj.core.api.Assertions.assertThat;
import static org.flowable.cmmn.api.runtime.PlanItemInstanceState.ACTIVE;
import static org.flowable.cmmn.api.runtime.PlanItemInstanceState.AVAILABLE;

import java.util.List;

import org.flowable.cmmn.api.history.HistoricPlanItemInstance;
import org.flowable.cmmn.api.repository.CaseDefinition;
import org.flowable.cmmn.api.runtime.CaseInstance;
import org.flowable.cmmn.api.runtime.PlanItemInstance;
import org.flowable.cmmn.engine.CmmnEngineConfiguration;
import org.flowable.cmmn.engine.impl.deployer.CmmnDeploymentManager;
import org.flowable.cmmn.engine.impl.persistence.entity.deploy.CaseDefinitionCacheEntry;
import org.flowable.cmmn.engine.test.CmmnDeployment;
import org.flowable.cmmn.engine.test.FlowableCmmnTestCase;
import org.flowable.cmmn.engine.test.impl.CmmnTestRunner;
import org.flowable.cmmn.model.Case;
import org.flowable.cmmn.model.CaseElement;
import org.flowable.cmmn.model.CmmnModel;
import org.flowable.task.api.Task;
import org.junit.Test;

/**
 * Testing dynamic injection of a new plan item at runtime.
 *
 * @author Micha Kiener
 */
public class PlanItemInjectionTest extends FlowableCmmnTestCase {

    protected CmmnDeploymentManager deploymentManager;

    @Test
    @CmmnDeployment
    public void testDynamicPlanItemInjection() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        // inject new plan item into Stage A
        PlanItemInstance injectedTask = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Task A")
                .caseDefinitionId(caseInstance.getCaseDefinitionId())
                .elementId(getPlanItemInstanceByName(planItemInstances, "Task A", ACTIVE).getElementId())
                .createInStage(getPlanItemInstanceIdByNameAndState(planItemInstances, "Stage A", ACTIVE));

        assertThat(injectedTask).isNotNull();
        assertThat(injectedTask.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be the same as the running one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(caseInstance.getCaseDefinitionId())
                .list();

        assertThat(derivedPlanItems).isNotNull();
        assertThat(derivedPlanItems)
                .extracting(PlanItemInstance::getName)
                .containsExactly("Injected Task A");

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn" })
    public void testDynamicPlanItemInjectionInCase() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        // inject new plan item into case instance
        PlanItemInstance injectedTask = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Task A")
                .caseDefinitionId(caseInstance.getCaseDefinitionId())
                .elementId(getPlanItemInstanceByName(planItemInstances, "Task A", ACTIVE).getElementId())
                .createInCase(caseInstance.getId());

        assertThat(injectedTask).isNotNull();
        assertThat(injectedTask.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be the same as the running one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(caseInstance.getCaseDefinitionId())
                .list();

        assertThat(derivedPlanItems).isNotNull();
        assertThat(derivedPlanItems)
                .extracting(PlanItemInstance::getName)
                .containsExactly("Injected Task A");

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(1);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));

        assertThat(cmmnRuntimeService.createPlanItemInstanceQuery().count()).isZero();
        assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero();
        assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().finished().count()).isEqualTo(1);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(caseInstance.getCaseDefinitionId())
                .list();

        assertThat(historicPlanItemInstances).isNotNull();
        assertThat(historicPlanItemInstances)
                .extracting(HistoricPlanItemInstance::getName)
                .containsExactly("Injected Task A");
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicPlanItemInjectionFromTemplate() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateTask = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem1");

        // inject new plan item into Stage A
        PlanItemInstance injectedTask = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Task A")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateTask.getId())
                .createInStage(getPlanItemInstanceIdByNameAndState(planItemInstances, "Stage A", ACTIVE));

        assertThat(injectedTask).isNotNull();
        assertThat(injectedTask.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).isNotNull();
        assertThat(derivedPlanItems)
                .extracting(PlanItemInstance::getName)
                .containsExactly("Injected Task A");

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).isNotNull();
        assertThat(historicPlanItemInstances)
                .extracting(HistoricPlanItemInstance::getName)
                .containsExactly("Injected Task A");
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicPlanItemInjectionFromTemplateInCase() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateTask = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem1");

        // inject new plan item into case instance
        PlanItemInstance injectedTask = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Task A")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateTask.getId())
                .createInCase(caseInstance.getId());

        assertThat(injectedTask).isNotNull();
        assertThat(injectedTask.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).isNotNull();
        assertThat(derivedPlanItems)
                .extracting(PlanItemInstance::getName)
                .containsExactly("Injected Task A");

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(1);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));

        assertThat(cmmnRuntimeService.createPlanItemInstanceQuery().count()).isZero();
        assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero();
        assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().finished().count()).isEqualTo(1);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).isNotNull();
        assertThat(historicPlanItemInstances)
                .extracting(HistoricPlanItemInstance::getName)
                .containsExactly("Injected Task A");
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionFromTemplate() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem5");

        // inject new plan item into Stage A
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInStage(getPlanItemInstanceIdByNameAndState(planItemInstances, "Stage A", ACTIVE));

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", AVAILABLE);
        assertThat(getPlanItemInstanceByName(planItemInstances, "Injected Stage", ACTIVE).isStage()).isTrue();

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", AVAILABLE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).hasSize(3);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionFromTemplateInCase() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem5");

        // inject new plan item into running case
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInCase(caseInstance.getId());

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", AVAILABLE);
        assertThat(getPlanItemInstanceByName(planItemInstances, "Injected Stage", ACTIVE).isStage()).isTrue();

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(2);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Injected Task A");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", AVAILABLE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Task B", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Injected Task B", ACTIVE));

        assertThat(cmmnRuntimeService.createPlanItemInstanceQuery().count()).isZero();
        assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero();
        assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().finished().count()).isEqualTo(1);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).hasSize(3);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionWithSentryFromTemplate() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        // already make sure the condition for the injected stage entry sentry will be satisfied when the stage will be injected
        cmmnRuntimeService.setVariable(caseInstance.getId(), "injectedStageEnabled", true);

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem8");

        // inject new plan item into Stage A
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInStage(getPlanItemInstanceIdByNameAndState(planItemInstances, "Stage A", ACTIVE));

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(3);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Task X");
        assertSingleTaskExists(tasks, "Task Y");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task X", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task Y", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionWithSentryFromTemplateInCase() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        // already make sure the condition for the injected stage entry sentry will be satisfied when the stage will be injected
        cmmnRuntimeService.setVariable(caseInstance.getId(), "injectedStageEnabled", true);

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem8");

        // inject new plan item into running case
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInCase(caseInstance.getId());

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(ACTIVE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(3);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Task X");
        assertSingleTaskExists(tasks, "Task Y");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task X", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task Y", ACTIVE));

        assertThat(cmmnRuntimeService.createPlanItemInstanceQuery().count()).isZero();
        assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero();
        assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().finished().count()).isEqualTo(1);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).hasSize(3);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionWithSentryConditionFromTemplate() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem8");

        // inject new plan item into Stage A
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInStage(getPlanItemInstanceIdByNameAndState(planItemInstances, "Stage A", ACTIVE));

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(AVAILABLE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", AVAILABLE);
        assertThat(getPlanItemInstanceByName(planItemInstances, "Injected Stage", AVAILABLE).isStage()).isTrue();

        cmmnRuntimeService.setVariable(caseInstance.getId(), "injectedStageEnabled", true);
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(3);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Task X");
        assertSingleTaskExists(tasks, "Task Y");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task X", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task Y", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
    }

    @Test
    @CmmnDeployment(resources = { "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.testDynamicPlanItemInjection.cmmn",
            "org/flowable/cmmn/test/runtime/PlanItemInjectionTest.dynamicPlanItemTemplates.cmmn" })
    public void testDynamicStagePlanItemInjectionWithSentryConditionFromTemplateInCase() {
        CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("dynamicPlanItemInjection").start();

        List<PlanItemInstance> planItemInstances = getPlanItemInstances(caseInstance.getId());

        assertThat(planItemInstances).hasSize(3);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);

        CaseDefinition dynamicPlanItemCase = cmmnRepositoryService.createCaseDefinitionQuery()
                .caseDefinitionKey("dynamicPlanItemCase")
                .latestVersion()
                .singleResult();

        CaseElement templateStage = getCase(dynamicPlanItemCase.getId()).getAllCaseElements().get("planItem8");

        // inject new plan item into running case
        PlanItemInstance injectedStage = dynamicCmmnService
                .createInjectedPlanItemInstanceBuilder()
                .name("Injected Stage")
                .caseDefinitionId(dynamicPlanItemCase.getId())
                .elementId(templateStage.getId())
                .createInCase(caseInstance.getId());

        assertThat(injectedStage).isNotNull();
        assertThat(injectedStage.getState()).isEqualTo(AVAILABLE);

        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", AVAILABLE);
        assertThat(getPlanItemInstanceByName(planItemInstances, "Injected Stage", AVAILABLE).isStage()).isTrue();

        cmmnRuntimeService.setVariable(caseInstance.getId(), "injectedStageEnabled", true);
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(6);
        assertPlanItemInstanceState(planItemInstances, "Stage A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Stage B", AVAILABLE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task A", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        List<Task> tasks = cmmnTaskService.createTaskQuery()
                .caseInstanceId(caseInstance.getId())
                .active()
                .list();

        assertThat(tasks).hasSize(3);
        assertSingleTaskExists(tasks, "Task A");
        assertSingleTaskExists(tasks, "Task X");
        assertSingleTaskExists(tasks, "Task Y");

        // test the query for the derived case definition (in this unit test, it will be a different one from the running case one)
        List<PlanItemInstance> derivedPlanItems = cmmnRuntimeService.createPlanItemInstanceQuery()
                .derivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(derivedPlanItems).hasSize(3);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task A", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(5);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task X", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task X", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(4);
        assertPlanItemInstanceState(planItemInstances, "Stage B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task B", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task B", ACTIVE));
        planItemInstances = getPlanItemInstances(caseInstance.getId());
        assertThat(planItemInstances).hasSize(2);
        assertPlanItemInstanceState(planItemInstances, "Injected Stage", ACTIVE);
        assertPlanItemInstanceState(planItemInstances, "Task Y", ACTIVE);

        cmmnRuntimeService.triggerPlanItemInstance(getPlanItemInstanceIdByNameAndState(planItemInstances, "Task Y", ACTIVE));

        assertThat(cmmnRuntimeService.createPlanItemInstanceQuery().count()).isZero();
        assertThat(cmmnRuntimeService.createCaseInstanceQuery().count()).isZero();
        assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().finished().count()).isEqualTo(1);

        List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
                .planItemInstanceDerivedCaseDefinitionId(dynamicPlanItemCase.getId())
                .list();

        assertThat(historicPlanItemInstances).hasSize(3);
    }

    @Override
    public void setupServices() {
        super.setupServices();
        CmmnEngineConfiguration cmmnEngineConfiguration = CmmnTestRunner.getCmmnEngineConfiguration();
        this.deploymentManager = cmmnEngineConfiguration.getDeploymentManager();
    }

    protected CmmnModel getCmmnModel(String caseDefinitionId) {
        CaseDefinitionCacheEntry cacheEntry = deploymentManager.getCaseDefinitionCache().get(caseDefinitionId);
        if (cacheEntry != null) {
            return cacheEntry.getCmmnModel();
        }
        deploymentManager.findDeployedCaseDefinitionById(caseDefinitionId);
        return deploymentManager.getCaseDefinitionCache().get(caseDefinitionId).getCmmnModel();
    }

    protected Case getCase(String caseDefinitionId) {
        return getCmmnModel(caseDefinitionId).getPrimaryCase();
    }
}


text:
require 'test_helper'

class HistoriesControllerTest < ActionController::TestCase
  setup do
    @history = histories(:one)
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:histories)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create history" do
    assert_difference('History.count') do
      post :create, history: { end_date: @history.end_date, start_date: @history.start_date }
    end

    assert_redirected_to history_path(assigns(:history))
  end

  test "should show history" do
    get :show, id: @history
    assert_response :success
  end

  test "should get edit" do
    get :edit, id: @history
    assert_response :success
  end

  test "should update history" do
    patch :update, id: @history, history: { end_date: @history.end_date, start_date: @history.start_date }
    assert_redirected_to history_path(assigns(:history))
  end

  test "should destroy history" do
    assert_difference('History.count', -1) do
      delete :destroy, id: @history
    end

    assert_redirected_to histories_path
  end
end

redpajama_set_name: RedPajamaGithub


text:
set -e

source "./scripts/env.sh"

./bin/server


text:
<?php

namespace PH7;

use PH7\Framework\Http\Http;

class HttpController extends Controller
{
    const HTTP_BAD_REQUEST_CODE = 400;
    const HTTP_UNAUTHORIZED_CODE = 401;
    const HTTP_PAYMENT_REQUIRED_CODE = 402;
    const HTTP_FORBIDDEN_CODE = 403;
    const HTTP_NOT_FOUND_CODE = 404;
    const HTTP_METHOD_NOT_ALLOWED_CODE = 405;
    const HTTP_INTERNAL_SERVER_ERROR_CODE = 500;
    const HTTP_UNIMPLEMENTED_CODE = 501;
    const HTTP_BAD_GATEWAY_CODE = 502;
    const HTTP_GATEWAY_TIMEOUT_CODE = 504;
    const HTTP_VERSION_UNSUPPORTED_CODE = 505;

    /** @var string */
    private $sTitle;

    public function index()
    {
        switch ($this->httpRequest->get('code', 'int')) {
            case self::HTTP_BAD_REQUEST_CODE:
                Http::setHeadersByCode(self::HTTP_BAD_REQUEST_CODE);
                $this->sTitle = t('Bad Request');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The request cannot be fulfilled due to bad syntax.');
                break;

            case self::HTTP_UNAUTHORIZED_CODE:
                Http::setHeadersByCode(self::HTTP_UNAUTHORIZED_CODE);
                $this->sTitle = t('Unauthorized');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('Your IP address or the username/password you entered were not correct. Your request was denied as you have no permission to access the data.');
                break;

            case self::HTTP_PAYMENT_REQUIRED_CODE:
                Http::setHeadersByCode(self::HTTP_PAYMENT_REQUIRED_CODE);
                $this->sTitle = t('Payment Required');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The data is not accessible at the time. The owner of the space has not yet payed their service provider.');
                break;

            case self::HTTP_FORBIDDEN_CODE:
                Http::setHeadersByCode(self::HTTP_FORBIDDEN_CODE);
                $this->sTitle = t('Forbidden');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t("You don't have permissions to access this page at the moment.");
                break;

            case self::HTTP_METHOD_NOT_ALLOWED_CODE:
                Http::setHeadersByCode(self::HTTP_METHOD_NOT_ALLOWED_CODE);
                $this->sTitle = t('Method Not Allowed');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('A request was made of a resource using a request method not supported by that resource;[2] for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.');
                break;

            case self::HTTP_INTERNAL_SERVER_ERROR_CODE:
                Http::setHeadersByCode(self::HTTP_INTERNAL_SERVER_ERROR_CODE);
                $this->sTitle = t('Internal Server Error');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The server encountered an error. This is most often caused by a scripting problem, a failed database access attempt, or other similar reasons.
Please come back later!');
                break;

            case self::HTTP_UNIMPLEMENTED_CODE:
                Http::setHeadersByCode(self::HTTP_UNIMPLEMENTED_CODE);
                $this->sTitle = t('Not Implemented');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The method you are using to access the document can not be performed by the server.
Possible methods include:') .
                    '
' . 'CONNECT

               DELETE

               DELETE

               GET

               HEAD

               OPTIONS

               POST

               PUT

               TRACE';
                break;

            case self::HTTP_BAD_GATEWAY_CODE:
                Http::setHeadersByCode(self::HTTP_BAD_GATEWAY_CODE);
                $this->sTitle = t('Bad Gateway');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The server was acting as a gateway or proxy and received an invalid response from the upstream server.');
                break;

            case self::HTTP_GATEWAY_TIMEOUT_CODE:
                Http::setHeadersByCode(self::HTTP_GATEWAY_TIMEOUT_CODE);
                $this->sTitle = t('Gateway Timeout');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t("Most likely the client has lost connectivity (disconnected from the internet) or the client's host is having technical difficulties.
 This could also meanthat a server that allows access to the requested server is down, having bandwidth/load issues, or otherwise unavailable.");
                break;

            case self::HTTP_VERSION_UNSUPPORTED_CODE:
                Http::setHeadersByCode(self::HTTP_VERSION_UNSUPPORTED_CODE);
                $this->sTitle = t('HTTP Version Not Supported');
                $this->view->page_title = $this->sTitle;
                $this->view->h1_title = $this->sTitle;
                $this->view->error_desc = t('The server does not support the HTTP protocol version used in the request.');
                break;

            default:
                // Add an image for 404 not found page, so we need to include a stylesheet file
                $this->design->addCss(
                    PH7_LAYOUT . PH7_SYS . PH7_MOD . $this->registry->module . PH7_SH . PH7_TPL . PH7_TPL_MOD_NAME . PH7_SH . PH7_CSS,
                    'style.css'
                );

                $this->displayPageNotFound();
        }

        $this->output();
    }
}


text:
<?php

namespace PandawanTechnology\Neo4jDataFixtures;

use PandawanTechnology\Neo4jDataFixtures\Exception\CircularReferenceException;

class Loader
{
    /**
     * @var Neo4jFixtureInterface[]
     */
    private $fixtures = [];

    /**
     * @var Neo4jFixtureInterface[]
     */
    private $orderedFixtures = [];

    /**
     * @var bool
     */
    private $orderFixturesByDependencies = false;

    /**
     * @var string
     */
    private $fileExtension = '.php';

    /**
     * Find fixtures classes in a given directory and load them.
     *
     * @param string $dir Directory to find fixture classes in.
     *
     * @return array $fixtures Array of loaded fixture object instances.
     */
    public function loadFromDirectory($dir)
    {
        if (!is_dir($dir)) {
            throw new \InvalidArgumentException(sprintf('"%s" does not exist', $dir));
        }

        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
            \RecursiveIteratorIterator::LEAVES_ONLY
        );

        return $this->loadFromIterator($iterator);
    }

    /**
     * Find fixtures classes in a given file and load them.
     *
     * @param string $fileName File to find fixture classes in.
     *
     * @return array $fixtures Array of loaded fixture object instances.
     */
    public function loadFromFile($fileName)
    {
        if (!is_readable($fileName)) {
            throw new \InvalidArgumentException(sprintf('"%s" does not exist or is not readable', $fileName));
        }

        $iterator = new \ArrayIterator(array(new \SplFileInfo($fileName)));

        return $this->loadFromIterator($iterator);
    }

    /**
     * Has fixture?
     *
     * @param Neo4jFixtureInterface $fixture
     *
     * @return bool
     */
    public function hasFixture($fixture)
    {
        return isset($this->fixtures[get_class($fixture)]);
    }

    /**
     * Add a fixture object instance to the loader.
     *
     * @param Neo4jFixtureInterface $fixture
     */
    public function addFixture(Neo4jFixtureInterface $fixture)
    {
        $fixtureClass = get_class($fixture);

        if (isset($this->fixtures[$fixtureClass])) {
            return;
        }

        $this->fixtures[$fixtureClass] = $fixture;

        if ($fixture instanceof Neo4jDependentFixtureInterface) {
            $this->orderFixturesByDependencies = true;

            foreach ($fixture->getDependencies() as $class) {
                if (class_exists($class)) {
                    $this->addFixture(new $class());
                }
            }
        }
    }

    /**
     * Returns the array of data fixtures to execute.
     *
     * @return array $fixtures
     */
    public function getFixtures()
    {
        $this->orderedFixtures = [];

        if ($this->orderFixturesByDependencies) {
            $this->orderFixturesByDependencies();
        }

        if (!$this->orderFixturesByDependencies) {
            $this->orderedFixtures = $this->fixtures;
        }

        return $this->orderedFixtures;
    }

    /**
     * Check if a given fixture is transient and should not be considered a data fixtures
     * class.
     *
     * @param string $className
     *
     * @return bool
     */
    public function isTransient($className)
    {
        $rc = new \ReflectionClass($className);

        if ($rc->isAbstract()) {
            return true;
        }

        $interfaces = class_implements($className);

        return !in_array('PandawanTechnology\Neo4jDataFixtures\Neo4jFixtureInterface', $interfaces);
    }

    /**
     * Orders fixtures by dependencies.
     */
    private function orderFixturesByDependencies()
    {
        $sequenceForClasses = [];

        // If fixtures were already ordered by number then we need
        // to remove classes which are not instances of OrderedFixtureInterface
        // in case fixtures implementing DependentFixtureInterface exist.
        // This is because, in that case, the method orderFixturesByDependencies
        // will handle all fixtures which are not instances of
        // OrderedFixtureInterface

        // First we determine which classes has dependencies and which don't
        foreach ($this->fixtures as $fixture) {
            $fixtureClass = get_class($fixture);

            if ($fixture instanceof Neo4jDependentFixtureInterface) {
                $dependenciesClasses = $fixture->getDependencies();

                $this->validateDependencies($dependenciesClasses);
                if (!is_array($dependenciesClasses) || empty($dependenciesClasses)) {
                    throw new \InvalidArgumentException(sprintf('Method "%s" in class "%s" must return an array of classes which are dependencies for the fixture, and it must be NOT empty.', 'getDependencies', $fixtureClass));
                }

                if (in_array($fixtureClass, $dependenciesClasses)) {
                    throw new \InvalidArgumentException(sprintf('Class "%s" can\'t have itself as a dependency', $fixtureClass));
                }

                // We mark this class as unsequenced
                $sequenceForClasses[$fixtureClass] = -1;
            } else {
                // This class has no dependencies, so we assign 0
                $sequenceForClasses[$fixtureClass] = 0;
            }
        }
        // Now we order fixtures by sequence
        $sequence = 1;
        $lastCount = -1;

        while (($count = count($unsequencedClasses = $this->getUnsequencedClasses($sequenceForClasses))) > 0 && $count !== $lastCount) {
            foreach ($unsequencedClasses as $key => $class) {
                /** @var Neo4jDependentFixtureInterface $fixture */
                $fixture = $this->fixtures[$class];
                $dependencies = $fixture->getDependencies();
                $unsequencedDependencies = $this->getUnsequencedClasses($sequenceForClasses, $dependencies);

                if (count($unsequencedDependencies) === 0) {
                    $sequenceForClasses[$class] = $sequence++;
                }
            }

            $lastCount = $count;
        }
        $orderedFixtures = array();

        // If there're fixtures unsequenced left and they couldn't be sequenced,
        // it means we have a circular reference
        if ($count > 0) {
            $msg = 'Classes "%s" have produced a CircularReferenceException. ';
            $msg .= 'An example of this problem would be the following: Class C has class B as its dependency. ';
            $msg .= 'Then, class B has class A has its dependency. Finally, class A has class C as its dependency. ';
            $msg .= 'This case would produce a CircularReferenceException.';

            throw new CircularReferenceException(sprintf($msg, implode(',', $unsequencedClasses)));
        }

        // We order the classes by sequence
        asort($sequenceForClasses);

        foreach ($sequenceForClasses as $class => $sequence) {
            // If fixtures were ordered
            $orderedFixtures[] = $this->fixtures[$class];
        }

        $this->orderedFixtures = array_merge($this->orderedFixtures, $orderedFixtures);
    }

    /**
     * @param array $dependenciesClasses
     *
     * @return bool
     */
    private function validateDependencies($dependenciesClasses)
    {
        $loadedFixtureClasses = array_keys($this->fixtures);

        foreach ($dependenciesClasses as $class) {
            if (!in_array($class, $loadedFixtureClasses)) {
                throw new \RuntimeException(sprintf('Fixture "%s" was declared as a dependency, but it should be added in fixture loader first.', $class));
            }
        }

        return true;
    }

    /**
     * @param array      $sequences
     * @param null|array $classes
     *
     * @return array
     */
    private function getUnsequencedClasses(array $sequences, $classes = null)
    {
        $unsequencedClasses = array();

        if (is_null($classes)) {
            $classes = array_keys($sequences);
        }

        foreach ($classes as $class) {
            if ($sequences[$class] === -1) {
                $unsequencedClasses[] = $class;
            }
        }

        return $unsequencedClasses;
    }

    /**
     * Load fixtures from files contained in iterator.
     *
     * @param \Iterator $iterator Iterator over files from which fixtures should be loaded.
     *
     * @return Neo4jFixtureInterface[] $fixtures Array of loaded fixture object instances.
     */
    private function loadFromIterator(\Iterator $iterator)
    {
        $includedFiles = [];

        foreach ($iterator as $file) {
            if (($fileName = $file->getBasename($this->fileExtension)) == $file->getBasename()) {
                continue;
            }

            $sourceFile = realpath($file->getPathName());
            require_once $sourceFile;
            $includedFiles[] = $sourceFile;
        }

        $fixtures = [];
        $declared = get_declared_classes();

        foreach ($declared as $className) {
            $reflClass = new \ReflectionClass($className);
            $sourceFile = $reflClass->getFileName();

            if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) {
                $fixture = new $className();
                $fixtures[] = $fixture;
                $this->addFixture($fixture);
            }
        }

        return $fixtures;
    }
}


text:
//-----------------------------------------------------------------------------
// Copyright 2016 seblemaguer
// Author: https://github.com/seblemaguer
// Last update: 2017/02/01
//
// Summary:
// The example analyzes a .wav file and outputs three files in each parameter.
// Files are used to synthesize speech by "synthesis.cpp".
//
// How to use:
// The format is shown in the line 253.
//-----------------------------------------------------------------------------
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <iostream>
#include <fstream>

#if (defined (__WIN32__) || defined (_WIN32)) && !defined (__MINGW32__)
#include <conio.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
#pragma warning(disable : 4996)
#endif
#if (defined (__linux__) || defined(__CYGWIN__) || defined(__APPLE__))
#include <stdint.h>
#include <sys/time.h>
#endif

// For .wav input/output functions.
#include "audioio.h"

// WORLD core functions.
// Note: win.sln uses an option in Additional Include Directories.
// To compile the program, the option "-I $(SolutionDir)..\src" was set.
#include "world/d4c.h"
#include "world/dio.h"
#include "world/matlabfunctions.h"
#include "world/cheaptrick.h"
#include "world/stonemask.h"

#if (defined (__linux__) || defined(__CYGWIN__) || defined(__APPLE__))
// Linux porting section: implement timeGetTime() by gettimeofday(),
#ifndef DWORD
#define DWORD uint32_t
#endif
DWORD timeGetTime() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    DWORD ret = static_cast<DWORD>(tv.tv_usec / 1000 + tv.tv_sec * 1000);
    return ret;
}
#endif

//-----------------------------------------------------------------------------
// struct for WORLD
// This struct is an option.
// Users are NOT forced to use this struct.
//-----------------------------------------------------------------------------
typedef struct {
    double frame_period;
    int fs;

    double *f0;
    double *time_axis;
    int f0_length;

    double **spectrogram;
    double **aperiodicity;
    int fft_size;
} WorldParameters;

namespace {

    /**
     *  Displaying wav file information
     *
     *   @param fs : the sampling frequence
     *   @param nbit : the number of bits to code the signal
     *   @param x_length : the number of samples
     */
    void DisplayInformation(int fs, int nbit, int x_length)
    {
        std::cout << "File information" << std::endl;
        std::cout << "Sampling : " << fs << " Hz " << nbit << " Bit" << std::endl;
        std::cout << "Length " << x_length << " [sample]" << std::endl;
        std::cout << "Length " << static_cast<double>(x_length) / fs <<  "[sec]" << std::endl;
    }

    /**
     *  F0 estimation function
     *
     *    @param x : the signal samples
     *    @param x_length : the number of samples
     *    @param world_parameters : the world structure which is going to contains the F0 values (double format)
     *     in the f0 structure field
     */
    void F0Estimation(double *x, int x_length, WorldParameters *world_parameters)
    {
        DioOption option = {0};
        InitializeDioOption(&option);

        // Modification of the option
        // When you You must set the same value.
        // If a different value is used, you may suffer a fatal error because of a
        // illegal memory access.
        option.frame_period = world_parameters->frame_period;

        // Valuable option.speed represents the ratio for downsampling.
        // The signal is downsampled to fs / speed Hz.
        // If you want to obtain the accurate result, speed should be set to 1.
        option.speed = 1;

        // You should not set option.f0_floor to under world::kFloorF0.
        // If you want to analyze such low F0 speech, please change world::kFloorF0.
        // Processing speed may sacrify, provided that the FFT length changes.
        option.f0_floor = 71.0;

        // You can give a positive real number as the threshold.
        // Most strict value is 0, but almost all results are counted as unvoiced.
        // The value from 0.02 to 0.2 would be reasonable.
        option.allowed_range = 0.1;

        // Parameters setting and memory allocation.
        world_parameters->f0_length = GetSamplesForDIO(world_parameters->fs,
                                                       x_length, world_parameters->frame_period);
        world_parameters->f0 = new double[world_parameters->f0_length];
        world_parameters->time_axis = new double[world_parameters->f0_length];
        double *refined_f0 = new double[world_parameters->f0_length];

        std::cout << std::endl << "Analysis" << std::endl;
        DWORD elapsed_time = timeGetTime();
        Dio(x, x_length, world_parameters->fs, &option, world_parameters->time_axis,
            world_parameters->f0);

        std::cout << "DIO: " << timeGetTime() - elapsed_time << " [msec]" << std::endl;

        // StoneMask is carried out to improve the estimation performance.
        elapsed_time = timeGetTime();
        StoneMask(x, x_length, world_parameters->fs, world_parameters->time_axis,
                  world_parameters->f0, world_parameters->f0_length, refined_f0);

        std::cout << "StoneMask: " << timeGetTime() - elapsed_time << " [msec]" << std::endl;

        for (int i = 0; i < world_parameters->f0_length; ++i)
            world_parameters->f0[i] = refined_f0[i];

        delete[] refined_f0;
        return;
    }

    /**
     *  Spectral envelope estimation function
     *
     *    @param x : the signal samples
     *    @param x_length : the number of samples
     *    @param world_parameters : the world structure which is going to contains the spectrogram (double values)
     *    in the spectrogram structure field
     */
    void SpectralEnvelopeEstimation(double *x, int x_length,
                                    WorldParameters *world_parameters)
    {
        CheapTrickOption option;
        InitializeCheapTrickOption(world_parameters->fs, &option);

        // This value may be better one for HMM speech synthesis.
        // Default value is -0.09.
        option.q1 = -0.15;

        // Important notice (2016/02/02)
        // You can control a parameter used for the lowest F0 in speech.
        // You must not set the f0_floor to 0.
        // It will cause a fatal error because fft_size indicates the infinity.
        // You must not change the f0_floor after memory allocation.
        // You should check the fft_size before excucing the analysis/synthesis.
        // The default value (71.0) is strongly recommended.
        // On the other hand, setting the lowest F0 of speech is a good choice
        // to reduce the fft_size.
        option.f0_floor = 71.0;

        // Parameters setting and memory allocation.
        world_parameters->fft_size =
            GetFFTSizeForCheapTrick(world_parameters->fs, &option);
        world_parameters->spectrogram = new double *[world_parameters->f0_length];
        for (int i = 0; i < world_parameters->f0_length; ++i) {
            world_parameters->spectrogram[i] =
                new double[world_parameters->fft_size / 2 + 1];
        }

        DWORD elapsed_time = timeGetTime();
        CheapTrick(x, x_length, world_parameters->fs, world_parameters->time_axis,
                   world_parameters->f0, world_parameters->f0_length, &option,
                   world_parameters->spectrogram);
        std::cout << "CheapTrick: " << timeGetTime() - elapsed_time << " [msec]" << std::endl;
    }

    /**
     *  Aperiodicity envelope estimation function
     *
     *    @param x : the signal samples
     *    @param x_length : the number of samples
     *    @param world_parameters : the world structure which is going to contains the aperidicity (double values)
     *    in the aperiodicity structure field
     */
    void AperiodicityEstimation(double *x, int x_length,
                                WorldParameters *world_parameters)
    {
        D4COption option;
        InitializeD4COption(&option);

        // Parameters setting and memory allocation.
        world_parameters->aperiodicity = new double *[world_parameters->f0_length];
        for (int i = 0; i < world_parameters->f0_length; ++i) {
            world_parameters->aperiodicity[i] =
                new double[world_parameters->fft_size / 2 + 1];
        }

        DWORD elapsed_time = timeGetTime();
        // option is not implemented in this version. This is for future update.
        // We can use "NULL" as the argument.
        D4C(x, x_length, world_parameters->fs, world_parameters->time_axis,
            world_parameters->f0, world_parameters->f0_length,
            world_parameters->fft_size, &option, world_parameters->aperiodicity);

        std::cout << "D4C: " << timeGetTime() - elapsed_time << " [msec]" << std::endl;
    }

    void DestroyMemory(WorldParameters *world_parameters) {
        delete[] world_parameters->time_axis;
        delete[] world_parameters->f0;
        for (int i = 0; i < world_parameters->f0_length; ++i) {
            delete[] world_parameters->spectrogram[i];
            delete[] world_parameters->aperiodicity[i];
        }
        delete[] world_parameters->spectrogram;
        delete[] world_parameters->aperiodicity;
    }

}  // namespace

/**
 * Main function
 *
 */
int main(int argc, char *argv[])
{
    if (argc != 5)
    {
        std::cerr << argv[0] << "<input_wav_file> <output_f0_file> <output_spectrum_file> <output_aperiodicity_file>" << std::endl;
        return EXIT_FAILURE;
    }

    // 2016/01/28: Important modification.
    // Memory allocation is carried out in advanse.
    // This is for compatibility with C language.
    int x_length = GetAudioLength(argv[1]);
    if (x_length <= 0) {
        if (x_length == 0)
            std::cerr << "error: File \"" << argv[1] << "\" not found"  << std::endl;
        else
            std::cerr << "error: File \"" << argv[1] << "\" is not a .wav format"  << std::endl;
        return EXIT_FAILURE;
    }
    double *x = new double[x_length];

    // wavread() must be called after GetAudioLength().
    int fs, nbit;
    wavread(argv[1], &fs, &nbit, x);
    DisplayInformation(fs, nbit, x_length);

    // 2016/02/02
    // A new struct is introduced to implement safe program.
    WorldParameters world_parameters;

    // You must set fs and frame_period before analysis/synthesis.
    world_parameters.fs = fs;

    // 5.0 ms is the default value.
    // Generally, the inverse of the lowest F0 of speech is the best.
    // However, the more elapsed time is required.
    world_parameters.frame_period = 5.0;

    //---------------------------------------------------------------------------
    // Analysis part
    //---------------------------------------------------------------------------

    // F0 estimation
    F0Estimation(x, x_length, &world_parameters);

    // Spectral envelope estimation
    SpectralEnvelopeEstimation(x, x_length, &world_parameters);

    // Aperiodicity estimation by D4C
    AperiodicityEstimation(x, x_length, &world_parameters);

    std::cout << "fft size = " << world_parameters.fft_size << std::endl;

    //---------------------------------------------------------------------------
    // Saving part
    //---------------------------------------------------------------------------

    // F0 saving
    std::ofstream out_f0(argv[2],  std::ios::out | std::ios::binary);
    if(!out_f0)
    {
        std::cerr << "Cannot open file: " << argv[2] << std::endl;
        return EXIT_FAILURE;
    }

    out_f0.write(reinterpret_cast<const char*>(world_parameters.f0),
                 std::streamsize(world_parameters.f0_length * sizeof(double)));
    out_f0.close();

    // Spectrogram saving
    std::ofstream out_spectrogram(argv[3],  std::ios::out | std::ios::binary);
    if(!out_spectrogram)
    {
        std::cerr << "Cannot open file: " << argv[3] << std::endl;
        return EXIT_FAILURE;
    }

    // write the spectrogram data
    for (int i=0; i<world_parameters.f0_length; i++)
    {
        out_spectrogram.write(reinterpret_cast<const char*>(world_parameters.spectrogram[i]),
                              std::streamsize((world_parameters.fft_size / 2 + 1) * sizeof(double)));
    }

    out_spectrogram.close();

    // Aperiodicity saving
    std::ofstream out_aperiodicity(argv[4],  std::ios::out | std::ios::binary);
    if(!out_aperiodicity)
    {
        std::cerr << "Cannot open file: " << argv[4] << std::endl;
        return EXIT_FAILURE;
    }

    for (int i=0; i<world_parameters.f0_length; i++)
    {
        out_aperiodicity.write(reinterpret_cast<const char*>(world_parameters.aperiodicity[i]),
                               std::streamsize((world_parameters.fft_size / 2 + 1) * sizeof(double)));
    }

    out_aperiodicity.close();

    //---------------------------------------------------------------------------
    // Cleaning part
    //---------------------------------------------------------------------------
    delete[] x;
    DestroyMemory(&world_parameters);

    std::cout << "complete" << std::endl;
    return EXIT_SUCCESS;
}

/* analysis_prog.cpp ends here */


text:
package org.onosproject.rest;

import java.io.IOException;
import java.net.ServerSocket;

import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;

/**
 * Base class for REST API tests.  Performs common configuration operations.
 */
public class ResourceTest extends JerseyTest {

    /**
     * Creates a new web-resource test.
     */
    public ResourceTest() {
        super();
    }

    /**
     * Creates a new web-resource test initialized according to the specified
     * web application class.
     */
    protected ResourceTest(Class<?> webAppClass) {
        super(new WebAppDescriptor.Builder("javax.ws.rs.Application",
                                           webAppClass.getCanonicalName())
                      .servletClass(ServletContainer.class).build());
    }

    /**
     * Assigns an available port for the test.
     *
     * @param defaultPort If a port cannot be determined, this one is used.
     * @return free port
     */
    @Override
    public int getPort(int defaultPort) {
        try {
            ServerSocket socket = new ServerSocket(0);
            socket.setReuseAddress(true);
            int port = socket.getLocalPort();
            socket.close();
            return port;
        } catch (IOException ioe) {
            return defaultPort;
        }
    }

    @Override
    public AppDescriptor configure() {
        return new WebAppDescriptor.Builder("org.onosproject.rest").build();
    }

}