public void TestCollectionConstructorUsesCorrectComparer()
        {
            var key1 = new StrongBox <int>(1);
            var key2 = new StrongBox <int>(2);

            KeyValuePair <StrongBox <int>, int>[] pairs =
            {
                new KeyValuePair <StrongBox <int>, int>(key1, 1),
                new KeyValuePair <StrongBox <int>, int>(key2, 2),
            };

            var comparer         = new ComparisonComparer <StrongBox <int> >((x, y) => Comparer <int> .Default.Compare(x.Value, y.Value));
            var objectDictionary = ImmutableSortedTreeDictionary.CreateRange(comparer, pairs);

            Assert.Same(comparer, objectDictionary.KeyComparer);
            Assert.Equal(2, objectDictionary.Count);
            Assert.Equal(new[] { new KeyValuePair <StrongBox <int>, int>(key1, 1), new KeyValuePair <StrongBox <int>, int>(key2, 2) }, objectDictionary);

            var stringDictionary = ImmutableSortedTreeDictionary.Create <string, int>();

            Assert.Same(Comparer <string> .Default, stringDictionary.KeyComparer);

            stringDictionary = ImmutableSortedTreeDictionary.Create <string, int>(StringComparer.OrdinalIgnoreCase);
            Assert.Same(StringComparer.OrdinalIgnoreCase, stringDictionary.KeyComparer);

            KeyValuePair <StrongBox <int>, int>[] pairsWithDuplicateKey =
            {
                new KeyValuePair <StrongBox <int>, int>(key1, 1),
                new KeyValuePair <StrongBox <int>, int>(key2, 2),
                new KeyValuePair <StrongBox <int>, int>(key1, 3),
            };

            Assert.Throws <ArgumentException>(() => ImmutableSortedTreeDictionary.CreateRange(comparer, pairsWithDuplicateKey));
        }
        public void TestImmutableSortedTreeDictionaryCreateRange()
        {
            KeyValuePair <string, int>[] pairs =
            {
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
            };

            var dictionary = ImmutableSortedTreeDictionary.CreateRange(pairs);

            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);
        }
        public void TestMultipleElementDictionary()
        {
            KeyValuePair <string, int>[] pairs =
            {
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
                new KeyValuePair <string, int>(Generator.GetInt32().ToString(), Generator.GetInt32()),
            };

            // Construction using ImmutableSortedTreeDictionary.Create
            var dictionary = ImmutableSortedTreeDictionary.CreateRange(pairs);

            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = ImmutableSortedTreeDictionary.CreateRange <string, int>(keyComparer: null, pairs);
            Assert.Same(Comparer <string> .Default, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = ImmutableSortedTreeDictionary.CreateRange(StringComparer.OrdinalIgnoreCase, pairs);
            Assert.Same(StringComparer.OrdinalIgnoreCase, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, new KeyOfPairComparer <string, int>(StringComparer.OrdinalIgnoreCase)), dictionary);

            // Construction using ImmutableSortedTreeDictionary.ToImmutableSortedTreeDictionary
            dictionary = pairs.ToImmutableSortedTreeDictionary();
            Assert.Same(Comparer <string> .Default, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = pairs.ToImmutableSortedTreeDictionary(keyComparer: null);
            Assert.Same(Comparer <string> .Default, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = pairs.ToImmutableSortedTreeDictionary(StringComparer.OrdinalIgnoreCase);
            Assert.Same(StringComparer.OrdinalIgnoreCase, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, new KeyOfPairComparer <string, int>(StringComparer.OrdinalIgnoreCase)), dictionary);

            // Construction using ImmutableSortedTreeDictionary.ToImmutableSortedTreeDictionary, where the source is already an
            // ImmutableSortedTreeDictionary<TKey, TValue>
            dictionary = pairs.ToImmutableSortedTreeDictionary().ToImmutableSortedTreeDictionary();
            Assert.Same(Comparer <string> .Default, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = pairs.ToImmutableSortedTreeDictionary().ToImmutableSortedTreeDictionary(keyComparer: null);
            Assert.Same(Comparer <string> .Default, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, KeyOfPairComparer <string, int> .Default), dictionary);

            dictionary = pairs.ToImmutableSortedTreeDictionary().ToImmutableSortedTreeDictionary(StringComparer.OrdinalIgnoreCase);
            Assert.Same(StringComparer.OrdinalIgnoreCase, dictionary.KeyComparer);
            Assert.Equal(pairs.OrderBy(x => x, new KeyOfPairComparer <string, int>(StringComparer.OrdinalIgnoreCase)), dictionary);
        }
        public void TestImmutableSortedTreeDictionaryCreateRangeValidation()
        {
            Assert.Throws <ArgumentNullException>("items", () => ImmutableSortedTreeDictionary.CreateRange <string, int>(null !));
            Assert.Throws <ArgumentNullException>("items", () => ImmutableSortedTreeDictionary.CreateRange <string, int>(Comparer <string> .Default, null !));
            Assert.Throws <ArgumentNullException>("items", () => ImmutableSortedTreeDictionary.CreateRange <string, int>(Comparer <string> .Default, EqualityComparer <int> .Default, null !));

            Assert.Throws <ArgumentNullException>("items", () => default(IEnumerable <KeyValuePair <string, int> >) !.ToImmutableSortedTreeDictionary());
            Assert.Throws <ArgumentNullException>("items", () => default(IEnumerable <KeyValuePair <string, int> >) !.ToImmutableSortedTreeDictionary(Comparer <string> .Default));
            Assert.Throws <ArgumentNullException>("items", () => default(IEnumerable <KeyValuePair <string, int> >) !.ToImmutableSortedTreeDictionary(Comparer <string> .Default, EqualityComparer <int> .Default));
            Assert.Throws <ArgumentNullException>("source", () => default(IEnumerable <KeyValuePair <string, int> >) !.ToImmutableSortedTreeDictionary(x => x.Key, x => x.Value, Comparer <string> .Default));
            Assert.Throws <ArgumentNullException>("source", () => default(IEnumerable <KeyValuePair <string, int> >) !.ToImmutableSortedTreeDictionary(x => x.Key, x => x.Value, Comparer <string> .Default, EqualityComparer <int> .Default));

            Assert.Throws <ArgumentNullException>("keySelector", () => Enumerable.Empty <KeyValuePair <string, int> >().ToImmutableSortedTreeDictionary(keySelector: null !, x => x.Value, Comparer <string> .Default));
            Assert.Throws <ArgumentNullException>("keySelector", () => Enumerable.Empty <KeyValuePair <string, int> >().ToImmutableSortedTreeDictionary(keySelector: null !, x => x.Value, Comparer <string> .Default, EqualityComparer <int> .Default));

            Assert.Throws <ArgumentNullException>("elementSelector", () => Enumerable.Empty <KeyValuePair <string, int> >().ToImmutableSortedTreeDictionary <KeyValuePair <string, int>, string, int>(x => x.Key, elementSelector: null !, Comparer <string> .Default));
            Assert.Throws <ArgumentNullException>("elementSelector", () => Enumerable.Empty <KeyValuePair <string, int> >().ToImmutableSortedTreeDictionary(x => x.Key, elementSelector: null !, Comparer <string> .Default, EqualityComparer <int> .Default));
        }
        public void TestDefaultComparer()
        {
            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>().KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>().ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>().KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>().ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>().KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>().ValueComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(Enumerable.Empty <KeyValuePair <object, object> >()).KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(Enumerable.Empty <KeyValuePair <object, object> >()).ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(Enumerable.Empty <KeyValuePair <int, int> >()).KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(Enumerable.Empty <KeyValuePair <int, int> >()).ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).ValueComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null).ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>(keyComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>(keyComparer: null).ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>(keyComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>(keyComparer: null).ValueComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(keyComparer: null, Enumerable.Empty <KeyValuePair <object, object> >()).KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(keyComparer: null, Enumerable.Empty <KeyValuePair <object, object> >()).ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(keyComparer: null, Enumerable.Empty <KeyValuePair <int, int> >()).KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(keyComparer: null, Enumerable.Empty <KeyValuePair <int, int> >()).ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(keyComparer: null, Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(keyComparer: null, Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).ValueComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null, valueComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null, valueComparer: null).ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>(keyComparer: null, valueComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.Create <int, int>(keyComparer: null, valueComparer: null).ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>(keyComparer: null, valueComparer: null).KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.Create <IComparable, IComparable>(keyComparer: null, valueComparer: null).ValueComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <object, object> >()).KeyComparer);
            Assert.Same(EqualityComparer <object> .Default, ImmutableSortedTreeDictionary.CreateRange <object, object>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <object, object> >()).ValueComparer);
            Assert.Same(Comparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <int, int> >()).KeyComparer);
            Assert.Same(EqualityComparer <int> .Default, ImmutableSortedTreeDictionary.CreateRange <int, int>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <int, int> >()).ValueComparer);
            Assert.Same(Comparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).KeyComparer);
            Assert.Same(EqualityComparer <IComparable> .Default, ImmutableSortedTreeDictionary.CreateRange <IComparable, IComparable>(keyComparer: null, valueComparer: null, Enumerable.Empty <KeyValuePair <IComparable, IComparable> >()).ValueComparer);
        }
        public void TestExplicitComparer()
        {
            var objComparer        = new ComparisonComparer <object>((x, y) => 0);
            var intComparer        = new ComparisonComparer <int>((x, y) => 0);
            var comparableComparer = new ComparisonComparer <IComparable>((x, y) => 0);

            ZeroHashCodeEqualityComparer <object?> objValueComparer = ZeroHashCodeEqualityComparer <object?> .Default;

            Assert.Same(objComparer, ImmutableSortedTreeDictionary.Create <object, int>(keyComparer: objComparer).KeyComparer);
            Assert.Same(intComparer, ImmutableSortedTreeDictionary.Create <int, int>(keyComparer: intComparer).KeyComparer);
            Assert.Same(comparableComparer, ImmutableSortedTreeDictionary.Create <IComparable, int>(keyComparer: comparableComparer).KeyComparer);

            Assert.Same(objComparer, ImmutableSortedTreeDictionary.CreateRange <object, int>(keyComparer: objComparer, Enumerable.Empty <KeyValuePair <object, int> >()).KeyComparer);
            Assert.Same(intComparer, ImmutableSortedTreeDictionary.CreateRange <int, int>(keyComparer: intComparer, Enumerable.Empty <KeyValuePair <int, int> >()).KeyComparer);
            Assert.Same(comparableComparer, ImmutableSortedTreeDictionary.CreateRange <IComparable, int>(keyComparer: comparableComparer, Enumerable.Empty <KeyValuePair <IComparable, int> >()).KeyComparer);

            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null, valueComparer: objValueComparer).KeyComparer);
            Assert.Same(objValueComparer, ImmutableSortedTreeDictionary.Create <object, object>(keyComparer: null, valueComparer: objValueComparer).ValueComparer);
            Assert.Same(Comparer <object> .Default, ImmutableSortedTreeDictionary.Create <object, object?>().Add(new object(), null).WithComparers(keyComparer: null, valueComparer: objValueComparer).KeyComparer);
            Assert.Same(objValueComparer, ImmutableSortedTreeDictionary.Create <object, object?>().Add(new object(), null).WithComparers(keyComparer: null, valueComparer: objValueComparer).ValueComparer);
        }