code: public Partition refine(Partition coarser) {
          Partition finer = new Partition(coarser);
  
          // start the queue with the blocks of a in reverse order
          blocksToRefine = new LinkedList<Set<Integer>>();
          for (int i = 0; i < finer.size(); i++) {
              blocksToRefine.add(finer.copyBlock(i));
          }
  
          int numberOfVertices = refinable.getVertexCount();
          while (!blocksToRefine.isEmpty()) {
              Set<Integer> t = blocksToRefine.remove();
              currentBlockIndex = 0;
              while (currentBlockIndex < finer.size() && finer.size() < numberOfVertices) {
                  if (!finer.isDiscreteCell(currentBlockIndex)) {
  
                      // get the neighbor invariants for this block
                      Map<Invariant, SortedSet<Integer>> invariants = getInvariants(finer, t);
  
                      // split the block on the basis of these invariants
                      split(invariants, finer);
                  }
                  currentBlockIndex++;
              }
  
              // the partition is discrete
              if (finer.size() == numberOfVertices) {
                  return finer;
              }
          }
          return finer;
      }
docs: Refines the coarse partition <code>a</code> into a finer one.
  
  @param coarser the partition to refine
  @return a finer partition