code: public static <T extends Comparable<? super T>> TreeNode<T> addInterval(IntervalTree<T> tree, TreeNode<T> root, Interval<T> interval) {
  		if (root == null) {
  			tree.size++;
  			return new TreeNode<>(interval);
  		}
  		if (interval.contains(root.midpoint)){
  			if (root.decreasing.add(interval))
  				tree.size++;
  			root.increasing.add(interval);
  			return root;
  		} else if (interval.isLeftOf(root.midpoint)){
  			root.left = addInterval(tree, root.left, interval);
  			root.height = Math.max(height(root.left), height(root.right))+1;
  		} else {
  			root.right = addInterval(tree, root.right, interval);
  			root.height = Math.max(height(root.left), height(root.right))+1;
  		}
  
  		return root.balanceOut();
  	}
docs: A helper function for the {@link IntervalTree#add(Interval)} method. Adds a new
  interval to the subtree rooted at a {@code TreeNode}.
  
  @param tree The {@link IntervalTree} containing the subtree. Used primarily for
  housekeeping, such as adjusting the size of the tree, if needed.
  @param root The root of the subtree, to which we are adding a new interval.
  @param interval The {@link Interval} that we are adding.
  @param <T> The type of the start and end points of the interval.
  @return The new root of the subtree. It may be different than the current root,
  if the subtree had to be rebalanced after the operation.