/// <summary>
        /// Try to find the node with the value
        /// </summary>
        /// <param name="value">the value to find</param>
        /// <param name="node">The resulting node. null if not found</param>
        /// <returns>true if the value was found</returns>
        public bool TryLocateNode(T value, out IOrderedNode <T> node)
        {
            var found = TryLocateInternalNode(value, out var internalNode);

            node = internalNode;
            return(found);
        }
 /// <summary>
 /// Remove a known node
 /// </summary>
 /// <param name="node">the node</param>
 public void RemoveNode(IOrderedNode <T> node)
 {
     if (node is Node nodeToDelete)
     {
         this.RemoveNode(nodeToDelete);
     }
     else
     {
         this.Remove(node.Data);
     }
 }
        /// <summary>
        /// Replace a known node with a value that would sort at the same position.
        /// </summary>
        /// <param name="node">the node</param>
        /// <param name="value">the new content</param>
        /// <returns>the new node</returns>
        public IOrderedNode <T> ReplaceNode(IOrderedNode <T> node, T value)
        {
            if (!(node is Node old))
            {
                this.Remove(node.Data);
                return(this.AddNode(value));
            }

            var newNode = new Node(value);

            this.ReplaceAtParent(old, newNode);
            newNode.SetLeftChild(old.Left);
            newNode.SetRightChild(old.Right);
            newNode.IsRed = old.IsRed;
            return(newNode);
        }