code: public <E> MinimizationResult<S, L> performMinimization(UniversalGraph<S, E, ?, L> graph,
                                                              Collection<? extends S> initialNodes) {
          // Initialize the data structures (esp. state records) and build
          // the initial partition.
          Collection<Block<S, L>> initialBlocks = initialize(graph, initialNodes);
  
          // Add all blocks from the initial partition as an element
          // of the partition, and as a potential splitter.
          partition = new UnorderedCollection<>(initialBlocks.size());
          ///splitters.hintNextCapacity(initialBlocks.size());
  
          for (Block<S, L> block : initialBlocks) {
              if (block == null || block.isEmpty()) {
                  continue;
              }
              addToPartition(block);
              addToSplitterQueue(block);
              numBlocks++;
          }
  
          // Split the blocks of the partition, until no splitters
          // remain
          while (!splitters.isEmpty()) {
              Block<S, L> block = splitters.choose();
              removeFromSplitterQueue(block);
  
              split(block);
              updateBlocks();
          }
  
          // Return the result.
          MinimizationResult<S, L> result = new MinimizationResult<>(stateStorage, partition);
  
          // Ensure the garbage collection isn't hampered
          stateStorage = null;
          partition = null;
          numBlocks = 0;
  
          return result;
      }
docs: Performs the minimization of an automaton.
  <p>
  The automaton is accessed via a {@link UniversalGraph}. The result of the minimization process is effectively a
  partition on the set of states, each element (block) in this partition contains equivalent states that can be
  merged in a minimized automaton.
  
  @param <E>
  edge identifier class.
  @param graph
  the automaton interface.
  
  @return a {@link MinimizationResult} structure, containing the state partition.