protected BPlusTreeNode <TKey, TValue> GetRightSibling(bool mustHaveSameParent)
        {
            if (this.IsLeaf)
            {
                // use the rightsibling pointer
                BPlusTreeLeafNode <TKey, TValue> leaf = this as BPlusTreeLeafNode <TKey, TValue>;
                return(BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, leaf.RightSiblingLocation));
            }
            else
            {
                // look in parent for our smallest keyword, grab childlocation to the left of it
                int parentChildCount;
                int childLocationIndex = GetIndexInParent(out parentChildCount);

                if (childLocationIndex == -1)
                {
                    // never found the index, or no parent (aka root). No sibling to return.
                    return(null);
                }
                else
                {
                    if (childLocationIndex < parentChildCount - 1)
                    {
                        // we know the right sibling is attached to the same parent.
                        BPlusTreeNode <TKey, TValue> node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, Parent.ChildLocations[childLocationIndex + 1]);

                        return(node);
                    }
                    else
                    {
                        // we are the rightmost child, as we're at the location that's 1 past the fanout size
                        if (mustHaveSameParent)
                        {
                            // caller wants the sibling only if it's from the same parent, and it's not.
                            return(null);
                        }
                        else
                        {
                            // we have to find the common ancestor between this and its right sibling.
                            // spin up until we find the first node whose child index is <= Fanoutsize
                            // then drill down the leftmost path until we're at the same depth as we started at
                            int i = 0;
                            int nodeChildLocationIndex        = -1;
                            BPlusTreeNode <TKey, TValue> node = this;
                            while (node.Parent != null)
                            {
                                i++;

                                // keep bubbling up until we're at a node whose parent has at least one child to our right.
                                nodeChildLocationIndex = node.GetIndexInParent(out parentChildCount);
                                if (nodeChildLocationIndex < parentChildCount - 1)
                                {
                                    // this node is not the rightmost child of its parent.
                                    // we're done bubbling (node contains the ancestor node, nodeChildLocationIndex can tell us the subtree to search down)
                                    break;
                                }
                                else
                                {
                                    node = node.Parent;
                                }
                            }

                            if (nodeChildLocationIndex == parentChildCount - 1)
                            {
                                // the only common ancestor has our node being the rightmost node in the tree (at this depth).
                                return(null);
                            }


                            // ok, node contains the ancestor somehwere up the tree that has the node we're looking for as its
                            // leftmost descendent at the same depth.
                            // So we just keep drilling down the leftmost path until we're at the same depth.
                            node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, node as BPlusTreeIndexNode <TKey, TValue>, nodeChildLocationIndex + 1);

                            while (i > 0)
                            {
                                BPlusTreeIndexNode <TKey, TValue> indexNode = node as BPlusTreeIndexNode <TKey, TValue>;
                                node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, indexNode, indexNode.ChildLocations[0]);

                                i--;
                            }

                            // node now contains the right sibling!
                            return(node);
                        }
                    }
                }



                //// bounce up to the parent
                //if (Parent != null) {
                //    TKey ourKey = FirstKeyword;
                //    for (int i=0; i < Parent.Keywords.Count; i++) {
                //        TKey parentKeyword = Parent.Keywords[i];
                //        if (parentKeyword.CompareTo(ourKey, KeywordMatchMode.ExactMatch, false) == 0) {
                //            // follow right child
                //            BPlusTreeNode<TKey, TValue> node = BPlusTreeNode<TKey, TValue>.Read(this.Tree, this.Parent, Parent.ChildLocations[i+1]);
                //            return node;
                //        }
                //    }
                //}
                //return null;
            }
        }
        protected BPlusTreeNode <TKey, TValue> GetLeftSibling(bool mustHaveSameParent)
        {
            // look in parent for our smallest keyword, grab childlocation to the left of it

            int parentChildCount;
            int childLocationIndex = GetIndexInParent(out parentChildCount);

            if (childLocationIndex == -1)
            {
                // never found the index, or no parent (aka root). No sibling to return.
                return(null);
            }
            else
            {
                if (childLocationIndex == 0)
                {
                    if (mustHaveSameParent)
                    {
                        // caller wants the sibling only if it's from the same parent, and it's not.
                        return(null);
                    }
                    else
                    {
                        // we have to find the parent of our left sibling.
                        // spin up until we find the first node whose child index is > 0
                        // then drill down the rightmost path until we're at the same depth as we started at
                        int i = 0;
                        int nodeChildLocationIndex        = -1;
                        BPlusTreeNode <TKey, TValue> node = this;
                        while (node.Parent != null)
                        {
                            i++;

                            // keep bubbling up until we're at a node whose parent has at least one child to our left.
                            nodeChildLocationIndex = node.GetIndexInParent(out parentChildCount);
                            if (nodeChildLocationIndex > 0)
                            {
                                // this node is not the leftmost child of its parent.
                                // we're done bubbling (node contains the ancestor node, nodeChildLocationIndex can tell us the subtree to search down)
                                break;
                            }
                            else
                            {
                                node = node.Parent;
                            }
                        }

                        if (nodeChildLocationIndex == 0)
                        {
                            // the only common ancestor has our node being the leftmost node in the tree (at this depth).
                            return(null);
                        }

                        // ok, node contains the ancestor somehwere up the tree that has the node we're looking for as its
                        // rightmost descendent at the same depth.
                        // So we just keep drilling down until we're at the same depth.
                        node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, node as BPlusTreeIndexNode <TKey, TValue>, nodeChildLocationIndex - 1);

                        while (i > 0)
                        {
                            BPlusTreeIndexNode <TKey, TValue> indexNode = node as BPlusTreeIndexNode <TKey, TValue>;
                            node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, indexNode, indexNode.LastChildLocation);

                            i--;
                        }

                        // node now contains the left sibling!
                        return(node);
                    }
                }
                else
                {
                    // we know the left sibling is attached to the same parent.
                    BPlusTreeNode <TKey, TValue> node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, Parent.ChildLocations[childLocationIndex - 1]);

                    return(node);
                }
            }
        }