code: @Override
    public <T extends OutputStream> T serialize(final FSA fsa, T os) throws IOException {
      /*
       * Calculate the most frequent labels and build indexed labels dictionary.
       */
      computeLabelsIndex(fsa);
  
      /*
       * Calculate the number of bytes required for the node data, if
       * serializing with numbers.
       */
      if (withNumbers) {
        this.numbers = FSAUtils.rightLanguageForAllStates(fsa);
      }
  
      /*
       * Linearize all the states, optimizing their layout.
       */
      IntArrayList linearized = linearize(fsa);
  
      /*
       * Emit the header.
       */
      FSAHeader.write(os, CFSA2.VERSION);
  
      EnumSet<FSAFlags> fsaFlags = EnumSet.of(FLEXIBLE, STOPBIT, NEXTBIT);
      if (withNumbers) {
        fsaFlags.add(NUMBERS);
      }
  
      final short sflags = FSAFlags.asShort(fsaFlags);
      os.write((sflags >> 8) & 0xFF);
      os.write((sflags) & 0xFF);
  
      /*
       * Emit labels index.
       */
      os.write(labelsIndex.length);
      os.write(labelsIndex);
  
      /*
       * Emit the automaton.
       */
      int size = emitNodes(fsa, os, linearized);
      assert size == 0 : "Size changed in the final pass?";
  
      return os;
    }
docs: Serializes any {@link FSA} to {@link CFSA2} stream.
  
  @see #withNumbers()
  @return Returns <code>os</code> for chaining.