docs: private void doReverseKNNQuery(int k, DBIDRef q, ModifiableDoubleDBIDList result, ModifiableDBIDs candidates) {
      final ComparableMinHeap<MTreeSearchCandidate> pq = new ComparableMinHeap<>();
  
      // push root
      pq.add(new MTreeSearchCandidate(0., getRootID(), null, Double.NaN));
  
      // search in tree
      while(!pq.isEmpty()) {
        MTreeSearchCandidate pqNode = pq.poll();
        // FIXME: cache the distance to the routing object in the queue node!
  
        MkCoPTreeNode<O> node = getNode(pqNode.nodeID);
  
        // directory node
        if(!node.isLeaf()) {
          for(int i = 0; i < node.getNumEntries(); i++) {
            MkCoPEntry entry = node.getEntry(i);
            double distance = distance(entry.getRoutingObjectID(), q);
            double minDist = entry.getCoveringRadius() > distance ? 0. : distance - entry.getCoveringRadius();
            double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
  
            if(minDist <= approximatedKnnDist_cons) {
              pq.add(new MTreeSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID(), Double.NaN));
            }
          }
        }
        // data node
        else {
          for(int i = 0; i < node.getNumEntries(); i++) {
            MkCoPLeafEntry entry = (MkCoPLeafEntry) node.getEntry(i);
            double distance = distance(entry.getRoutingObjectID(), q);
            double approximatedKnnDist_prog = entry.approximateProgressiveKnnDistance(k);
  
            if(distance <= approximatedKnnDist_prog) {
              result.add(distance, entry.getRoutingObjectID());
            }
            else {
              double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
              double diff = distance - approximatedKnnDist_cons;
              if(diff <= 1E-10) {
                candidates.add(entry.getRoutingObjectID());
              }
            }
          }
        }
      }
    }