private int CalculateOrder()
            {
                AugmentedTreeNode rightSubtreeRoot = FindRightSubtreeRoot();

                return((Left?.NumberOfNodesInSubtree ?? 0) +
                       (rightSubtreeRoot?.Order ?? 0) + 1);
            }
        public int KthSmallest(TreeNode root, int k)
        {
            AugmentedTreeNode augmentedRoot = AugmentedTreeNode.CreateAugmentedTreeNode(root, null, false);

            AugmentedTreeNode currentNode = augmentedRoot;

            while (currentNode.Order != k)
            {
                currentNode = currentNode.Order > k ? currentNode.Left : currentNode.Right;
            }

            return(currentNode.Value);
        }
            public static AugmentedTreeNode CreateAugmentedTreeNode(TreeNode simpleNode, AugmentedTreeNode parentNode, bool isLeftChild)
            {
                if (simpleNode == null)
                {
                    return(null);
                }

                AugmentedTreeNode current = new AugmentedTreeNode();

                current.Parent      = parentNode;
                current.IsRoot      = parentNode == null;
                current.Value       = simpleNode.val;
                current.Left        = CreateAugmentedTreeNode(simpleNode.left, current, true);
                current.Right       = CreateAugmentedTreeNode(simpleNode.right, current, false);
                current.IsLeftChild = isLeftChild;
                current.CalculateNodesInSubtree();

                return(current);
            }
            private AugmentedTreeNode FindRightSubtreeRoot()
            {
                if (IsRoot)
                {
                    return(null);
                }

                if (!IsLeftChild)
                {
                    return(Parent);
                }

                AugmentedTreeNode currentParent = Parent;

                while (!currentParent.IsRoot && currentParent.IsLeftChild)
                {
                    currentParent = currentParent.Parent;
                }

                return(currentParent.IsRoot ? null : currentParent.Parent);
            }