static boolean prefixMatches(Tree target, Tree pattern) {
    if (pattern.isEmpty()) return true;
    if (target.isEmpty() || target.value() != pattern.value()) return false;

    return prefixMatches(target.left(), pattern.left())
        && prefixMatches(target.right(), pattern.right());
  }
 /*
  * Trim BST - Given min and max trim the tree so that all nodes has values between min and max
  */
 public Tree trimTree(Tree node, int min, int max) {
   if (node == null) return null;
   node.left = trimTree(node.left, min, max);
   node.right = trimTree(node.right, min, max);
   if (node.value < min) return node.right;
   else if (node.value > max) return node.left;
   else return node;
 }
  /**
   * Search the tree for the first instance of `pattern`, giving preference to the left child.
   *
   * <p>`pattern` is a tree, representing a pattern of nodes. `NilNode`s should be considered
   * wildcards.
   *
   * <p>Example patterns ---------------- `Tree()` Matches any tree.
   *
   * <p>`Tree(3)` Matches any tree where the root node has a value of `3`.
   *
   * <p>`Tree(3, Tree(2), Tree())` Matches any tree where the root node has a value of `3`, and a
   * left sub-tree with a root value of `2`, and any (or no) right sub-tree.
   */
  static Optional<Tree> find(Tree target, Tree pattern) {
    if (pattern.isEmpty()) return Optional.of(target);
    if (target.isEmpty()) return Optional.empty();
    if (prefixMatches(target, pattern)) return Optional.of(target);

    Optional<Tree> leftMatch = find(target.left(), pattern);
    if (leftMatch.isPresent()) return leftMatch;
    return find(target.right(), pattern);
  }
 public Tree add(Tree node, int value) {
   if (node == null) {
     node = new Tree(value);
     return node;
   } else {
     if (value < node.value) node.left = add(node.left, value);
     else node.right = add(node.right, value);
   }
   return node;
 }