public BalancedBoundingNode Insert(TBounds lower, TBounds upper, TPayload value)
            {
                if (lower.CompareTo(upper) > 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(lower), $"lower ({lower}) needs to be <= upper ({upper})");
                }

                if (upper.CompareTo(LowerBound) <= 0)
                {
                    if (ReferenceEquals(LowerTree, Nil))
                    {
                        LowerTree = new BalancedBoundingNode(lower, upper, value, Colour.Black)
                        {
                            Parent = this
                        };
                        return(LowerTree);
                    }
                    return(LowerTree.Insert(lower, upper, value));
                }

                if (lower.CompareTo(UpperBound) >= 0)
                {
                    if (ReferenceEquals(UpperTree, Nil))
                    {
                        UpperTree = new BalancedBoundingNode(lower, upper, value, Colour.Black)
                        {
                            Parent = this
                        };
                        return(UpperTree);
                    }
                    return(UpperTree.Insert(lower, upper, value));
                }

                throw new ArgumentOutOfRangeException($"Lower {lower} and upper {upper} overlap with this tree l:{LowerBound},u:{UpperBound}");
            }
            public void WalkTree(Action <BalancedBoundingNode> action)
            {
                if (action == null)
                {
                    return;
                }

                LowerTree?.WalkTree(action);
                action(this);
                UpperTree?.WalkTree(action);
            }