private Node <T> BalanceOut(Node <T> node, AddedSide addedSide, AddedSide childAddedSide)
 {
     if (Math.Abs(Height(node.RightNode) - Height(node.LeftNode)) > 1)
     {
         if (addedSide == AddedSide.Left && childAddedSide == AddedSide.Left)
         {
             return(RotateWithLeftChild(node));
         }
         else if (addedSide == AddedSide.Left && childAddedSide == AddedSide.Right)
         {
             return(DoubleRotateWithLeftChild(node));
         }
         else if (addedSide == AddedSide.Right && childAddedSide == AddedSide.Left)
         {
             return(DoubleRotateWithRightChild(node));
         }
         else if (addedSide == AddedSide.Right && childAddedSide == AddedSide.Right)
         {
             return(RotateWithRightChild(node));
         }
         else
         {
             throw new Exception();
         }
     }
     else
     {
         return(node);
     }
 }
        public Node <T> Add(T data, Node <T> node, out AddedSide childAddedSide)
        {
            childAddedSide = default(AddedSide);
            if (node == null)
            {
                return(new Node <T>(data));
            }
            var compared  = data.CompareTo(node.Element);
            var addedSide = default(AddedSide);

            if (compared < 0)
            {
                node.LeftNode = Add(data, node.LeftNode, out childAddedSide);
                addedSide     = AddedSide.Left;
            }
            else if (compared > 0)
            {
                node.RightNode = Add(data, node.RightNode, out childAddedSide);
                addedSide      = AddedSide.Right;
            }
            else
            {
                throw new DuplicateItemException(data);
            }

            var retNode = BalanceOut(node, addedSide, childAddedSide);

            childAddedSide = addedSide;
            return(retNode);
        }