private void removeNodeTwoChildren(BinaryNode node) {
   BinaryNode current = (BinaryNode) right(node);
   BinaryNode behind = node;
   while (hasLeft(current)) {
     behind = current;
     current = (BinaryNode) left(current);
   }
   node.setData(current.getData());
   if (behind != node) {
     behind.setLeft(right(current));
   } else {
     node.setRight(right(current));
   }
 }
  protected BinaryNode<T> remove(T value, BinaryNode<T> root) {
    if (root == null) {
      return null;
    }

    int compareResult = value.compareTo(root.getData());

    if (compareResult < 0) {
      root.setLeft(remove(value, root.getLeft()));
    } else if (compareResult > 0) {
      root.setRight(remove(value, root.getRight()));
    } else if (root.getLeft() != null && root.getRight() != null) {
      root.setData(findMin(root.getRight()));
      root.setRight(remove(root.getData(), root.getRight()));
    } else {
      root = root.getLeft() != null ? root.getLeft() : root.getRight();
    }

    return root;
  }
 private E addEntry(BinaryNode node, E entry) {
   E result = null;
   if (node.getData().compareTo(entry) == 0) {
     result = node.getData();
     node.setData(entry);
   } else if (entry.compareTo(node.getData()) < 0) {
     if (hasLeft(node)) {
       result = addEntry((BinaryNode) left(node), entry);
     } else {
       node.setLeft(new BinaryNode(entry));
       incSize();
     }
   } else {
     if (hasRight(node)) {
       result = addEntry((BinaryNode) right(node), entry);
     } else {
       node.setRight(new BinaryNode(entry));
       incSize();
     }
   }
   return result;
 }