docs: public static <T> void processDense(T data, Adapter<T> adapter, Collector collector) {
      // Number of nodes
      final int n = adapter.size(data);
      // Best distance for each node
      double[] best = new double[n];
      Arrays.fill(best, Double.POSITIVE_INFINITY);
      // Best previous node
      int[] src = new int[n];
      // Nodes already handled
      // byte[] uses more memory, but it will be faster.
      byte[] connected = new byte[n];
  
      // We always start at "random" node 0
      // Note: we use this below in the "j" loop!
      int current = 0;
      connected[current] = 1;
      best[current] = 0;
  
      // Search
      for(int i = n - 2; i >= 0; i--) {
        // Update best and src from current:
        int newbesti = -1;
        double newbestd = Double.POSITIVE_INFINITY;
        // Note: we assume we started with 0, and can thus skip it
        for(int j = 0; j < n; ++j) {
          if(connected[j] == 1) {
            continue;
          }
          final double dist = adapter.distance(data, current, j);
          if(dist < best[j]) {
            best[j] = dist;
            src[j] = current;
          }
          if(best[j] < newbestd || newbesti == -1) {
            newbestd = best[j];
            newbesti = j;
          }
        }
        assert (newbesti >= 0);
        // Flag
        connected[newbesti] = 1;
        // Store edge
        collector.addEdge(newbestd, src[newbesti], newbesti);
        // Continue
        current = newbesti;
      }
    }