code: public Set<Match<? extends E>> search(E query, int maxDistance) {
          if (query == null) throw new NullPointerException();
          if (maxDistance < 0) throw new IllegalArgumentException("maxDistance must be non-negative");
  
          Metric<? super E> metric = tree.getMetric();
  
          Set<Match<? extends E>> matches = new HashSet<>();
  
          Queue<Node<E>> queue = new ArrayDeque<>();
          queue.add(tree.getRoot());
  
          while (!queue.isEmpty()) {
              Node<E> node = queue.remove();
              E element = node.getElement();
  
              int distance = metric.distance(element, query);
              if (distance < 0) {
                  throw new IllegalMetricException(
                      format("negative distance (%d) defined between element `%s` and query `%s`",
                          distance, element, query));
              }
  
              if (distance <= maxDistance) {
                  matches.add(new Match<>(element, distance));
              }
  
              int minSearchDistance = max(distance - maxDistance, 0);
              int maxSearchDistance = distance + maxDistance;
  
              for (int searchDistance = minSearchDistance; searchDistance <= maxSearchDistance; ++searchDistance) {
                  Node<E> childNode = node.getChildNode(searchDistance);
                  if (childNode != null) {
                      queue.add(childNode);
                  }
              }
          }
  
          return matches;
      }
docs: Searches the tree for elements whose distance from the given query
  is less than or equal to the given maximum distance.
  
  @param query query against which to match tree elements
  @param maxDistance non-negative maximum distance of matching elements from query
  @return matching elements in no particular order