public static TreeNode inorderSuccessor(TreeNode n) {
        if (n == null) return null;

        // case 1: n has right subtree ->
        //         return leftmost node of right subtree
        if (n.right != null) return leftmostChild(n.right);

        // case 2:   n has no right subtree
        // case 2.1: n is left child of its parent ->
        //           just return its parent
        // case 2.2: n is right child of its parent ->
        //           n goes up until n is left child of its parent,
        //           then return this parent
        // case 3:   n is the last node in traversal ->
        //           return root's parent, ie., null
        while (n.parent != null && n.parent.right == n) {
            n = n.parent; 
        }
        return n.parent;
    }