code: public Set<Interval<T>> query(Interval<T> interval){
  		Set<Interval<T>> result = new HashSet<>();
  
  		if (root == null || interval.isEmpty())
  			return result;
  		TreeNode<T> node = root;
  		while (node != null){
  			if (interval.contains(node.midpoint)){
  				result.addAll(node.increasing);
  				TreeNode.rangeQueryLeft(node.left, interval, result);
  				TreeNode.rangeQueryRight(node.right, interval, result);
  				break;
  			}
  			if (interval.isLeftOf(node.midpoint)) {
  				for (Interval<T> next: node.increasing){
  					if (!interval.intersects(next))
  						break;
  					result.add(next);
  				}
  				node = node.left;
  			}
  			else {
  				for (Interval<T> next: node.decreasing){
  					if (!interval.intersects(next))
  						break;
  					result.add(next);
  				}
  				node = node.right;
  			}
  		}
  		return result;
  	}
docs: Searches for and returns all intervals stored in the tree, that intersect a given
  query interval. This operation is guaranteed to run in {@code O(logn + k)}, where
  {@code n} is the size of the tree and {@code k} is the size of the returned set,
  provided that the time complexity of iterating over the intervals stored in each
  visited node is amortized {@code O(1)}. This assumption is met for the current
  implementation of {@link TreeNode}, where {@link TreeSet}s are used.
  
  @param interval The query interval.
  @return A set containing all intervals from the tree, intersecting the query interval.