@Override
  public void delete(int delVal) {

    int numChildren = numChildren();

    // Root node
    if (this.parent == null && this.value == delVal && numChildren == 0) {
      this.hasValue = false;
      return;
    }

    if (value == delVal) {

      // System.out.println("Deleting " + value + " with numChildren = " + numChildren);
      if (numChildren == 2) {
        BinarySearchTree successor = children[RIGHT].findMin();
        this.value = successor.value;
        successor.delete(successor.value);
      } else if (numChildren == 1) {

        BinarySearchTree child = children[LEFT] != null ? children[LEFT] : children[RIGHT];
        // Check if root
        if (parent != null) {
          int directionFromParent = this.equals(parent.children[LEFT]) ? LEFT : RIGHT;
          parent.children[directionFromParent] = child;
        }

        child.parent = this.parent;
      } else {
        int directionFromParent = this.equals(parent.children[LEFT]) ? LEFT : RIGHT;
        parent.children[directionFromParent] = null;
        this.parent = null;
      }
    }

    int direction = delVal < value ? LEFT : RIGHT;
    BinarySearchTree child = children[direction];
    if (child != null) child.delete(delVal);
  }