code: public void computeCoarsestStablePartition() {
          Block curr;
          while ((curr = poll()) != null) {
              int blockRange = curr.high - curr.low;
              // copy blockData, because #moveLeft() may change its data while we iterate over it
              // TODO maybe find an implementation that does not need to workaround this concurrent modification
              int[] blockCopy = new int[blockRange];
              System.arraycopy(blockData, curr.low, blockCopy, 0, blockRange);
              int predOfsBase = predOfsDataLow;
              for (int i = 0; i < numInputs; i++) {
                  for (int j = 0; j < blockRange; j++) {
                      int state = blockCopy[j];
                      int predOfsIdx = predOfsBase + state;
                      int predLow = predOfsData[predOfsIdx], predHigh = predOfsData[predOfsIdx + 1];
                      for (int k = predLow; k < predHigh; k++) {
                          int pred = predData[k];
                          moveLeft(pred);
                      }
                  }
                  predOfsBase += numStates;
                  processTouched();
              }
          }
      }
docs: Refines the partition until it stabilizes.