protected <STATE, TOKEN> StateAliasNfa<TOKEN> createNfa(Nfa<STATE> nfa, Function<STATE, TOKEN> state2token) {
HashMap<STATE, StateAlias<TOKEN>> cache = Maps.<STATE, StateAlias<TOKEN>> newLinkedHashMap();
StateAlias<TOKEN> stop = null;
if (nfa.getStart() != nfa.getStop()) {
stop = new StateAlias<TOKEN>(new ElementAlias<TOKEN>(state2token.apply(nfa.getStop())));
cache.put(nfa.getStop(), stop);
}
StateAlias<TOKEN> start = toAlias(nfa, state2token, nfa.getStart(), cache);
if (nfa.getStart() == nfa.getStop()) {
stop = new StateAlias<TOKEN>(start.getElement());
for (StateAlias<TOKEN> in : start.getIncoming()) {
stop.getIncoming().add(in);
in.getOutgoing().add(stop);
in.getOutgoing().remove(start);
}
start.getIncoming().clear();
}
StateAliasNfa<TOKEN> states = new StateAliasNfa<TOKEN>(start, stop);
return states;
}