@SuppressWarnings({"unchecked"})
  @Test
  public void testInternalTransition() throws Exception {
    context.register(BaseConfig.class, Config2.class);
    context.refresh();
    assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
    ObjectStateMachine<TestStates, TestEvents> machine =
        context.getBean(
            StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
    machine.start();
    TestExitAction testExitAction = context.getBean("testExitAction", TestExitAction.class);
    TestEntryAction testEntryAction = context.getBean("testEntryAction", TestEntryAction.class);
    TestAction externalTestAction = context.getBean("externalTestAction", TestAction.class);
    TestAction internalTestAction = context.getBean("internalTestAction", TestAction.class);

    assertThat(machine.getState().getIds(), contains(TestStates.S1));
    assertThat(testExitAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(false));
    assertThat(testEntryAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(false));

    machine.sendEvent(TestEvents.E1);
    assertThat(testExitAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(false));
    assertThat(testEntryAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(false));
    assertThat(internalTestAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));

    machine.sendEvent(TestEvents.E2);
    assertThat(testExitAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(testEntryAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));
    assertThat(externalTestAction.onExecuteLatch.await(1, TimeUnit.SECONDS), is(true));

    assertThat(machine.getState().getIds(), contains(TestStates.S2));
  }
 @SuppressWarnings({"unchecked"})
 @Test
 public void testTriggerlessTransitionInRegions() throws Exception {
   context.register(BaseConfig.class, Config6.class);
   context.refresh();
   assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
   ObjectStateMachine<TestStates, TestEvents> machine =
       context.getBean(
           StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
   machine.start();
   assertThat(machine.getState().getIds(), contains(TestStates.S1));
   machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
   assertThat(
       machine.getState().getIds(),
       containsInAnyOrder(TestStates.S2, TestStates.S201, TestStates.S211));
 }
 @SuppressWarnings({"unchecked"})
 @Test
 public void testTriggerlessTransitionFromInitial() throws Exception {
   context.register(BaseConfig.class, Config3.class);
   context.refresh();
   assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
   ObjectStateMachine<TestStates, TestEvents> machine =
       context.getBean(
           StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
   machine.start();
   assertThat(machine.getState().getIds(), contains(TestStates.S2));
 }
  @SuppressWarnings({"unchecked"})
  @Test
  public void testTriggerlessTransition() throws Exception {
    context.register(BaseConfig.class, Config1.class);
    context.refresh();

    assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
    ObjectStateMachine<TestStates, TestEvents> machine =
        context.getBean(
            StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);

    TestListener listener = new TestListener();
    machine.addStateListener(listener);

    machine.start();
    assertThat(machine.getState().getIds(), contains(TestStates.S1));

    listener.reset(2);
    machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
    assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
    assertThat(listener.stateChangedCount, is(2));
    assertThat(machine.getState().getIds(), contains(TestStates.S3));
  }
  @SuppressWarnings({"unchecked"})
  @Test
  public void testTriggerlessTransitionFromInitialToEnd() throws Exception {
    context.register(BaseConfig.class, Config4.class);
    context.refresh();

    assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
    ObjectStateMachine<TestStates, TestEvents> machine =
        context.getBean(
            StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class);
    machine.start();
    // end state terminates sm so state is null
    assertThat(machine.getState(), nullValue());
    assertThat(machine.isComplete(), is(true));
    assertThat(machine.isRunning(), is(false));
  }