///<summary>Returns an editable view of all existing bounds that are overlapping or adjacent to the provided range.</summary>
        private SortedSet <BigIntRangeBound> GetOverlappingOrAdjacentBounds(BigInteger minimum, BigInteger maximum)
        {
            //To find adjacent ranges, just expand the new range by 1 on each side (and ensure
            //that all existing bounds at those points will be included, by making the lower
            //bound's direction as low as possible, and vice versa for the upper bound)
            var expandedMinimum = new BigIntRangeBound(minimum - 1, Direction.Down);
            var expandedMaximum = new BigIntRangeBound(maximum + 1, Direction.Up);

            return(_sortedSet.GetViewBetween(expandedMinimum, expandedMaximum));
        }
        //	public bool TryGetSurroundingRange(BigInteger x, out BigIntRange range) {
        //		//This is where using SortedSet doesn't work so well - ideally we'd be able to traverse
        //		//over the inner tree properly to do this search in O(log n) time (or if SortedSet had
        //		//'TryGetLessThan()' and 'TryGetGreaterThan()' methods in addition to TryGetValue()). Instead...
        //
        //		BigInteger? prevLowerBound = null; //only non-null when the previous bound has direction Direction.Up
        //		foreach (var bound in sortedBounds)
        //		{
        //			if (bound.Bound >= x)
        //			{
        //				if (bound.Direction == Direction.Nowhere) {
        //					if (prevLowerBound != null) throw new InvalidOperationException("Underlying sorted set of range bounds is corrupt - previous bound (at value " + prevLowerBound.Value + ") expected a matching closing bound next but current bound (at value " + bound.Bound + ") represents a single point.");
        //					range = BigIntRange.Single(bound.Bound);
        //					return true;
        //				}
        //				else if (bound.Direction == Direction.Up) {
        //					if (prevLowerBound != null) throw new InvalidOperationException("Underlying sorted set of range bounds is corrupt - previous bound (at value " + prevLowerBound.Value + ") expected a matching closing bound next but current bound (at value " + bound.Bound + ") represents the start of a new range.");
        //					range = default(BigIntRange);
        //					return false;
        //				}
        //				else {
        //					if (prevLowerBound == null) throw new InvalidOperationException("Underlying sorted set of range bounds is corrupt - current bound (at value " + bound.Bound + ") represents the end of a range, but the previous bound was a complete range or there was no previous bound");
        //					range = BigIntRange.CreateStartEnd(prevBound.Value, bound.Bound);
        //					return true;
        //				}
        //			}
        //			else
        //			{
        //				prevLowerBound = bound.Direction == Direction.Up ? bound : null;
        //			}
        //		}
        //
        //		range = default(BigIntRange);
        //		return false;
        //
        //		//	BigInteger? prevLowerBound = null;
        //		//	foreach (var bound in _sortedSet) {
        //		//		if (bound.Bound >= x) {
        //		//			if (bound.Direction == Direction.Nowhere) {
        //		//				if (prevLowerBound != null) todo;
        //		//				range = BigIntRange.CreateStartEnd(start: prevLowerBound.Value, end: bound);
        //		//				return true;
        //		//			} else if (bound.Direction == Direction.Down) {
        //		//				if (prevLowerBound != null) todo;
        //		//				range = BigIntRange.CreateStartEnd(start: prevLowerBound.Value, end: bound);
        //		//				return true;
        //		//			}
        //		//			else {
        //		//				if (prevLowerBound !=
        //		//				range = default(BigIntRange);
        //		//				return false;
        //		//			}
        //		//		}
        //		//
        //		//	}
        //	}

        private bool TryGetSurroundingBounds(BigInteger x, out BigIntRangeBound below, out BigIntRangeBound above)
        {
            //This is where using SortedSet doesn't work so well - ideally we'd be able to traverse
            //over the inner tree properly to do this search in O(log n) time (or if SortedSet had
            //'TryGetLessThan()' and 'TryGetGreaterThan()' methods in addition to TryGetValue()). Instead...

            BigIntRangeBound?prevBound = null;

            foreach (var bound in _sortedSet)
            {
                if (bound.Bound <= x)
                {
                    if (bound.Direction == Direction.Nowhere)
                    {
                        below = bound;
                        above = bound;
                        return(true);
                    }
                    else
                    {
                        prevBound = bound;
                    }
                }
                else
                {
                    if (prevBound == null)
                    {
                        below = default(BigIntRangeBound);
                        above = default(BigIntRangeBound);
                        return(false);
                    }
                    else
                    {
                        below = prevBound.Value;
                        above = bound;
                        return(true);
                    }
                }
            }

            below = default(BigIntRangeBound);
            above = default(BigIntRangeBound);
            return(false);
        }