code: private int[] computeFirstStates(IntIntHashMap inlinkCount, int maxStates, int minInlinkCount) {
      Comparator<IntIntHolder> comparator = new Comparator<FSAUtils.IntIntHolder>() {
        public int compare(IntIntHolder o1, IntIntHolder o2) {
          int v = o1.a - o2.a;
          return v == 0 ? (o1.b - o2.b) : v;
        } 
      };
  
      PriorityQueue<IntIntHolder> stateInlink = new PriorityQueue<IntIntHolder>(1, comparator);
      IntIntHolder scratch = new IntIntHolder();
      for (IntIntCursor c : inlinkCount) {
        if (c.value > minInlinkCount) {
          scratch.a = c.value;
          scratch.b = c.key;
  
          if (stateInlink.size() < maxStates || comparator.compare(scratch, stateInlink.peek()) > 0) {
            stateInlink.add(new IntIntHolder(c.value, c.key));
            if (stateInlink.size() > maxStates) {
              stateInlink.remove();
            }
          }
        }
      }
  
      int [] states = new int [stateInlink.size()];
      for (int position = states.length; !stateInlink.isEmpty();) {
        IntIntHolder i = stateInlink.remove();
        states[--position] = i.b;
      }
  
      return states;
    }
docs: Compute the set of states that should be linearized first to minimize other
  states goto length.