class NFACompiler {

	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;
	}

}