code: private int linearizeAndCalculateOffsets(FSA fsa, IntArrayList states, IntArrayList linearized,
        IntIntHashMap offsets) throws IOException {
      final BitSet visited = new BitSet();
      final IntStack nodes = new IntStack();
      linearized.clear();
  
      /*
       * Linearize states with most inlinks first.
       */
      for (int i = 0; i < states.size(); i++) {
        linearizeState(fsa, nodes, linearized, visited, states.get(i));
      }
  
      /*
       * Linearize the remaining states by chaining them one after another, in depth-order.
       */
      nodes.push(fsa.getRootNode());
      while (!nodes.isEmpty()) {
        final int node = nodes.pop();
        if (visited.get(node))
          continue;
  
        linearizeState(fsa, nodes, linearized, visited, node);
      }
  
      /*
       * Calculate new state offsets. This is iterative. We start with 
       * maximum potential offsets and recalculate until converged.
       */
      int MAX_OFFSET = Integer.MAX_VALUE;
      for (IntCursor c : linearized) {
        offsets.put(c.value, MAX_OFFSET);
      }
  
      int i, j = 0;
      while ((i = emitNodes(fsa, null, linearized)) > 0) {
        j = i;
      }
      return j;
    }
docs: Linearize all states, putting <code>states</code> in front of the automaton
  and calculating stable state offsets.