public void TestIDictionary()
        {
            IDictionary dictionary = new SortedTreeDictionary <int, int>(branchingFactor: 4);

            Assert.False(dictionary.IsFixedSize);
            Assert.False(dictionary.IsReadOnly);
            Assert.False(dictionary.IsSynchronized);

            Assert.Throws <ArgumentNullException>("key", () => dictionary.Add(key: null, value: 1));
            Assert.Throws <ArgumentException>("value", () => dictionary.Add(key: 1, value: null));
            Assert.Throws <ArgumentException>("key", () => dictionary.Add(key: "string value", value: 0));
            Assert.Throws <ArgumentException>("value", () => dictionary.Add(key: 0, value: "string value"));

            for (int i = 0; i < 11; i++)
            {
                dictionary.Add(i, i + 1);
            }

            Assert.Throws <ArgumentNullException>("key", () => dictionary[key: null]);
            Assert.Null(dictionary["string key"]);
            Assert.Equal(11, dictionary[10]);

            Assert.Throws <ArgumentNullException>("key", () => dictionary[key: null] = 12);
            Assert.Throws <ArgumentException>("key", () => dictionary["string key"]  = 12);
            Assert.Throws <ArgumentException>("value", () => dictionary[10]          = null);
            Assert.Throws <ArgumentException>("value", () => dictionary[10]          = "string value");
            dictionary[10] = 12;
            Assert.Equal(12, dictionary[10]);
            dictionary[10] = 11;

            TestCollection(dictionary, i => new KeyValuePair <int, int>(i, i + 1));

            var entries = new DictionaryEntry[dictionary.Count];

            dictionary.CopyTo(entries, 0);
            Assert.Equal(entries.Select(i => i.Key), dictionary.Keys.Cast <object>());
            Assert.Equal(entries.Select(i => i.Value), dictionary.Values.Cast <object>());

            Assert.Throws <ArgumentNullException>(() => dictionary.Contains(null));
            Assert.False(dictionary.Contains("string value"));
            Assert.True(dictionary.Contains(10));

            Assert.Throws <ArgumentNullException>(() => dictionary.Remove(null));
            Assert.Equal(11, dictionary.Count);
            dictionary.Remove("string value");
            Assert.Equal(11, dictionary.Count);
            dictionary.Remove(10);
            Assert.Equal(10, dictionary.Count);
            Assert.False(dictionary.Contains(10));

            IDictionaryEnumerator enumerator = dictionary.GetEnumerator();

            Assert.NotNull(enumerator);
            Assert.True(enumerator.MoveNext());
            Assert.Equal(0, enumerator.Key);
            Assert.Equal(1, enumerator.Value);
            Assert.Equal(enumerator.Key, enumerator.Entry.Key);
            Assert.Equal(enumerator.Value, enumerator.Entry.Value);
            Assert.Equal(enumerator.Entry, enumerator.Current);

            Assert.True(enumerator.MoveNext());
            Assert.Equal(1, enumerator.Key);
            Assert.Equal(2, enumerator.Value);
            Assert.Equal(enumerator.Key, enumerator.Entry.Key);
            Assert.Equal(enumerator.Value, enumerator.Entry.Value);
            Assert.Equal(enumerator.Entry, enumerator.Current);

            enumerator.Reset();
            Assert.True(enumerator.MoveNext());
            Assert.Equal(0, enumerator.Key);
            Assert.Equal(1, enumerator.Value);
            Assert.Equal(enumerator.Key, enumerator.Entry.Key);
            Assert.Equal(enumerator.Value, enumerator.Entry.Value);
            Assert.Equal(enumerator.Entry, enumerator.Current);

            ICollection keys = dictionary.Keys;

            TestCollection(keys, i => i);

            ICollection values = dictionary.Values;

            TestCollection(values, i => i + 1);

            dictionary.Clear();
            Assert.Empty(dictionary);
            Assert.Empty(keys);
            Assert.Empty(values);

            void TestCollection <T>(ICollection collection, Func <int, T> indexToExpectedValue)
            {
                Assert.NotNull(collection);
                Assert.False(collection.IsSynchronized);
                Assert.Same(dictionary.SyncRoot, collection.SyncRoot);

                Assert.Throws <ArgumentNullException>("array", () => collection.CopyTo(null, 0));
                Assert.Throws <ArgumentException>(() => collection.CopyTo(new int[collection.Count, 1], 0));
                Assert.Throws <ArgumentException>(() => collection.CopyTo(Array.CreateInstance(typeof(int), lengths: new[] { collection.Count }, lowerBounds: new[] { 1 }), 0));
                Assert.Throws <ArgumentOutOfRangeException>("index", () => collection.CopyTo(new int[collection.Count], -1));
                Assert.Throws <ArgumentOutOfRangeException>("index", () => collection.CopyTo(new int[collection.Count], collection.Count + 1));
                Assert.Throws <ArgumentException>(() => collection.CopyTo(new int[collection.Count], 1));

                var elements = new T[collection.Count];

                collection.CopyTo(elements, 0);
                Assert.Equal(elements, collection);

                var objects = new object[collection.Count];

                collection.CopyTo(objects, 0);
                Assert.Equal(objects, collection);

                Assert.Throws <ArgumentException>(() => collection.CopyTo(new string[collection.Count], 0));
                Assert.Throws <ArgumentException>(() => collection.CopyTo(new byte[collection.Count], 0));

                IEnumerator collectionEnumerator = collection.GetEnumerator();

                Assert.NotNull(collectionEnumerator);
                Assert.True(collectionEnumerator.MoveNext());
                Assert.Equal(indexToExpectedValue(0), collectionEnumerator.Current);

                Assert.True(collectionEnumerator.MoveNext());
                Assert.Equal(indexToExpectedValue(1), collectionEnumerator.Current);

                collectionEnumerator.Reset();
                Assert.True(collectionEnumerator.MoveNext());
                Assert.Equal(indexToExpectedValue(0), collectionEnumerator.Current);
            }
        }