* @param <code>target</code> the element to remove from the tree
   */
  protected BSTNode<E> remove( BSTNode<E> node, E target ) 
  {
    if ( node == null ) 
    { // element isn't in the tree : base case - failure
      return null;
    }

//        System.out.println("current node's element = " + node.element );

    int compareResult = target.compareTo( node.element );
    if ( compareResult < 0 ) 
    {
      node.leftChild = remove( node.leftChild, target ); // recursive case - left
    }
    else if ( compareResult > 0 ) 
    {
      node.rightChild = remove( node.rightChild, target ); // recursive case - right
    }
    else
    { // found it!                                   // base case - success
      this.size--;

      // handle the case of two children first
      if ( ( node.leftChild != null ) && ( node.rightChild != null ) ) 
      {
        BSTNode<E> replacement = successor( node );
        node.element = replacement.element;

        // now deal with removing the replacement
        BSTNode<E> newChild = replacement.leftChild == null ?
            replacement.rightChild : replacement.leftChild;
        if ( replacement == replacement.parent.leftChild ) 
        {
          replacement.parent.leftChild = newChild;
        }
        else 
        {
          replacement.parent.rightChild = newChild;
        }
      }
      else 
      { // Collapse the cases of no children and 1 child
        node = ( node.leftChild == null ) ? node.rightChild : node.leftChild;
      }
    }
    return node;
  }