// Removes an element with a given
        // key value from the tree
        public void prune(Key key)
        {
            // If the given key does not exist in
            // the binary search tree, no action is
            // needed.
            if (has(key))
            {
                bool latch = true;
                TreeElement <Key, Value> keyElement  = firstElement;
                TreeElement <Key, Value> parentOfKey = firstElement;
                bool keyOnRight = false;
                // Loops until an element with the given
                // key value is found.  Keeps track of
                // the element this element is immediately
                // below
                while (latch)
                {
                    if (0 == compare(keyElement.key, key))
                    {
                        latch = false;
                    }
                    else if (0 < compare(keyElement.key, key))
                    {
                        if (keyElement.hasLeft)
                        {
                            parentOfKey = keyElement;
                            keyOnRight  = false;
                            keyElement.onLeft--;
                            keyElement = keyElement.leftBranch;
                        }
                        else
                        {
                            latch = false;
                        }
                    }
                    else
                    {
                        if (keyElement.hasRight)
                        {
                            parentOfKey = keyElement;
                            keyOnRight  = true;
                            keyElement  = keyElement.rightBranch;
                        }
                        else
                        {
                            latch = false;
                        }
                    }
                }

                if (0 == compare(keyElement.key, key))
                {
                    numberOfElements--;
                    if (keyElement.hasRight)
                    {
                        TreeElement <Key, Value> swapKeyFor = keyElement.rightBranch;
                        latch = true;
                        // Finds the element with the lowest
                        // key on the right branch of the
                        // binary search tree
                        while (swapKeyFor.hasLeft)
                        {
                            swapKeyFor.onLeft--;
                            if (false == swapKeyFor.leftBranch.hasLeft)
                            {
                                // The current element referenced by
                                // swapKeyFor will have its left element
                                // removed.
                                swapKeyFor.hasLeft = false;
                            }
                            swapKeyFor = swapKeyFor.leftBranch;
                        }

                        TreeElement <Key, Value> pushRightTo = swapKeyFor;
                        // Finds the element with the highest
                        // key on the right branch of swapKeyFor;
                        // the right element of the element to
                        // be removed will be assigned to this
                        // element.
                        while (pushRightTo.hasRight)
                        {
                            pushRightTo = pushRightTo.rightBranch;
                        }
                        pushRightTo.rightBranch = keyElement.rightBranch;
                        swapKeyFor.onLeft       = keyElement.onLeft;
                        swapKeyFor.leftBranch   = keyElement.leftBranch;
                        if (0 == compare(parentOfKey.key, keyElement.key))
                        {
                            firstElement = swapKeyFor;
                        }
                        else if (keyOnRight)
                        {
                            parentOfKey.rightBranch = swapKeyFor;
                        }
                        else
                        {
                            parentOfKey.leftBranch = swapKeyFor;
                        }
                    }
                    else if (keyElement.hasLeft)
                    {
                        parentOfKey.leftBranch = keyElement.leftBranch;
                    }
                    else
                    {
                        parentOfKey.hasLeft = false;
                    }
                }
            }
        }
        // Adds an element with the specified
        // key-value pair to the tree
        public void add(Key key, Value value)
        {
            // No element has a negative index - this
            // effectively reset indexRequestedLast
            indexRequestedLast = -1;

            // If no elements have been added to the
            // binary search tree, the key-value pair
            // is added as the first element
            if (0 == numberOfElements)
            {
                firstElement = new TreeElement <Key, Value>(key, value);
                numberOfElements++;
            }

            // If the given key matches the key of the
            // previously located element, its value
            // is simply added to the binary search
            // tree
            else if (null != foundLast && 0 == compare(foundLast.key, key))
            {
                foundLast.value = value;
            }

            // If the given key already exists in the binary
            // search tree, its value is set to the
            // given value
            else if (has(key))
            {
                foundLast.value = value;
            }
            else
            {
                bool latch = true;
                TreeElement <Key, Value> scanning = firstElement;
                while (latch)
                {
                    if (0 < compare(scanning.key, key))
                    {
                        scanning.onLeft++;
                        if (scanning.hasLeft)
                        {
                            scanning = scanning.leftBranch;
                        }
                        else
                        {
                            scanning.leftBranch = new TreeElement <Key, Value>(key, value);
                            latch = false;
                        }
                    }
                    else
                    {
                        if (scanning.hasRight)
                        {
                            scanning = scanning.rightBranch;
                        }
                        else
                        {
                            scanning.rightBranch = new TreeElement <Key, Value>(key, value);
                            latch = false;
                        }
                    }
                }
                numberOfElements++;
            }
        }