public static void TestCompositeRangeArgsOrderWithKeys()
        {
            var seek = new Random().Next();

            Console.WriteLine(
                $"{MethodBase.GetCurrentMethod().Name}: Rnd seek: {seek} (use the seek to reproduce test results).");
            var rnd = new Random(seek);

            var emtpy    = Range.Create(RangeBoundaryFrom <int> .Empty, RangeBoundaryTo <int> .Empty, "E");
            var infinite = Range.Create(
                RangeBoundaryFrom <int> .NegativeInfinity,
                RangeBoundaryTo <int> .PositiveInfinity, "I");
            // Equal ranges should use same keys to provide repeatable results after
            // ranges array will be shuffled.
            var ranges = new[]
            {
                emtpy,
                Range.Create(1, 2, "A"),
                Range.Create(1, 2, "A"),
                Range.Create(3, 4, "B"),
                Range.Create(3, 5, "C"),
                emtpy,
                emtpy,
                emtpy,
                Range.CreateExclusive(4, 6, "D"),
                Range.CreateExclusiveTo(7, 8, "F"),
                Range.CreateExclusiveTo(3, 5, "G"),
                Range.CreateExclusive(3, 5, "H"),
                Range.CreateExclusiveFrom(3, 5, "K"),
                Range.Create(0, 6, (string)null),
                emtpy,
                emtpy,
                infinite
            };

            var compositeRange = new CompositeRange <int, string>(ranges);

            AreEqual(
                compositeRange.ToString(),
                "(-∞..+∞): { 'I':(-∞..+∞); '':[0..6]; 'A':[1..2]; 'A':[1..2]; 'B':[3..4]; " +
                "'G':[3..5); 'C':[3..5]; 'H':(3..5); 'K':(3..5]; 'D':(4..6); 'F':[7..8) }");

            compositeRange = new CompositeRange <int, string>(ranges.OrderBy(r => rnd.Next()));
            AreEqual(
                compositeRange.ToString(),
                "(-∞..+∞): { 'I':(-∞..+∞); '':[0..6]; 'A':[1..2]; 'A':[1..2]; 'B':[3..4]; " +
                "'G':[3..5); 'C':[3..5]; 'H':(3..5); 'K':(3..5]; 'D':(4..6); 'F':[7..8) }");

            compositeRange = new CompositeRange <int, string>(ranges.Take(ranges.Length - 1));
            AreEqual(
                compositeRange.ToString(),
                "[0..8): { '':[0..6]; 'A':[1..2]; 'A':[1..2]; 'B':[3..4]; " +
                "'G':[3..5); 'C':[3..5]; 'H':(3..5); 'K':(3..5]; 'D':(4..6); 'F':[7..8) }");

            compositeRange = new CompositeRange <int, string>(ranges.Take(ranges.Length - 1).OrderBy(r => rnd.Next()));
            AreEqual(
                compositeRange.ToString(),
                "[0..8): { '':[0..6]; 'A':[1..2]; 'A':[1..2]; 'B':[3..4]; " +
                "'G':[3..5); 'C':[3..5]; 'H':(3..5); 'K':(3..5]; 'D':(4..6); 'F':[7..8) }");

            compositeRange = new CompositeRange <int, string>(ranges.Last());
            AreEqual(compositeRange.ToString(), "(-∞..+∞): { 'I':(-∞..+∞) }");

            compositeRange = new CompositeRange <int, string>(ranges.First());
            AreEqual(compositeRange.ToString(), "∅");

            compositeRange = new CompositeRange <int, string>(ranges.Take(0));
            AreEqual(compositeRange.ToString(), "∅");

            compositeRange = new CompositeRange <int, string>();
            AreEqual(compositeRange.ToString(), "∅");
        }
        public static void TestCompositeRangEqualsWithKeysComplex()
        {
            var ranges = new[]
            {
                Range.Create(0, 1, "X"),
                Range.Create(0, 1, "Y"),
                Range.Create(1, 1, "Z"),
                Range.Create(1, 2, "A"),
                Range.Create(1, 2, "B"),
                Range.Create(1, 2, "C"),
                Range.Create(1, 2, "B"),
                Range.Create(2, 3, "X"),
                Range.Create(2, 3, "Y"),
                Range.Create(2, 2, "Z")
            };
            var ranges3 = new[]
            {
                Range.Create(0, 1, "X"),
                Range.Create(0, 1, "Y"),
                Range.Create(1, 1, "Z"),
                Range.Create(1, 2, "A"),
                Range.Create(1, 2, "B"),
                Range.Create(1, 2, "C"),
                Range.Create(1, 2, "B"),
                Range.Create(2, 3, "Y2"),
                Range.Create(2, 3, "Y2"),
                Range.Create(2, 2, "Z")
            };
            var ranges4 = new[]
            {
                Range.Create(0, 1, "X"),
                Range.Create(0, 1, "Y"),
                Range.Create(1, 1, "Z"),
                Range.Create(1, 2, "A"),
                Range.Create(1, 2, "A"),
                Range.Create(1, 2, "B"),
                Range.Create(1, 2, "C"),
                Range.Create(2, 3, "X"),
                Range.Create(2, 3, "Y"),
                Range.Create(2, 2, "Z")
            };

            var ranges2 = ranges.Reverse().ToArray();

            var compositeRange  = new CompositeRange <int, string>(ranges);
            var compositeRange2 = new CompositeRange <int, string>(ranges2);
            var compositeRange3 = new CompositeRange <int, string>(ranges3);
            var compositeRange4 = new CompositeRange <int, string>(ranges4);

            AreEqual(
                compositeRange.ToString(),
                "[0..3]: { 'X':[0..1]; 'Y':[0..1]; 'Z':[1..1]; 'A':[1..2]; 'B':[1..2]; 'C':[1..2]; 'B':[1..2]; 'Z':[2..2]; 'X':[2..3]; 'Y':[2..3] }");
            AreEqual(
                compositeRange2.ToString(),
                "[0..3]: { 'Y':[0..1]; 'X':[0..1]; 'Z':[1..1]; 'B':[1..2]; 'C':[1..2]; 'B':[1..2]; 'A':[1..2]; 'Z':[2..2]; 'Y':[2..3]; 'X':[2..3] }");
            AreEqual(
                compositeRange3.ToString(),
                "[0..3]: { 'X':[0..1]; 'Y':[0..1]; 'Z':[1..1]; 'A':[1..2]; 'B':[1..2]; 'C':[1..2]; 'B':[1..2]; 'Z':[2..2]; 'Y2':[2..3]; 'Y2':[2..3] }");
            AreEqual(
                compositeRange4.ToString(),
                "[0..3]: { 'X':[0..1]; 'Y':[0..1]; 'Z':[1..1]; 'A':[1..2]; 'A':[1..2]; 'B':[1..2]; 'C':[1..2]; 'Z':[2..2]; 'X':[2..3]; 'Y':[2..3] }");

            AreEqual(compositeRange, compositeRange);
            AreEqual(compositeRange2, compositeRange2);
            AreEqual(compositeRange3, compositeRange3);
            AreEqual(compositeRange4, compositeRange4);

            AreEqual(compositeRange, compositeRange2);
            AreNotEqual(compositeRange, compositeRange3);
            AreNotEqual(compositeRange, compositeRange4);
            AreNotEqual(compositeRange2, compositeRange3);
            AreNotEqual(compositeRange2, compositeRange4);
            AreNotEqual(compositeRange3, compositeRange4);
        }
        public static void TestCompositeRangeArgsOrder()
        {
            var seek = new Random().Next();

            Console.WriteLine(
                $"{MethodBase.GetCurrentMethod().Name}: Rnd seek: {seek} (use the seek to reproduce test results).");
            var rnd = new Random(seek);

            var ranges = new[]
            {
                Range <int> .Empty,
                Range.Create(1, 2),
                Range.Create(1, 2),
                Range.Create(3, 4),
                Range.Create(3, 5),
                Range <int> .Empty,
                Range <int> .Empty,
                Range <int> .Empty,
                Range.CreateExclusive(4, 6),
                Range.CreateExclusiveTo(7, 8),
                Range.CreateExclusiveTo(3, 5),
                Range.CreateExclusive(3, 5),
                Range.CreateExclusiveFrom(3, 5),
                Range.Create(0, 6),
                Range <int> .Empty,
                Range <int> .Empty,
                Range <int> .Infinite
            };

            var compositeRange = new CompositeRange <int>(ranges);

            AreEqual(
                compositeRange.ToString(),
                "(-∞..+∞): { (-∞..+∞); [0..6]; [1..2]; [1..2]; [3..4]; [3..5); [3..5]; (3..5); (3..5]; (4..6); [7..8) }");

            compositeRange = ranges.OrderBy(r => rnd.Next()).ToCompositeRange();
            AreEqual(
                compositeRange.ToString(),
                "(-∞..+∞): { (-∞..+∞); [0..6]; [1..2]; [1..2]; [3..4]; [3..5); [3..5]; (3..5); (3..5]; (4..6); [7..8) }");

            compositeRange = ranges.Take(ranges.Length - 1).ToCompositeRange();
            AreEqual(
                compositeRange.ToString(),
                "[0..8): { [0..6]; [1..2]; [1..2]; [3..4]; [3..5); [3..5]; (3..5); (3..5]; (4..6); [7..8) }");

            compositeRange = ranges.Take(ranges.Length - 1).OrderBy(r => rnd.Next()).ToCompositeRange();
            AreEqual(
                compositeRange.ToString(),
                "[0..8): { [0..6]; [1..2]; [1..2]; [3..4]; [3..5); [3..5]; (3..5); (3..5]; (4..6); [7..8) }");

            compositeRange = new CompositeRange <int>(ranges.Last());
            AreEqual(compositeRange.ToString(), "(-∞..+∞): { (-∞..+∞) }");

            compositeRange = new CompositeRange <int>(ranges.First());
            AreEqual(compositeRange.ToString(), "∅");

            compositeRange = new CompositeRange <int>(ranges.Take(0));
            AreEqual(compositeRange.ToString(), "∅");

            compositeRange = new CompositeRange <int>();
            AreEqual(compositeRange.ToString(), "∅");
        }