public void Balance()
		{
			Queue<IComparable> treeData = GetIorderQueue();
			nodeData = treeData.ToArray();
			root = null; // delete old tree and then start all over again
			balanceInsert(0, nodeData.Length - 1);
		}
		private static bool recIsBst(BSTNode node, int min, int max)
		{
			//an empty tree is an BST
			if (node == null) return true;

			if (node.data.CompareTo(min) < 0 || node.data.CompareTo(max) > 0)
				return false;

			return recIsBst(node.left, min, (int) node.data) && recIsBst(node.right, (int) node.data + 1, max) ;
		}
		private static int checkHeight(BSTNode node)
		{
			if (node == null) return 0; //height of 0

			int leftHeight = checkHeight(node.left);
			if (leftHeight == -1) return -1; // not balanced

			int rightHeight = checkHeight(node.right);
			if (rightHeight == -1) return -1; // not balanced

			int heightDiff = leftHeight - rightHeight; // check if current node is balanced
			if (Math.Abs(heightDiff) > 1) 
				return -1;
			return Math.Max(leftHeight, rightHeight) + 1; //return height

		}
        private static BSTNode recInsert(IComparable item, BSTNode tree)
        {
            if (tree == null)
            {
                tree = new BSTNode {left = null, right = null, info = item};
            }
            else if (item.CompareTo(tree.info) < 0)
            {
                tree.left = recInsert(item, tree.left); //insert at the left
            }
            else
            {
                tree.right = recInsert(item, tree.right); // insert at right
            }

            return tree;
        }
        private static int recNumberOfNodes(BSTNode tree)
        {
            //return tree == null ? 0 : recNumberOfNodes(tree.left) + recNumberOfNodes(tree.right) + 1;

            if (tree == null)
                return 0;
            else if (tree.left == null && tree.right == null)
                return 1;
            else if (tree.left == null)
            {
                return recNumberOfNodes(tree.right) + 1; //search right of sub tree
            }
            else if (tree.right == null)
            {
                return recNumberOfNodes(tree.left) + 1; //search left of sub tree
            }
            else
            {   //both left and right are present
                return recNumberOfNodes(tree.left) + recNumberOfNodes(tree.right) + 1;
            }
        }
 public void Insert(IComparable item)
 {
     root = recInsert(item, root);
 }
 private IComparable recRetrive(IComparable item, BSTNode tree)
 {
     if (item.CompareTo(tree.info) < 0)
         return recRetrive(item, tree.left);
     else if (item.CompareTo(tree.info) > 0)
         return recRetrive(item, tree.right);
     else
         return tree.info;
 }
 public BST()
 {
     root = null;
 }
		private static BSTNode recInsert(BSTNode node, IComparable item)
		{
			if (node == null)  //base case
				return new BSTNode {data = item};

			if (item.CompareTo(node.data) < 0) //go to left 
				node.left = recInsert(node.left, item);

			if (item.CompareTo(node.data) > 0) // go to right
				node.right = recInsert(node.right, item);

			return node;
		}
 private bool recIsThere(IComparable item, BSTNode tree)
 {
     if (tree == null)
         return false;
     if (item.CompareTo(tree.info) < 0)
         return recIsThere(item, tree.left);
     else if (item.CompareTo(tree.info) > 0)
         return recIsThere(item, tree.right);
     else
         return true;
 }
		private BSTNode deleteNode(BSTNode tree)
		{
			if (tree.right == null && tree.left == null) // delete the leaf node
				return null;
			else if (tree.left == null) // node to be delete doesnt have left child so return right one
				return tree.right;
			else if (tree.right == null) // no right child so return left
				return tree.left;
			else
			{
				IComparable temp = getDescendentValue(tree.left); // get data to be replaced
				tree.data = temp; // copy that data 
				tree.left = recDelete(temp, tree.left);
				return tree;
			}
		}
		private BSTNode recDelete(IComparable item, BSTNode tree)
		{
			if (item.CompareTo(tree.data) < 0) // go left
				tree.left = recDelete(item, tree.left);
			else if (item.CompareTo(tree.data) > 0) // go right
				tree.right = recDelete(item, tree.right);
			else
				tree = deleteNode(tree); // found the node .. so go ahead and delete it

			return tree;
		}
		private void inOrder(BSTNode tree)
		{
			if (tree == null) return;
			inOrder(tree.left);
			inOrderQueue.Enqueue(tree.data);
			inOrder(tree.right);
		}
		public void Insert(IComparable item)
		{
			root = recInsert(root, item);
		}
		private static void printPath(IComparable[] toPrintNodes, BSTNode tree, int len)
		{
			if (tree == null) return;
			toPrintNodes[len] = tree.data;
			len++;
			if (tree.left == null && tree.right == null)
				printTree(toPrintNodes, len);
			else
			{
				printPath(toPrintNodes, tree.left, len);
				printPath(toPrintNodes, tree.right, len);
			}
		}
		private static int find_NodeLevel(BSTNode tree, IComparable item)
		{
			int level = 0;

			while (tree != null)
			{
				if (item.CompareTo(tree.data) == 0)
					return level++;
				if (item.CompareTo(tree.data) < 0) // if item less go left
				{
					tree = tree.left;
					level++;
				}
				else if (item.CompareTo(tree.data) > 0) // go right
				{
					tree = tree.right;
					level++;
				}
			}

			return level;
		}
		private static IComparable getDescendentValue(BSTNode tree)
		{
			while (tree.right != null)
			{
				tree = tree.right;
			}

			return tree.data;
		}
		public void Delete(IComparable item)
		{
			root = recDelete(item, root);
		}
		public BinarySearchTree()
		{
			root = null;
		}