StateMachine { public <U> U getStateOfType(Class<U> type) { for (final State<T, C> state : getStates()) { if (type.isInstance(state)) { return type.cast(state); } } throw new IllegalArgumentException("There is no instance of " + type + " in this state machine."); } StateMachine(State<T, C> start,
      ImmutableTable<State<T, C>, T, State<T, C>> table,
      boolean explRecurTrns); void handle(C context); void handle(@Nullable T trigger, C context); State<T, C> getCurrentState(); boolean stateIs(State<T, C> s); @SafeVarargs final boolean stateIsOneOf(State<T, C>... states); ImmutableCollection<State<T, C>> getStates(); U getStateOfType(Class<U> type); boolean isSupported(T trigger); EventAPI getEventAPI(); @Override int hashCode(); @Override boolean equals(@Nullable Object other); @Override String toString(); @CheckReturnValue static StateMachineBuilder<T, C> create(
      State<T, C> initialState);  }
@Test public void testGetStateOfType() { final StateA a = new StateA(); final StateB b = new StateB(); final StateC c = new StateC(); final StateMachineBuilder<Events, Context> smb = StateMachine.create(a) .addTransition(a, Events.START, b) .addTransition(b, Events.START, c) .addTransition(c, Events.START, a); if (explicitRecursiveTransitions) { smb.explicitRecursiveTransitions(); } fsm = smb.build(); final State<Events, Context> first = fsm.getStates().iterator().next(); assertEquals(first, fsm.getStateOfType(Object.class)); assertEquals(b, fsm.getStateOfType(StateB.class)); assertEquals(c, fsm.getStateOfType(StateC.class)); boolean fail = false; try { fsm.getStateOfType(Enum.class); } catch (final IllegalArgumentException e) { fail = true; } assertTrue(fail); }