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);
  }
  /**
   * +--------------+ |outerscope | | +----------+ | | |innerscope| | +-----+ | | +----+ | | +---+
   * |start|---->|wait|------>|end| +-----+ | | +----+ | | +---+ | +----------+ | +--------------+
   */
  public void testNestedActivitiesEventsOnTransitionEvents() {
    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("wait")
            .executionListener(eventCollector)
            .endTransition()
            .endActivity()
            .createActivity("outerscope")
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("innerscope")
            .scope()
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_START, eventCollector)
            .executionListener(
                org.camunda.bpm.engine.impl.pvm.PvmEvent.EVENTNAME_END, eventCollector)
            .createActivity("wait")
            .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("end")
            .endActivity()
            .endActivity()
            .endActivity()
            .createActivity("end")
            .behavior(new WaitState())
            .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)-->(wait)");
    expectedEvents.add("start on Activity(outerscope)");
    expectedEvents.add("start on Activity(innerscope)");
    expectedEvents.add("start on Activity(wait)");

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

    PvmExecution execution = processInstance.findExecution("wait");
    execution.signal(null, null);

    expectedEvents.add("end on Activity(wait)");
    expectedEvents.add("end on Activity(innerscope)");
    expectedEvents.add("end on Activity(outerscope)");

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