code: private double filter(Node node, double[][] centroids, int[] candidates, int k, double[][] sums, int[] counts, int[] membership) {
          int d = centroids[0].length;
  
          // Determine which mean the node mean is closest to
          double minDist = Math.squaredDistance(node.center, centroids[candidates[0]]);
          int closest = candidates[0];
          for (int i = 1; i < k; i++) {
              double dist = Math.squaredDistance(node.center, centroids[candidates[i]]);
              if (dist < minDist) {
                  minDist = dist;
                  closest = candidates[i];
              }
          }
  
          // If this is a non-leaf node, recurse if necessary
          if (node.lower != null) {
              // Build the new list of candidates
              int[] newCandidates = new int[k];
              int newk = 0;
  
              for (int i = 0; i < k; i++) {
                  if (!prune(node.center, node.radius, centroids, closest, candidates[i])) {
                      newCandidates[newk++] = candidates[i];
                  }
              }
  
              // Recurse if there's at least two
              if (newk > 1) {
                  double result = filter(node.lower, centroids, newCandidates, newk, sums, counts, membership) + filter(node.upper, centroids, newCandidates, newk, sums, counts, membership);
  
                  return result;
              }
          }
  
          // Assigns all data within this node to a single mean
          for (int i = 0; i < d; i++) {
              sums[closest][i] += node.sum[i];
          }
  
          counts[closest] += node.count;
  
          if (membership != null) {
              int last = node.index + node.count;
              for (int i = node.index; i < last; i++) {
                  membership[index[i]] = closest;
              }
          }
  
          return getNodeCost(node, centroids[closest]);
      }
docs: This determines which clusters all data that are rooted node will be
  assigned to, and updates sums, counts and membership (if not null)
  accordingly. Candidates maintains the set of cluster indices which
  could possibly be the closest clusters for data in this subtree.