/// <summary>
        /// Applies a folding function to the list of intervals.
        /// </summary>
        /// <typeparam name="T">The type of value being folded.</typeparam>
        /// <param name="xs">The first list of intervals.</param>
        /// <param name="ys">The second list of intervals.</param>
        /// <param name="initial">The initial value.</param>
        /// <param name="fold">The folding function.</param>
        /// <param name="final">The final fold function.</param>
        /// <returns>The resulting value.</returns>
        private static T Fold <T>(IReadOnlyList <int> xs, IReadOnlyList <int> ys, T initial, IntervalFold <T> fold, IntervalFinalFold <T> final)
        {
            #region Contract
            Debug.Assert(xs != null);
            Debug.Assert(ys != null);
            Debug.Assert(fold != null);
            Debug.Assert(final != null);
            #endregion

            T current = initial;

            // Neither lists has any elements, so we'll return.
            if (xs.Count == 0 && ys.Count == 0)
            {
                return(current);
            }

            // Indices point to the elements in the lists that are greater than or equal to `cursor`.
            int xi = 0;
            int yi = 0;
            // The cursor is the current position.
            int comparison = CompareIntervals(xs, ys, xi, yi, out int cursor);
            if (comparison <= 0)
            {
                xi += 1;
            }
            if (comparison >= 0)
            {
                yi += 1;
            }

            while (xi < xs.Count || yi < ys.Count)
            {
                comparison = CompareIntervals(xs, ys, xi, yi, out int nextCursor);

                int  start = cursor;
                int  end   = nextCursor;
                bool hasX  = (xi % 2) != 0;
                bool hasY  = (yi % 2) != 0;
                current = fold(start, end, hasX, hasY, current);

                if (comparison <= 0)
                {
                    xi += 1;
                }
                if (comparison >= 0)
                {
                    yi += 1;
                }
                cursor = nextCursor;
            }

            current = final(cursor, current);

            return(current);
        }
 /// <summary>
 /// Applies a folding function to the list of intervals.
 /// </summary>
 /// <typeparam name="T">The type of value being folded.</typeparam>
 /// <param name="xs">The first list of intervals.</param>
 /// <param name="ys">The second list of intervals.</param>
 /// <param name="initial">The initial value.</param>
 /// <param name="fold">The folding function.</param>
 /// <returns>The resulting value.</returns>
 private static T Fold <T>(IReadOnlyList <int> xs, IReadOnlyList <int> ys, T initial, IntervalFold <T> fold)
 => Fold(xs, ys, initial, fold, (_, v) => v);