docs: private void fixMergeOrderAndAssign(double[] mergedDistance, IntList merge_kept, IntList merge_removed, int lowK, final int N, int highK, int[] designations)
      {
          //Now that we are done clustering, we need to re-order the merges so that the smallest distances are mergered first
          IndexTable it = new IndexTable(mergedDistance);
          it.apply(merge_kept);
          it.apply(merge_removed);
          it.apply(mergedDistance);
          for(int i = 0; i < it.length(); i++)
          {
              merges[merges.length-i*2-1] = merge_removed.get(i);
              merges[merges.length-i*2-2] = merge_kept.get(i);
          }
  
          //Now lets figure out a guess at the cluster size
          /*
          * Keep track of the average dist when merging, mark when it becomes abnormaly large as a guess at K
          */
          OnLineStatistics distChange = new OnLineStatistics();
          double maxStndDevs = Double.MIN_VALUE;
  
          /**
           * How many clusters to return
           */
          int clusterSize = lowK;
  
          for(int i = 0; i < mergedDistance.length; i++)
          {
              
              //Keep track of the changes in cluster size, and mark if this one was abnormall large
              distChange.add(mergedDistance[i]);
  
              int curK = N - i;
              if (curK >= lowK && curK <= highK)//In the cluster window?
              {
                  double stndDevs = (mergedDistance[i] - distChange.getMean()) / distChange.getStandardDeviation();
                  if (stndDevs > maxStndDevs)
                  {
                      maxStndDevs = stndDevs;
                      clusterSize = curK;
                  }
              }
          }
          
          PriorityHAC.assignClusterDesignations(designations, clusterSize, merges);
      }