public static boolean canProduceEmptyMatches(final Pattern<?, ?> pattern) {
        NFAFactoryCompiler<?> compiler = new NFAFactoryCompiler<>(checkNotNull(pattern));
        compiler.compileFactory();
        State<?> startState =
                compiler.getStates().stream()
                        .filter(State::isStart)
                        .findFirst()
                        .orElseThrow(
                                () ->
                                        new IllegalStateException(
                                                "Compiler produced no start state. It is a bug. File a jira."));

        Set<State<?>> visitedStates = new HashSet<>();
        final Stack<State<?>> statesToCheck = new Stack<>();
        statesToCheck.push(startState);
        while (!statesToCheck.isEmpty()) {
            final State<?> currentState = statesToCheck.pop();
            if (visitedStates.contains(currentState)) {
                continue;
            } else {
                visitedStates.add(currentState);
            }

            for (StateTransition<?> transition : currentState.getStateTransitions()) {
                if (transition.getAction() == StateTransitionAction.PROCEED) {
                    if (transition.getTargetState().isFinal()) {
                        return true;
                    } else {
                        statesToCheck.push(transition.getTargetState());
                    }
                }
            }
        }

        return false;
    }
@Test
    public void testCheckingEmptyMatches() {
        assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").optional()), is(true));
        assertThat(
                NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore().optional()),
                is(true));
        assertThat(
                NFACompiler.canProduceEmptyMatches(
                        Pattern.begin("a").oneOrMore().optional().next("b").optional()),
                is(true));

        assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a")), is(false));
        assertThat(NFACompiler.canProduceEmptyMatches(Pattern.begin("a").oneOrMore()), is(false));
        assertThat(
                NFACompiler.canProduceEmptyMatches(
                        Pattern.begin("a").oneOrMore().next("b").optional()),
                is(false));
    }