docs: public void contractStates() {
        boolean contracted;
        do {
           contracted = false;
           for (Iterator<State> iterator = states.iterator(); iterator.hasNext(); ) {
              State s = iterator.next();
              if (s.links.size() == 1 && s.links.get(0).type == LinkType.BACKTRACK) {
                 Link l = s.links.get(0);
                 boolean contractedNow = false;
                 for (State s2 : states) {
                    for (Link l2 : s2.links) {
                       if (l2.next == s && l2.type != LinkType.SENTINEL) {
                          l2.code = l2.code + "\n" + l.code;
                          l2.next = l.next;
                          contractedNow = true;
                       }
                    }
                 }
                 if (contractedNow) {
                    iterator.remove();
                    contracted = true;
                 }
              }
           }
        } while (contracted);
        // renumber
        for (int i = 0; i < states.size(); ++i) {
           states.get(i).id = i;
        }
     }