public void testSimpleAutmaticConcurrency() {
    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder()
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .transition("fork")
            .endActivity()
            .createActivity("fork")
            .behavior(new ParallelGateway())
            .transition("c1")
            .transition("c2")
            .endActivity()
            .createActivity("c1")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("c2")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("join")
            .behavior(new ParallelGateway())
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new End())
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    assertTrue(processInstance.isEnded());
  }
  public void testJoinForkCombinedInOneParallelGateway() {
    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder()
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .transition("fork")
            .endActivity()
            .createActivity("fork")
            .behavior(new ParallelGateway())
            .transition("c1")
            .transition("c2")
            .transition("c3")
            .endActivity()
            .createActivity("c1")
            .behavior(new Automatic())
            .transition("join1")
            .endActivity()
            .createActivity("c2")
            .behavior(new Automatic())
            .transition("join1")
            .endActivity()
            .createActivity("c3")
            .behavior(new Automatic())
            .transition("join2")
            .endActivity()
            .createActivity("join1")
            .behavior(new ParallelGateway())
            .transition("c4")
            .transition("c5")
            .transition("c6")
            .endActivity()
            .createActivity("c4")
            .behavior(new Automatic())
            .transition("join2")
            .endActivity()
            .createActivity("c5")
            .behavior(new Automatic())
            .transition("join2")
            .endActivity()
            .createActivity("c6")
            .behavior(new Automatic())
            .transition("join2")
            .endActivity()
            .createActivity("join2")
            .behavior(new ParallelGateway())
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new WaitState())
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    assertNotNull(processInstance.findExecution("end"));
  }
  public void testUnstructuredConcurrencyTwoForks() {
    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder()
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .transition("fork1")
            .endActivity()
            .createActivity("fork1")
            .behavior(new ParallelGateway())
            .transition("c1")
            .transition("c2")
            .transition("fork2")
            .endActivity()
            .createActivity("c1")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("c2")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("fork2")
            .behavior(new ParallelGateway())
            .transition("c3")
            .transition("c4")
            .endActivity()
            .createActivity("c3")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("c4")
            .behavior(new Automatic())
            .transition("join")
            .endActivity()
            .createActivity("join")
            .behavior(new ParallelGateway())
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new WaitState())
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    assertNotNull(processInstance.findExecution("end"));
  }
  public void testSimpleWaitStateConcurrency() {
    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder()
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .transition("fork")
            .endActivity()
            .createActivity("fork")
            .behavior(new ParallelGateway())
            .transition("c1")
            .transition("c2")
            .endActivity()
            .createActivity("c1")
            .behavior(new WaitState())
            .transition("join")
            .endActivity()
            .createActivity("c2")
            .behavior(new WaitState())
            .transition("join")
            .endActivity()
            .createActivity("join")
            .behavior(new ParallelGateway())
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new WaitState())
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    PvmExecution activityInstanceC1 = processInstance.findExecution("c1");
    assertNotNull(activityInstanceC1);

    PvmExecution activityInstanceC2 = processInstance.findExecution("c2");
    assertNotNull(activityInstanceC2);

    activityInstanceC1.signal(null, null);
    activityInstanceC2.signal(null, null);

    List<String> activityNames = processInstance.findActiveActivityIds();
    List<String> expectedActivityNames = new ArrayList<String>();
    expectedActivityNames.add("end");

    assertEquals(expectedActivityNames, activityNames);
  }
  /** +-------+ +-----+ | start |-->| end | +-------+ +-----+ */
  public void testStartEndEvents() {
    EventCollector eventCollector = new EventCollector();

    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder("events")
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .startTransition("end")
            .executionListener(eventCollector)
            .endTransition()
            .endActivity()
            .createActivity("end")
            .behavior(new End())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    List<String> expectedEvents = new ArrayList<String>();
    expectedEvents.add("start on ProcessDefinition(events)");
    expectedEvents.add("start on Activity(start)");
    expectedEvents.add("end on Activity(start)");
    expectedEvents.add("take on (start)-->(end)");
    expectedEvents.add("start on Activity(end)");
    expectedEvents.add("end on Activity(end)");
    expectedEvents.add("end on ProcessDefinition(events)");

    assertEquals(
        "expected " + expectedEvents + ", but was \n" + eventCollector + "\n",
        expectedEvents,
        eventCollector.events);
  }
  /**
   * +-----------------------------------------------+ +-----+ | +-----------+ +------------+
   * +----------+ | +---+ |start|-->| |startInside|-->| taskInside |-->|endInsdide| |-->|end|
   * +-----+ | +-----------+ +------------+ +----------+ | +---+
   * +-----------------------------------------------+
   */
  public void testEmbeddedSubProcessEventsDelete() {
    EventCollector eventCollector = new EventCollector();

    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder("events")
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("embeddedsubprocess")
            .endActivity()
            .createActivity("embeddedsubprocess")
            .scope()
            .behavior(new EmbeddedSubProcess())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("startInside")
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("taskInside")
            .endActivity()
            .createActivity("taskInside")
            .behavior(new WaitState())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("endInside")
            .endActivity()
            .createActivity("endInside")
            .behavior(new End())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .endActivity()
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new End())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    ExecutionImpl execution = (ExecutionImpl) processInstance;
    FoxDeleteProcessInstanceCmd cmd = new FoxDeleteProcessInstanceCmd(null, null);
    List<InterpretableExecution> collectExecutionToDelete = cmd.collectExecutionToDelete(execution);
    for (InterpretableExecution interpretableExecution : collectExecutionToDelete) {
      interpretableExecution.deleteCascade2("");
    }

    List<String> expectedEvents = new ArrayList<String>();
    expectedEvents.add("start on ProcessDefinition(events)");
    expectedEvents.add("start on Activity(start)");
    expectedEvents.add("end on Activity(start)");
    expectedEvents.add("start on Activity(embeddedsubprocess)");
    expectedEvents.add("start on Activity(startInside)");
    expectedEvents.add("end on Activity(startInside)");
    expectedEvents.add("start on Activity(taskInside)");
    expectedEvents.add("end on Activity(taskInside)");
    expectedEvents.add("end on Activity(embeddedsubprocess)");
    expectedEvents.add("end on ProcessDefinition(events)");

    assertEquals(
        "expected " + expectedEvents + ", but was \n" + eventCollector + "\n",
        expectedEvents,
        eventCollector.events);
  }
  /**
   * +--+ +--->|c1|---+ | +--+ | | v +-----+ +----+ +----+ +---+ |start|-->|fork| |join|-->|end|
   * +-----+ +----+ +----+ +---+ | ^ | +--+ | +--->|c2|---+ +--+
   */
  public void testSimpleAutmaticConcurrencyEvents() {
    EventCollector eventCollector = new EventCollector();

    PvmProcessDefinition processDefinition =
        new ProcessDefinitionBuilder("events")
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("start")
            .initial()
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("fork")
            .endActivity()
            .createActivity("fork")
            .behavior(new ParallelGateway())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("c1")
            .transition("c2")
            .endActivity()
            .createActivity("c1")
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("join")
            .endActivity()
            .createActivity("c2")
            .behavior(new Automatic())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("join")
            .endActivity()
            .createActivity("join")
            .behavior(new ParallelGateway())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .transition("end")
            .endActivity()
            .createActivity("end")
            .behavior(new End())
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .endActivity()
            .buildProcessDefinition();

    PvmProcessInstance processInstance = processDefinition.createProcessInstance();
    processInstance.start();

    List<String> expectedEvents = new ArrayList<String>();
    expectedEvents.add("start on ProcessDefinition(events)");
    expectedEvents.add("start on Activity(start)");
    expectedEvents.add("end on Activity(start)");
    expectedEvents.add("start on Activity(fork)");
    expectedEvents.add("end on Activity(fork)");
    expectedEvents.add("start on Activity(c1)");
    expectedEvents.add("end on Activity(c1)");
    expectedEvents.add("start on Activity(join)");
    expectedEvents.add("end on Activity(fork)");
    expectedEvents.add("start on Activity(c2)");
    expectedEvents.add("end on Activity(c2)");
    expectedEvents.add("start on Activity(join)");
    expectedEvents.add("end on Activity(join)");
    expectedEvents.add("end on Activity(join)");
    expectedEvents.add("start on Activity(end)");
    expectedEvents.add("end on Activity(end)");
    expectedEvents.add("end on ProcessDefinition(events)");

    assertEquals(
        "expected " + expectedEvents + ", but was \n" + eventCollector + "\n",
        expectedEvents,
        eventCollector.events);
  }