OrderedMultiDictionaryTests.cs :  » Development » TULP2G » Wintellect » PowerCollections » Tests » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » TULP2G 
TULP2G » Wintellect » PowerCollections » Tests » OrderedMultiDictionaryTests.cs
//******************************
// Written by Peter Golde
// Copyright (c) 2004-2005, Wintellect
//
// Use and restribution of this code is subject to the license agreement 
// contained in the file "License.txt" accompanying this file.
//******************************

using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using Wintellect.PowerCollections.Tests;

namespace Wintellect.PowerCollections.Tests{
    using MyInt = OrderedDictionaryTests.MyInt;

    [TestFixture]
    public class OrderedMultiDictionaryTests
    {
        // Check the contents of a Multi-Dictionary non-destructively. Keys and Values must be in order.
        internal static void CheckOrderedMultiDictionaryContents<TKey, TValue>(OrderedMultiDictionary<TKey, TValue> dict, TKey[] keys, TValue[][] values, TKey nonKey, TValue nonValue, BinaryPredicate<TKey> keyEquals, BinaryPredicate<TValue> valueEquals)
        {
            int iKey, iValue;
            ICollection<TValue> getValues;

            if (keyEquals == null)
                keyEquals = delegate(TKey x, TKey y) { return object.Equals(x, y); };
            if (valueEquals == null)
                valueEquals = delegate(TValue x, TValue y) { return object.Equals(x, y); };

            // Check Count.
            Assert.AreEqual(keys.Length, dict.Count);

            // Check indexer, ContainsKey, Contains, TryGetValue for each key.
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                Assert.IsTrue(dict.ContainsKey(keys[iKey]));
                Assert.IsTrue(dict.Contains(new KeyValuePair<TKey, ICollection<TValue>>(keys[iKey], values[iKey])));

                bool b = ((IDictionary<TKey,ICollection<TValue>>)dict).TryGetValue(keys[iKey], out getValues);
                Assert.IsTrue(b);
                iValue = 0;
                foreach (TValue val in getValues) {
                    Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                    ++iValue;
                }

                iValue = 0;
                foreach (TValue val in values[iKey]) {
                    Assert.IsTrue(dict.Contains(keys[iKey], val));
                    ++iValue;
                }

                iValue = 0;
                foreach (TValue val in dict[keys[iKey]]) {
                    Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                    ++iValue;
                }
                Assert.IsTrue(iValue == values[iKey].Length);
            }

            // Check Keys collection.
            iKey = 0;
            foreach (TKey key in dict.Keys) {
                Assert.IsTrue(keyEquals(keys[iKey], key));
                ++iKey;
            }
            Assert.IsTrue(iKey == keys.Length);
            InterfaceTests.TestReadonlyCollectionGeneric<TKey>(dict.Keys, keys, true, null, keyEquals);

            // Check Values collection
            iKey = 0; iValue = 0;
            int valueCount = 0;
            foreach (TValue val in dict.Values) {
                Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                ++iValue;
                if (iValue == values[iKey].Length) {
                    iValue = 0;
                    ++iKey;
                }
                ++valueCount;
            }
            Assert.IsTrue(iKey == keys.Length);

            int a = 0;
            TValue[] vals = new TValue[valueCount];
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                for (iValue = 0; iValue < values[iKey].Length; ++iValue) {
                    vals[a++] = values[iKey][iValue];
                }
            }
            InterfaceTests.TestReadonlyCollectionGeneric<TValue>(dict.Values, vals, true, null, valueEquals);

            // Check KeyValuePairs collection.
            iKey = 0; iValue = 0;
            valueCount = 0;
            foreach (KeyValuePair<TKey, TValue> pair in dict.KeyValuePairs) {
                Assert.IsTrue(keyEquals(keys[iKey], pair.Key));
                Assert.IsTrue(valueEquals(values[iKey][iValue], pair.Value));
                ++iValue;
                if (iValue == values[iKey].Length) {
                    iValue = 0;
                    ++iKey;
                }
                ++valueCount;
            }
            Assert.IsTrue(iKey == keys.Length);

            a = 0;
            KeyValuePair<TKey, TValue>[] pairs = new KeyValuePair<TKey, TValue>[valueCount];
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                for (iValue = 0; iValue < values[iKey].Length; ++iValue) {
                    pairs[a++] = new KeyValuePair<TKey, TValue>(keys[iKey], values[iKey][iValue]);
                }
            }
            InterfaceTests.TestReadonlyCollectionGeneric<KeyValuePair<TKey, TValue>>(dict.KeyValuePairs, pairs, true, null, InterfaceTests.KeyValueEquals<TKey,TValue>(keyEquals, valueEquals));

            // Tests Contains, ContainsKey, TryGetValue for wrong values.
            Assert.IsFalse(dict.ContainsKey(nonKey));
            Assert.IsFalse(((IDictionary<TKey, ICollection<TValue>>)dict).TryGetValue(nonKey, out getValues));
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                Assert.IsFalse(dict.Contains(keys[iKey], nonValue));
                Assert.IsFalse(dict.Contains(new KeyValuePair<TKey, ICollection<TValue>>(keys[iKey], new TValue[1] { nonValue })));
            }

            // Test IDictionary<TKey,IEnumerable<TValue>> implementation
            InterfaceTests.TestReadWriteMultiDictionaryGeneric<TKey, TValue>(dict, keys, values, nonKey, nonValue, true, "OrderedMultiDictionary", keyEquals, valueEquals);
        }

        // Do random add,remove,replaces and create an array.
        private int[,] AddRemoveRandom(Random rand, OrderedMultiDictionary<int, string> dict, bool useDups, int iter)
        {
            const int MAXKEY = 100, MAXVAL = 50;
            int[,] counts = new int[MAXKEY, MAXVAL];

            for (int x = 0; x < iter; ++x) {
                int key = rand.Next(MAXKEY);
                int val = rand.Next(MAXVAL);
                string valString = string.Format("A{0:0000}", val);

                if (counts[key, val] == 0) {
                    if (rand.Next(30) == 0) {
                        // Do a replace
                        dict.Replace(key, valString);
                        for (int i = 0; i < MAXVAL; ++i)
                            counts[key, i] = 0;
                        counts[key, val] = 1;
                    }
                    else {
                        // Do an add
                        dict.Add(key, valString);
                        counts[key, val] = 1;
                    }
                }
                else {
                    if (rand.Next(30) == 0) {
                        // Do a replace
                        dict.Replace(key, valString);
                        for (int i = 0; i < MAXVAL; ++i)
                            counts[key, i] = 0;
                        counts[key, val] = 1;
                    }
                    else if (rand.Next(5) < 2) {
                        // Do an add
                        dict.Add(key, valString);
                        if (useDups)
                            counts[key, val] += 1;
                    }
                    else {
                        // Do a remove
                        dict.Remove(key, valString);
                        counts[key, val] -= 1;
                    }
                }
            }

            return counts;
        }

        // Check an ordered multi-dictionary against an array.
        private void CheckAgainstArray(OrderedMultiDictionary<int, string> dict, int[,] array)
        {
            List<string[]> values = new List<string[]>();
            List<int> keys = new List<int>();
            List<string> vals = new List<string>();

            for (int i = 0; i < array.GetLength(0); ++i) {
                bool hasval = false;
                for (int j = 0; j < array.GetLength(1); ++j) {
                    if (array[i, j] > 0) {
                        hasval = true;
                        for (int x = 0; x < array[i, j]; ++x)
                            vals.Add(string.Format("A{0:0000}", j));
                    }
                }

                if (hasval) {
                    keys.Add(i);
                    values.Add(vals.ToArray());
                    vals.Clear();
                }
            }

            int[] keysArray = keys.ToArray();
            string[][] valsArray = values.ToArray();

            CheckOrderedMultiDictionaryContents<int, string>(dict,
                keysArray,
                valsArray,
                -1, "Foo", null, null);
        }

        [Test]
        public void RandomAdd()
        {
            Random rand = new Random(14);
            OrderedMultiDictionary<int,string> dict = new OrderedMultiDictionary<int,string>(true);

            int[,] array = AddRemoveRandom(rand, dict, true, 3000);
            CheckAgainstArray(dict, array);
        }


        [Test]
        public void Add()
        {
            // Test without duplicate values.
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);

            CheckOrderedMultiDictionaryContents<string, double>(dict1,
                new string[] { null, "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 7.1 }, new double[] { -9 } },
                "zip", -100, null, null);

            // Test with duplicate values.
            dict1 = new OrderedMultiDictionary<string, double>(true);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);

            CheckOrderedMultiDictionaryContents<string, double>(dict1,
                new string[] { null, "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 5.5, 11.1, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8, 8.8 }, new double[] { 7.1 }, new double[] { -9 } },
                "zip", -100, null, null);

            // Test duplicate values with distinct equal values.
            OrderedMultiDictionary<string, string> dict2 = new OrderedMultiDictionary<string, string>(false, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);
            dict2.Add("foo", "BAR");
            dict2.Add("Foo", "bar");
            InterfaceTests.TestEnumerableElements<string>(dict2.Keys, new string[] { "Foo" });
            InterfaceTests.TestEnumerableElements<string>(dict2["FOO"], new string[] { "bar" });
            dict2 = new OrderedMultiDictionary<string, string>(true, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase); 
            dict2.Add("foo", "BAR");
            dict2.Add("Foo", "bar");
            InterfaceTests.TestEnumerableElements<string>(dict2.Keys, new string[] { "foo" });
            InterfaceTests.TestEnumerableElements<string>(dict2["FOO"], new string[] { "BAR", "bar" });
            Console.WriteLine(dict2.ToString());
            InterfaceTests.TestEnumerableElements < KeyValuePair<string, string>>
                (dict2.KeyValuePairs, new KeyValuePair<string, string>[] { new KeyValuePair<string,string>("foo", "BAR"),
                  new KeyValuePair<string,string>("Foo", "bar")}, InterfaceTests.KeyValueEquals<string,string>());
        }

        [Test]
        public void AddMany1()
        {
            // Test without duplicate values.
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false, StringComparer.InvariantCultureIgnoreCase);

            dict1.AddMany("foo", AlgorithmsTests.EnumerableFromArray(new double[] { 9.8, 1.2, -9, 9.8, -9, 4 }));
            dict1.AddMany("hi", new double[0]);
            dict1.AddMany("FOO", AlgorithmsTests.EnumerableFromArray(new double[] { 8, -9 }));

            Assert.AreEqual(1, dict1.Count);
            Assert.IsTrue(dict1.ContainsKey("foo"));
            Assert.IsFalse(dict1.ContainsKey("hi"));
            InterfaceTests.TestEnumerableElements(dict1.Keys, new string[] { "FOO" });
            InterfaceTests.TestEnumerableElements(dict1["fOo"], new double[] { -9, 1.2, 4, 8, 9.8 });
            InterfaceTests.TestEnumerableElements<KeyValuePair<string, double>>
                (dict1.KeyValuePairs, new KeyValuePair<string, double>[] { 
                            new KeyValuePair<string,double>("FOO", -9),
                            new KeyValuePair<string,double>("foo", 1.2),
                            new KeyValuePair<string,double>("foo", 4),
                            new KeyValuePair<string,double>("FOO",8),
                            new KeyValuePair<string,double>("foo",9.8)
                            });

            // Test with duplicate values
            dict1 = new OrderedMultiDictionary<string, double>(true, StringComparer.InvariantCultureIgnoreCase);

            dict1.AddMany("foo", AlgorithmsTests.EnumerableFromArray(new double[] { 9.8, 1.2, -9, 9.8, -9, 4 }));
            dict1.AddMany("hi", new double[0]);
            dict1.AddMany("a", new double[] { 2, 1, 2 });
            dict1.AddMany("FOO", AlgorithmsTests.EnumerableFromArray(new double[] { 8, -9 }));

            Assert.AreEqual(2, dict1.Count);
            Assert.IsTrue(dict1.ContainsKey("foo"));
            Assert.IsFalse(dict1.ContainsKey("hi"));
            InterfaceTests.TestEnumerableElements(dict1.Keys, new string[] { "a", "foo"});
            InterfaceTests.TestEnumerableElements(dict1["fOo"], new double[] { -9, -9, -9, 1.2, 4, 8, 9.8, 9.8 });
            InterfaceTests.TestEnumerableElements<KeyValuePair<string, double>>
                (dict1.KeyValuePairs, new KeyValuePair<string, double>[] { 
                            new KeyValuePair<string,double>("a", 1),
                            new KeyValuePair<string,double>("a", 2),
                            new KeyValuePair<string,double>("a", 2),
                            new KeyValuePair<string,double>("foo", -9),
                            new KeyValuePair<string,double>("foo", -9),
                            new KeyValuePair<string,double>("FOO", -9),
                            new KeyValuePair<string,double>("foo", 1.2),
                            new KeyValuePair<string,double>("foo", 4),
                            new KeyValuePair<string,double>("FOO",8),
                            new KeyValuePair<string,double>("foo",9.8),
                            new KeyValuePair<string,double>("foo",9.8)
                            });
        }


        [Test]
        public void Replace()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 3);
            dict1.Add("foo", 1);

            dict1.Replace("foo", 13);
            dict1.Replace("z", 19);
            dict1.Replace("hello", 193);
            dict1.Replace("foo", 123);
            dict1.Add("foo", 123);

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "foo", "hello", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 123, 123 }, new int[] {193}, new int[] { 19 } },
                "sailor", 19921, null, null);
        }

        [Test]
        public void ReplaceMany()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(false);

            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 3);
            dict1.Add("foo", 1);
            dict1.Add("bill", 9);

            dict1.ReplaceMany("bill", new int[0]);
            dict1.ReplaceMany("foo", new int[] { 13, 4 });
            dict1.ReplaceMany("z", new int[] { 19 });
            dict1.ReplaceMany("hello", new int[] { 193, -11, 193 });
            dict1.ReplaceMany("goodbye", new int[0]);
            dict1.ReplaceMany("foo", new int[] { 123, 0, 4 });
            dict1.Add("foo", 29);

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "foo", "hello", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 0, 4, 29, 123 }, new int[] { -11, 193 }, new int[] { 19 } },
                "sailor", 19921, null, null);
        }

        [Test]
        public void RemoveKey()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 10);
            dict1.Add("z", 3);
            dict1.Add("foo", 4);
            dict1.Add("bill", 9);

            Assert.IsTrue(dict1.ContainsKey("bill"));
            Assert.IsTrue(dict1.ContainsKey("foo"));
            Assert.IsTrue(dict1.ContainsKey("z"));

            Assert.IsTrue(dict1.Remove("bill"));
            Assert.IsFalse(dict1.Remove("bill"));
            Assert.IsFalse(dict1.Remove("smell"));
            Assert.IsTrue(dict1.Remove("foo"));

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 3, 3, 10 }},
                "sailor", 19921, null, null);
        }

        [Test]
        public void RemoveManyKeys()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 10);
            dict1.Add("z", 3);
            dict1.Add("foo", 4);
            dict1.Add("bill", 9);

            Assert.IsTrue(dict1.ContainsKey("bill"));
            Assert.IsTrue(dict1.ContainsKey("foo"));
            Assert.IsTrue(dict1.ContainsKey("z"));

            Assert.AreEqual(2, dict1.RemoveMany(new string[] { "bill", "smell", "foo", "bill" }));

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 3, 3, 10 } },
                "sailor", 19921, null, null);
        }

        [Test]
        public void Remove()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 10);
            dict1.Add("z", 3);
            dict1.Add("foo", 4);
            dict1.Add("bill", 9);
            dict1.Add("foo", 4);

            Assert.IsTrue(dict1.Remove("foo", 4));
            Assert.IsTrue(dict1.Remove("foo", 4));
            Assert.IsTrue(dict1.Remove("z", 10));
            Assert.IsFalse(dict1.Remove("z", 10));
            Assert.IsFalse(dict1.Remove("foo", 11));
            Assert.IsFalse(dict1.Remove(null, 0));
            Assert.IsTrue(dict1.Remove("bill", 9));

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "foo", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 4, 6 }, new int[] { 3, 3 } },
                "sailor", 19921, null, null);
        }

        [Test]
        public void RemoveMany1()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("bill", 7);
            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 10);
            dict1.Add("z", 3);
            dict1.Add("foo", 4);
            dict1.Add("bill", 9);
            dict1.Add("foo", 4);

            Assert.AreEqual(2, dict1.RemoveMany("foo", new int[] { 4, 11, 4 }));
            Assert.AreEqual(1, dict1.RemoveMany("z", new int[] { 9, 2, 10 }));
            Assert.AreEqual(0, dict1.RemoveMany("z", new int[] { 10, 16, 144, 10 }));
            Assert.AreEqual(0, dict1.RemoveMany("foo", new int[0]));
            Assert.AreEqual(0, dict1.RemoveMany(null, new int[2] { 1, 2 }));
            Assert.AreEqual(2, dict1.RemoveMany("bill", new int[] { 9, 7 }));

            CheckOrderedMultiDictionaryContents(dict1,
                new string[] { "bar", "foo", "z" },
                new int[][] { new int[] { 7, 8 }, new int[] { 4, 6 }, new int[] { 3, 3 } },
                "sailor", 19921, null, null);
        }

        [Test]
        public void Clear()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add("bill", 7);
            dict1.Add("foo", 4);
            dict1.Add("bar", 7);
            dict1.Add("foo", 6);
            dict1.Add("z", 3);
            dict1.Add("bar", 8);
            dict1.Add("z", 10);
            dict1.Add(null, 3);
            dict1.Add("foo", 4);
            dict1.Add("bill", 9);
            dict1.Add("foo", 4);

            dict1.Clear();

            Assert.AreEqual(0, dict1.Count);
            Assert.IsFalse(dict1.ContainsKey("foo"));
            Assert.IsFalse(dict1.ContainsKey("z"));
            Assert.IsFalse(dict1.ContainsKey(null));
            Assert.AreEqual(0, Algorithms.Count(dict1.Keys));
            Assert.AreEqual(0, Algorithms.Count(dict1.Values));
            Assert.AreEqual(0, Algorithms.Count(dict1.KeyValuePairs));

            CheckOrderedMultiDictionaryContents(dict1, new string[0], new int[0][], "foo", 4, null, null);
        }

        [Test]
        public void Count()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add(null, 7);
            dict1.Add("bar", 11);
            dict1.Add("foo", 7);
            dict1.Add(null, 7);
            dict1.Add("hello", 11);
            dict1.Add("foo", 4);
            Assert.AreEqual(4, dict1.Count);

            OrderedMultiDictionary<string, int> dict2 = new OrderedMultiDictionary<string, int>(false);

            dict2.Add("foo", 4);
            dict2.Add(null, 7);
            dict2.Add("bar", 11);
            dict2.Add("foo", 7);
            dict2.Add(null, 7);
            dict2.Add("hello", 11);
            dict2.Add("foo", 4);
            Assert.AreEqual(4, dict2.Count);

            dict2.Remove("foo");
            Assert.AreEqual(3, dict2.Count);

            dict2.Clear();
            Assert.AreEqual(0, dict2.Count);
        }

        [Test]
        public void ContainsKey()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add(null, 7);
            dict1.Add("bar", 11);
            dict1.Add("foo", 7);
            dict1.Add(null, 7);
            dict1.Add("hello", 11);
            dict1.Add("foo", 4);

            Assert.IsTrue(dict1.ContainsKey(null));
            Assert.IsTrue(dict1.ContainsKey("foo"));
            Assert.IsTrue(dict1.ContainsKey("bar"));
            Assert.IsTrue(dict1.ContainsKey("hello"));
            dict1.Remove("hello", 11);
            Assert.IsFalse(dict1.ContainsKey("hello"));
            dict1.Remove(null, 7);
            Assert.IsTrue(dict1.ContainsKey(null));
            dict1.Remove(null, 7);
            Assert.IsFalse(dict1.ContainsKey(null));
        }

        [Test]
        public void Contains()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 4);
            dict1.Add(null, 7);
            dict1.Add("bar", 11);
            dict1.Add("foo", 7);
            dict1.Add(null, 7);
            dict1.Add("hello", 11);
            dict1.Add("foo", 4);

            Assert.IsTrue(dict1.Contains(null, 7));
            Assert.IsTrue(dict1.Contains("foo", 4));
            Assert.IsTrue(dict1.Contains("bar", 11));
            Assert.IsTrue(dict1.Contains("hello", 11));
            Assert.IsFalse(dict1.Contains("HELLO", 11));
            Assert.IsFalse(dict1.Contains("bar", 12));
            Assert.IsFalse(dict1.Contains("foo", 0));
            dict1.Remove("hello", 11);
            Assert.IsFalse(dict1.Contains("hello", 11));
            dict1.Remove(null, 7);
            Assert.IsTrue(dict1.Contains(null, 7));
            dict1.Remove(null, 7);
            Assert.IsFalse(dict1.Contains(null, 7));
        }

        [Test]
        public void KeysCollection()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(false, StringComparer.InvariantCultureIgnoreCase);

            dict1.Add("foo", 4);
            dict1.Add(null, 2);
            dict1.Add("bar", 3);
            dict1.Add("sailor", 0);
            dict1.Add("FOO", 9);
            dict1.Add("b", 7);
            dict1.Add("Foo", -1);
            dict1.Add("BAR", 3);
            dict1.Remove("b", 7);

            InterfaceTests.TestReadonlyCollectionGeneric<string>(dict1.Keys, new string[] { null, "BAR", "Foo", "sailor" }, true, null);

            Assert.IsTrue(dict1.Keys.Contains("foo"));
            Assert.IsTrue(dict1.Keys.Contains("Foo"));
            Assert.IsTrue(dict1.Keys.Contains(null));
            Assert.IsTrue(dict1.Keys.Contains("Sailor"));
            Assert.IsFalse(dict1.Keys.Contains("banana"));

            OrderedMultiDictionary<string, int> dict2 = new OrderedMultiDictionary<string, int>(false, StringComparer.InvariantCultureIgnoreCase);
            InterfaceTests.TestEnumerableElements(dict2.Keys, new string[] { });
        }

        [Test]
        public void ValuesCollection1()
        {
            OrderedMultiDictionary<double, string> dict = new OrderedMultiDictionary<double, string>(false, Comparer<double>.Default, StringComparer.InvariantCultureIgnoreCase);

            dict.Add(7, "Gizzle");
            dict.Add(4, "foo");
            dict.Add(6, "Foo");
            dict.Add(3, "FOO");
            dict.Add(3, "baz");
            dict.Add(3, "bar");
            dict.Add(4, "FOo");
            dict.Add(3, "BAZ");
            dict.Add(5, "bAZ");
            dict.Add(7, "hello");
            dict.Add(7, "foo");

            ICollection<string> vals = dict.Values;

            string[] expected = {
                "bar", "BAZ", "FOO", "FOo", "bAZ", "Foo", "foo", "Gizzle", "hello"};

            InterfaceTests.TestReadonlyCollectionGeneric<string>(vals, expected, true, null);

            Assert.IsTrue(vals.Contains("gizzle"));
            Assert.IsTrue(vals.Contains("FOO"));
            Assert.IsTrue(vals.Contains("fOO"));
            Assert.IsTrue(vals.Contains("hello"));
            Assert.IsTrue(vals.Contains("bar"));
            Assert.IsTrue(vals.Contains("BAR"));
            Assert.IsFalse(vals.Contains("qatar"));
        }

        [Test]
        public void ValuesCollection2()
        {
            OrderedMultiDictionary<double, string> dict = new OrderedMultiDictionary<double, string>(true, Comparer<double>.Default, StringComparer.InvariantCultureIgnoreCase);

            dict.Add(7, "Gizzle");
            dict.Add(4, "foo");
            dict.Add(6, "Foo");
            dict.Add(3, "FOO");
            dict.Add(3, "baz");
            dict.Add(3, "bar");
            dict.Add(4, "FOo");
            dict.Add(3, "BAZ");
            dict.Add(5, "bAZ");
            dict.Add(7, "hello");
            dict.Add(7, "foo");

            ICollection<string> vals = dict.Values;

            string[] expected = {
                "bar", "baz", "BAZ", "FOO", "foo", "FOo", "bAZ", "Foo", "foo", "Gizzle", "hello"};

            InterfaceTests.TestReadonlyCollectionGeneric<string>(vals, expected, true, null);

            Assert.IsTrue(vals.Contains("gizzle"));
            Assert.IsTrue(vals.Contains("FOO"));
            Assert.IsTrue(vals.Contains("fOO"));
            Assert.IsTrue(vals.Contains("hello"));
            Assert.IsTrue(vals.Contains("bar"));
            Assert.IsTrue(vals.Contains("BAR"));
            Assert.IsFalse(vals.Contains("qatar"));
        }

        [Test]
        public void KeyValuesCollection1()
        {
            OrderedMultiDictionary<string, string> dict = new OrderedMultiDictionary<string, string>(false, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);

            dict.Add("7A", "Gizzle");
            dict.Add("4a", "foo");
            dict.Add("6A", "Foo");
            dict.Add("3a", "FOO");
            dict.Add("3A", "baz");
            dict.Add("3a", "bar");
            dict.Add("4a", "FOo");
            dict.Add("3A", "BAZ");
            dict.Add("5a", "bAZ");
            dict.Add("7a", "hello");
            dict.Add("7A", "foo");

            ICollection<KeyValuePair<string,string>> pairs = dict.KeyValuePairs;

            string[] expectedKeys = {
                "3a", "3A", "3a", "4a", "5a", "6A", "7A", "7A", "7a"};
            string[] expectedVals = {
                "bar", "BAZ", "FOO", "FOo", "bAZ", "Foo", "foo", "Gizzle", "hello"};
            KeyValuePair<string, string>[] expectedPairs = new KeyValuePair<string, string>[expectedKeys.Length];
            for (int i = 0; i < expectedKeys.Length; ++i)
                expectedPairs[i] = new KeyValuePair<string, string>(expectedKeys[i], expectedVals[i]);

            InterfaceTests.TestReadonlyCollectionGeneric<KeyValuePair<string,string>>(pairs, expectedPairs, true, null);

            Assert.IsTrue(pairs.Contains(new KeyValuePair<string,string>("3a", "baz")));
            Assert.IsTrue(pairs.Contains(new KeyValuePair<string,string>("3A", "baz")));
            Assert.IsTrue(pairs.Contains(new KeyValuePair<string, string>("6a", "foo")));
            Assert.IsFalse(pairs.Contains(new KeyValuePair<string, string>("7A", "bar")));

        }

        [Test]
        public void KeyValuesCollection2()
        {
            OrderedMultiDictionary<string, string> dict = new OrderedMultiDictionary<string, string>(true, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);

            dict.Add("7A", "Gizzle");
            dict.Add("4A", "foo");
            dict.Add("6A", "Foo");
            dict.Add("3a", "FOO");
            dict.Add("3A", "baz");
            dict.Add("3a", "bar");
            dict.Add("4a", "FOo");
            dict.Add("3a", "BAZ");
            dict.Add("5a", "bAZ");
            dict.Add("7a", "hello");
            dict.Add("7A", "foo");

            ICollection<KeyValuePair<string, string>> pairs = dict.KeyValuePairs;

            string[] expectedKeys = {
            "3a", "3A", "3a", "3a", "4A", "4a", "5a", "6A", "7A", "7A", "7a"};
            string[] expectedVals = {
            "bar", "baz", "BAZ", "FOO", "foo", "FOo", "bAZ", "Foo", "foo", "Gizzle", "hello"};
            KeyValuePair<string, string>[] expectedPairs = new KeyValuePair<string, string>[expectedKeys.Length];
            for (int i = 0; i < expectedKeys.Length; ++i)
                expectedPairs[i] = new KeyValuePair<string, string>(expectedKeys[i], expectedVals[i]);

            InterfaceTests.TestReadonlyCollectionGeneric<KeyValuePair<string, string>>(pairs, expectedPairs, true, null);

            Assert.IsTrue(pairs.Contains(new KeyValuePair<string, string>("3a", "baz")));
            Assert.IsTrue(pairs.Contains(new KeyValuePair<string, string>("3A", "baz")));
            Assert.IsTrue(pairs.Contains(new KeyValuePair<string, string>("6a", "foo")));
            Assert.IsFalse(pairs.Contains(new KeyValuePair<string, string>("7A", "bar")));
        }

        [Test]
        public void Indexer()
        {
            OrderedMultiDictionary<string, string> dict1 = new OrderedMultiDictionary<string, string>(true, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);

            dict1.Add("foo", "BAR");
            dict1.Add(null, "hello");
            dict1.Add("Hello", "sailor");
            dict1.Add(null, "hi");
            dict1.Add("foo", "bar");
            dict1.Add("HELLO", null);
            dict1.Add("foo", "a");
            dict1.Add("Foo", "A");
            dict1.Add("trail", "mix");

            InterfaceTests.TestEnumerableElements(dict1[null], new string[] { "hello", "hi" });
            InterfaceTests.TestEnumerableElements(dict1["hELLo"], new string[] { null, "sailor" });
            InterfaceTests.TestEnumerableElements(dict1["foo"], new string[] { "a", "A", "BAR", "bar" });
            InterfaceTests.TestEnumerableElements(dict1["trail"], new string[] { "mix" });
            InterfaceTests.TestEnumerableElements(dict1["nothing"], new string[] {  });
        }

        [Test]
        public void GetValueCount()
        {
            OrderedMultiDictionary<string, string> dict1 = new OrderedMultiDictionary<string, string>(true, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);

            dict1.Add("foo", "BAR");
            dict1.Add(null, "hello");
            dict1.Add("Hello", "sailor");
            dict1.Add(null, "hi");
            dict1.Add("foo", "bar");
            dict1.Add("HELLO", null);
            dict1.Add("foo", "a");
            dict1.Add("Foo", "A");
            dict1.Add("hello", null);
            dict1.Add("trail", "mix");

            Assert.AreEqual(2, dict1[null].Count);
            Assert.AreEqual(3, dict1["hELLo"].Count);
            Assert.AreEqual(4, dict1["foo"].Count);
            Assert.AreEqual(1, dict1["trail"].Count);
            Assert.AreEqual(0, dict1["nothing"].Count);

            dict1 = new OrderedMultiDictionary<string, string>(false, StringComparer.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase);

            dict1.Add("foo", "BAR");
            dict1.Add(null, "hello");
            dict1.Add("Hello", "sailor");
            dict1.Add(null, "hi");
            dict1.Add("foo", "bar");
            dict1.Add("HELLO", null);
            dict1.Add("foo", "a");
            dict1.Add("Foo", "A");
            dict1.Add("hello", null);
            dict1.Add("trail", "mix");

            Assert.AreEqual(2, dict1[null].Count);
            Assert.AreEqual(2, dict1["hELLo"].Count);
            Assert.AreEqual(2, dict1["foo"].Count);
            Assert.AreEqual(1, dict1["trail"].Count);
            Assert.AreEqual(0, dict1["nothing"].Count);

        }

        [Test]
        public void IMultiDictionaryInterface()
        {
            OrderedMultiDictionary<string, string> dict1 = new OrderedMultiDictionary<string, string>(true);

            dict1.Add("foo", "bar");
            dict1.Add(null, "hello");
            dict1.Add("hello", "sailor");
            dict1.Add(null, "hi");
            dict1.Add("foo", "bar");
            dict1.Add("hello", null);
            dict1.Add("foo", "a");
            dict1.Add("foo", "a");
            dict1.Add("hello", null);
            dict1.Add("trail", "mix");

            CheckOrderedMultiDictionaryContents<string, string>(dict1,
                new string[] { null, "foo", "hello", "trail" },
                new string[][] { new string[] { "hello", "hi" }, new string[] { "a", "a", "bar", "bar" }, new string[] { null, null, "sailor" }, new string[] { "mix" } },
                "zippy", "pinhead", null, null);

            dict1 = new OrderedMultiDictionary<string, string>(false);

            dict1.Add("foo", "bar");
            dict1.Add(null, "hello");
            dict1.Add("hello", "sailor");
            dict1.Add(null, "hi");
            dict1.Add("foo", "bar");
            dict1.Add("hello", null);
            dict1.Add("foo", "a");
            dict1.Add("foo", "a");
            dict1.Add("hello", null);

            dict1.Add("trail", "mix");
            CheckOrderedMultiDictionaryContents<string, string>(dict1,
                new string[] { null, "foo", "hello", "trail" },
                new string[][] { new string[] { "hello", "hi" }, new string[] { "a", "bar" }, new string[] { null, "sailor" }, new string[] { "mix" } },
                "zippy", "pinhead", null, null);

        }

        [Test]
        public void CustomComparison()
        {
            Comparison<string> reverseFirstLetter = delegate(string x, string y) {
                if (x[0] < y[0])
                    return 1;
                else if (x[0] > y[0])
                    return -1;
                else 
                    return 0;
            };

            OrderedMultiDictionary<string,string> dict1 = new OrderedMultiDictionary<string,string>(false, reverseFirstLetter);

            dict1.Add("hello", "AAA");
            dict1.Add("hi", "aaa");
            dict1.Add("qubert", "hello");
            dict1.Add("queztel", "hello");
            dict1.Add("alpha", "omega");
            dict1.Add("alzabar", "oz");

            InterfaceTests.TestEnumerableElements(dict1.KeyValuePairs, new KeyValuePair<string,string>[] {
                new KeyValuePair<string,string>("queztel", "hello"),
                new KeyValuePair<string,string>("hi", "aaa"),
                new KeyValuePair<string,string>("hello", "AAA"),
                new KeyValuePair<string,string>("alpha", "omega"),
                new KeyValuePair<string,string>("alzabar", "oz")});

            InterfaceTests.TestEnumerableElements(dict1.Keys, new string[] { "queztel", "hi", "alpha" });

            OrderedMultiDictionary<string, string> dict2 = new OrderedMultiDictionary<string, string>(false, StringComparer.InvariantCultureIgnoreCase.Compare, reverseFirstLetter);

            dict2.Add("qubert", "dinosaur");
            dict2.Add("Hello", "AAA");
            dict2.Add("Hi", "aaa");
            dict2.Add("qubert", "hello");
            dict2.Add("queztel", "hello");
            dict2.Add("alpha", "omega");
            dict2.Add("Alpha", "oz");
            dict2.Add("qubert", "hippy");

            InterfaceTests.TestEnumerableElements(dict2.KeyValuePairs, new KeyValuePair<string, string>[] {
                new KeyValuePair<string,string>("Alpha", "oz"),
                new KeyValuePair<string,string>("Hello", "AAA"),
                new KeyValuePair<string,string>("Hi", "aaa"),
                new KeyValuePair<string,string>("qubert", "hippy"),
                new KeyValuePair<string,string>("qubert", "dinosaur"),
                new KeyValuePair<string,string>("queztel", "hello")});
        }

        [Test, ExpectedException(typeof(InvalidOperationException))]
        public void NotComparable1()
        {
            OrderedMultiDictionary<OrderedDictionaryTests.UncomparableClass1, string> dict1 = new OrderedMultiDictionary<OrderedDictionaryTests.UncomparableClass1, string>(false);
        }

        [Test, ExpectedException(typeof(InvalidOperationException))]
        public void NotComparable2()
        {
            OrderedMultiDictionary<string, OrderedDictionaryTests.UncomparableClass2> dict2 = new OrderedMultiDictionary<string, OrderedDictionaryTests.UncomparableClass2>(true);
        }

        [Test]
        public void Clone()
        {
            Comparison<string> reverseFirstLetter = delegate(string x, string y) {
                if (x[0] < y[0])
                    return 1;
                else if (x[0] > y[0])
                    return -1;
                else
                    return 0;
            };

            OrderedMultiDictionary<string, string> dict1 = new OrderedMultiDictionary<string, string>(false, StringComparer.InvariantCultureIgnoreCase.Compare, reverseFirstLetter);

            dict1.Add("qubert", "dinosaur");
            dict1.Add("Hello", "AAA");
            dict1.Add("Hi", "aaa");
            dict1.Add("qubert", "hello");
            dict1.Add("queztel", "hello");
            dict1.Add("alpha", "omega");
            dict1.Add("Alpha", "oz");
            dict1.Add("qubert", "hippy");

            OrderedMultiDictionary<string, string> dict2 = dict1.Clone();

            Assert.IsTrue(dict1 != dict2);

            dict2.Add("qubert", "hoover");
            dict2.Remove("queztel");
            dict2.Add("hello", "banana");

            InterfaceTests.TestEnumerableElements(dict1.KeyValuePairs, new KeyValuePair<string, string>[] {
                new KeyValuePair<string,string>("Alpha", "oz"),
                new KeyValuePair<string,string>("Hello", "AAA"),
                new KeyValuePair<string,string>("Hi", "aaa"),
                new KeyValuePair<string,string>("qubert", "hippy"),
                new KeyValuePair<string,string>("qubert", "dinosaur"),
                new KeyValuePair<string,string>("queztel", "hello")});

            InterfaceTests.TestEnumerableElements(dict2.KeyValuePairs, new KeyValuePair<string, string>[] {
                new KeyValuePair<string,string>("Alpha", "oz"),
                new KeyValuePair<string,string>("hello", "banana"),
                new KeyValuePair<string,string>("Hello", "AAA"),
                new KeyValuePair<string,string>("Hi", "aaa"),
                new KeyValuePair<string,string>("qubert", "hoover"),
                new KeyValuePair<string,string>("qubert", "dinosaur")});

            dict2 = ((OrderedMultiDictionary<string, string>)((ICloneable)dict1).Clone());

            Assert.IsTrue(dict1 != dict2);

            dict2.Add("qubert", "hoover");
            dict2.Remove("queztel");
            dict2.Add("hello", "banana");

            InterfaceTests.TestEnumerableElements(dict2.KeyValuePairs, new KeyValuePair<string, string>[] {
                new KeyValuePair<string,string>("Alpha", "oz"),
                new KeyValuePair<string,string>("hello", "banana"),
                new KeyValuePair<string,string>("Hello", "AAA"),
                new KeyValuePair<string,string>("Hi", "aaa"),
                new KeyValuePair<string,string>("qubert", "hoover"),
                new KeyValuePair<string,string>("qubert", "dinosaur")});

            OrderedMultiDictionary<string, int> dict4 = new OrderedMultiDictionary<string, int>(true);
            OrderedMultiDictionary<string, int> dict5;
            dict5 = dict4.Clone();
            Assert.IsFalse(dict4 == dict5);
            Assert.IsTrue(dict4.Count == 0 && dict5.Count == 0);
            dict4.Add("hello", 1);
            Assert.IsTrue(dict4.Count == 1 && dict5.Count == 0);
            dict5.Add("hi", 7);
            dict4.Clear();
            Assert.IsTrue(dict4.Count == 0 && dict5.Count == 1);
        }

        void CompareClones<K, V>(OrderedMultiDictionary<K, V> d1, OrderedMultiDictionary<K, V> d2)
        {
            IEnumerator<KeyValuePair<K, V>> e1 = d1.KeyValuePairs.GetEnumerator();
            IEnumerator<KeyValuePair<K, V>> e2 = d2.KeyValuePairs.GetEnumerator();

            // Check that the dictionaries are equal, but not reference equals (e.g., have been cloned).
            while (e1.MoveNext()) {
                e2.MoveNext();
                if (e1.Current.Key == null)
                    Assert.IsNull(e2.Current.Key);
                else {
                    Assert.IsTrue(e1.Current.Key.Equals(e2.Current.Key));
                    Assert.IsFalse(object.ReferenceEquals(e1.Current.Key, e2.Current.Key));
                }

                if (e1.Current.Value == null)
                    Assert.IsNull(e2.Current.Value);
                else {
                    Assert.IsTrue(e1.Current.Value.Equals(e2.Current.Value));
                    Assert.IsFalse(object.ReferenceEquals(e1.Current.Value, e2.Current.Value));
                }
            }
        }

        [Test]
        public void CloneContents()
        {
            Comparison<MyInt> myIntComparison = 
                delegate(MyInt v1, MyInt v2) { 
                    if (v1 == null) 
                        return (v2 == null) ? 0 : -1; 
                    else if (v2 == null)
                        return 1;
                    else
                        return v2.value.CompareTo(v1.value); 
                };

            OrderedMultiDictionary<int, MyInt> dict1 = new OrderedMultiDictionary<int, MyInt>(true,
                delegate(int v1, int v2) { return - v2.CompareTo(v1); },
                myIntComparison);

            dict1.Add(4, new MyInt(143));
            dict1.Add(7, new MyInt(2));
            dict1.Add(11, new MyInt(9));
            dict1.Add(7, new MyInt(119));
            dict1.Add(18, null);
            dict1.Add(4, new MyInt(16));
            dict1.Add(7, null);
            dict1.Add(7, new MyInt(119));
            OrderedMultiDictionary<int, MyInt> dict2 = dict1.CloneContents();
            CompareClones(dict1, dict2);

            OrderedMultiDictionary<MyInt, int> dict3 = new OrderedMultiDictionary<MyInt, int>(false, myIntComparison);

            dict3.Add(new MyInt(4), 143);
            dict3.Add(new MyInt(7), 2);
            dict3.Add(new MyInt(11), 9);
            dict3.Add(new MyInt(7), 119);
            dict3.Add(new MyInt(18), 0);
            dict3.Add(new MyInt(4), 16);
            dict3.Add(null, 11);
            dict3.Add(new MyInt(7), 119);

            OrderedMultiDictionary<MyInt, int> dict4 = dict3.CloneContents();
            CompareClones(dict3, dict4);

            Comparison<UtilTests.CloneableStruct> comparison = delegate(UtilTests.CloneableStruct s1, UtilTests.CloneableStruct s2) {
                return s1.value.CompareTo(s2.value);
            };
            OrderedMultiDictionary<UtilTests.CloneableStruct, UtilTests.CloneableStruct> dict5 = new OrderedMultiDictionary<UtilTests.CloneableStruct, UtilTests.CloneableStruct>(true, comparison, comparison);
            dict5.Add(new UtilTests.CloneableStruct(7) , new UtilTests.CloneableStruct(-14));
            dict5.Add(new UtilTests.CloneableStruct(16) , new UtilTests.CloneableStruct(13));
            dict5.Add(new UtilTests.CloneableStruct(7) , new UtilTests.CloneableStruct(-14));
            dict5.Add(new UtilTests.CloneableStruct(7) , new UtilTests.CloneableStruct(31415));
            dict5.Add(new UtilTests.CloneableStruct(1111) , new UtilTests.CloneableStruct(0));
            OrderedMultiDictionary<UtilTests.CloneableStruct, UtilTests.CloneableStruct> dict6 = dict5.CloneContents();

            IEnumerator<KeyValuePair<UtilTests.CloneableStruct, UtilTests.CloneableStruct>> e1 = dict5.KeyValuePairs.GetEnumerator();
            IEnumerator<KeyValuePair<UtilTests.CloneableStruct, UtilTests.CloneableStruct>> e2 = dict6.KeyValuePairs.GetEnumerator();

            Assert.IsTrue(dict5.Count == dict6.Count);

            // Check that the dictionaries are equal, but not identical (e.g., have been cloned).
            while (e1.MoveNext()) {
                e2.MoveNext();
                Assert.IsTrue(e1.Current.Key.Equals(e2.Current.Key));
                Assert.IsFalse(e1.Current.Key.Identical(e2.Current.Key));

                Assert.IsTrue(e1.Current.Value.Equals(e2.Current.Value));
                Assert.IsFalse(e1.Current.Value.Identical(e2.Current.Value));
            }
        }

        class NotCloneable: IComparable<NotCloneable>
        { 
            public int  CompareTo(NotCloneable other)
            {
               return 0;
            }

            public bool  Equals(NotCloneable other)
            {
               return true;
            }
        }

        [Test, ExpectedException(typeof(InvalidOperationException))]
        public void CantCloneContents()
        {
            OrderedMultiDictionary<int, NotCloneable> dict1 = new OrderedMultiDictionary<int, NotCloneable>(true);

            dict1[4] = new NotCloneable[] { new NotCloneable() };
            dict1[5] = new NotCloneable[] { new NotCloneable(), new NotCloneable() };

            OrderedMultiDictionary<int, NotCloneable> dict2 = dict1.CloneContents();
        }


        [Test]
        public void FailFastEnumerator()
        {
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true);

            dict1.Add("foo", 12);
            dict1.Add("foo", 15);
            dict1.Add("foo", 3);
            dict1.Add("foo", 12);
            dict1.Add("bar", 1);
            dict1.Add("bar", 17);

            int iter = 0;
            try {
                foreach (KeyValuePair<string, int> pair in dict1.KeyValuePairs) {
                    if (pair.Key == "foo")
                        dict1.Replace("bar", 19);
                    ++iter;
                }
            }
            catch (Exception e) {
                Assert.IsTrue(e is InvalidOperationException);
                Assert.AreEqual(3, iter);
            }

            iter = 0;
            try {
                foreach (string key in dict1.Keys) {
                    if (key == "foo")
                        dict1.Add("grump", 117);
                    ++iter;
                }
            }
            catch (Exception e) {
                Assert.IsTrue(e is InvalidOperationException);
                Assert.AreEqual(2, iter);
            }

            iter = 0;
            try {
                foreach (int value in dict1["foo"]) {
                    if (value == 12)
                        dict1.Remove("grump", 117);
                    ++iter;
                }
            }
            catch (Exception e) {
                Assert.IsTrue(e is InvalidOperationException);
                Assert.AreEqual(2, iter);
            }

            iter = 0;
            try {
                foreach (string key in dict1.Keys) {
                    if (key == "foo")
                        dict1.Clear();
                    ++iter;
                }
            }
            catch (Exception e) {
                Assert.IsTrue(e is InvalidOperationException);
                Assert.AreEqual(2, iter);
            }

        }

        [Test]
        public void KeyComparerProperty()
        {
            IComparer<int> comparer1 = new GOddEvenComparer();
            OrderedMultiDictionary<int, string> dict1 = new OrderedMultiDictionary<int, string>(false, comparer1);
            Assert.AreSame(comparer1, dict1.KeyComparer);
            OrderedMultiDictionary<decimal, string> dict2 = new OrderedMultiDictionary<decimal, string>(true);
            Assert.AreSame(Comparer<decimal>.Default, dict2.KeyComparer);
            OrderedMultiDictionary<string, string> dict3 = new OrderedMultiDictionary<string, string>(true, StringComparer.OrdinalIgnoreCase, StringComparer.CurrentCulture);
            Assert.AreSame(StringComparer.OrdinalIgnoreCase, dict3.KeyComparer);

            Comparison<int> comparison1 = ComparersTests.CompareOddEven;
            OrderedMultiDictionary<int, string> dict4 = new OrderedMultiDictionary<int, string>(true, comparison1);
            OrderedMultiDictionary<int, string> dict5 = new OrderedMultiDictionary<int, string>(false, comparison1, delegate(string x, string y) { return - x.CompareTo(y); });
            Assert.AreEqual(dict4.KeyComparer, dict5.KeyComparer);
            Assert.IsFalse(dict4.KeyComparer == dict5.KeyComparer);
            Assert.IsFalse(object.Equals(dict4.KeyComparer, dict1.KeyComparer));
            Assert.IsFalse(object.Equals(dict4.KeyComparer, Comparer<int>.Default));
            Assert.IsTrue(dict4.KeyComparer.Compare(7, 6) < 0);

            Assert.AreSame(dict1.KeyComparer, dict1.Clone().KeyComparer);
            Assert.AreSame(dict2.KeyComparer, dict2.Clone().KeyComparer);
            Assert.AreSame(dict3.KeyComparer, dict3.Clone().KeyComparer);
            Assert.AreSame(dict4.KeyComparer, dict4.Clone().KeyComparer);
            Assert.AreSame(dict5.KeyComparer, dict5.Clone().KeyComparer);
        }

        [Test]
        public void ValueComparerProperty()
        {
            IComparer<int> comparer1 = new GOddEvenComparer();
            OrderedMultiDictionary<string, int> dict1 = new OrderedMultiDictionary<string, int>(true, StringComparer.InvariantCulture, comparer1);
            Assert.AreSame(comparer1, dict1.ValueComparer);
            OrderedMultiDictionary<string, decimal> dict2 = new OrderedMultiDictionary<string, decimal>(false);
            Assert.AreSame(Comparer<decimal>.Default, dict2.ValueComparer);
            OrderedMultiDictionary<string, string> dict3 = new OrderedMultiDictionary<string, string>(true, StringComparer.InvariantCulture, StringComparer.OrdinalIgnoreCase);
            Assert.AreSame(StringComparer.OrdinalIgnoreCase, dict3.ValueComparer);

            Comparison<int> comparison1 = ComparersTests.CompareOddEven;
            OrderedMultiDictionary<string, int> dict4 = new OrderedMultiDictionary<string, int>(true, delegate(string x, string y) { return x.CompareTo(y); }, comparison1);
            OrderedMultiDictionary<string, int> dict5 = new OrderedMultiDictionary<string, int>(false, delegate(string x, string y) { return - x.CompareTo(y); }, comparison1);
            Assert.AreEqual(dict4.ValueComparer, dict5.ValueComparer);
            Assert.IsFalse(dict4.ValueComparer == dict5.ValueComparer);
            Assert.IsFalse(object.Equals(dict4.ValueComparer, dict1.ValueComparer));
            Assert.IsFalse(object.Equals(dict4.ValueComparer, Comparer<int>.Default));
            Assert.IsTrue(dict4.ValueComparer.Compare(7, 6) < 0);

            Assert.AreSame(dict1.ValueComparer, dict1.Clone().ValueComparer);
            Assert.AreSame(dict2.ValueComparer, dict2.Clone().ValueComparer);
            Assert.AreSame(dict3.ValueComparer, dict3.Clone().ValueComparer);
            Assert.AreSame(dict4.ValueComparer, dict4.Clone().ValueComparer);
            Assert.AreSame(dict5.ValueComparer, dict5.Clone().ValueComparer);
        }


        // Check the contents of a Multi-Dictionary non-destructively. Keys and Values must be in order.
        internal static void CheckView<TKey, TValue>(OrderedMultiDictionary<TKey, TValue>.View dict, TKey[] keys, TValue[][] values, TKey nonKey, TValue nonValue, bool cantAddNonKey, BinaryPredicate<TKey> keyEquals, BinaryPredicate<TValue> valueEquals)
        {
            int iKey, iValue;
            ICollection<TValue> getValues;

            if (keyEquals == null)
                keyEquals = delegate(TKey x, TKey y) { return object.Equals(x, y); };
            if (valueEquals == null)
                valueEquals = delegate(TValue x, TValue y) { return object.Equals(x, y); };

            // Check Count.
            Assert.AreEqual(keys.Length, dict.Count);

            // Check indexer, ContainsKey, Contains, TryGetValue for each key.
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                Assert.IsTrue(dict.ContainsKey(keys[iKey]));
                Assert.IsTrue(dict.Contains(new KeyValuePair<TKey, ICollection<TValue>>(keys[iKey], values[iKey])));

                bool b = ((IDictionary<TKey, ICollection<TValue>>)dict).TryGetValue(keys[iKey], out getValues);
                Assert.IsTrue(b);
                iValue = 0;
                foreach (TValue val in getValues) {
                    Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                    ++iValue;
                }

                iValue = 0;
                foreach (TValue val in values[iKey]) {
                    Assert.IsTrue(dict.Contains(keys[iKey], val));
                    ++iValue;
                }

                iValue = 0;
                foreach (TValue val in dict[keys[iKey]]) {
                    Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                    ++iValue;
                }
                Assert.IsTrue(iValue == values[iKey].Length);
            }

            // Check Keys collection.
            iKey = 0;
            foreach (TKey key in dict.Keys) {
                Assert.IsTrue(keyEquals(keys[iKey], key));
                ++iKey;
            }
            Assert.IsTrue(iKey == keys.Length);
            InterfaceTests.TestReadonlyCollectionGeneric<TKey>(dict.Keys, keys, true, null);

            // Check Values collection
            iKey = 0; iValue = 0;
            int valueCount = 0;
            foreach (TValue val in dict.Values) {
                Assert.IsTrue(valueEquals(values[iKey][iValue], val));
                ++iValue;
                if (iValue == values[iKey].Length) {
                    iValue = 0;
                    ++iKey;
                }
                ++valueCount;
            }
            Assert.IsTrue(iKey == keys.Length);

            int a = 0;
            TValue[] vals = new TValue[valueCount];
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                for (iValue = 0; iValue < values[iKey].Length; ++iValue) {
                    vals[a++] = values[iKey][iValue];
                }
            }
            InterfaceTests.TestReadonlyCollectionGeneric<TValue>(dict.Values, vals, true, null);

            // Check KeyValuePairs collection.
            iKey = 0; iValue = 0;
            valueCount = 0;
            foreach (KeyValuePair<TKey, TValue> pair in dict.KeyValuePairs) {
                Assert.IsTrue(keyEquals(keys[iKey], pair.Key));
                Assert.IsTrue(valueEquals(values[iKey][iValue], pair.Value));
                ++iValue;
                if (iValue == values[iKey].Length) {
                    iValue = 0;
                    ++iKey;
                }
                ++valueCount;
            }
            Assert.IsTrue(iKey == keys.Length);

            a = 0;
            KeyValuePair<TKey, TValue>[] pairs = new KeyValuePair<TKey, TValue>[valueCount];
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                for (iValue = 0; iValue < values[iKey].Length; ++iValue) {
                    pairs[a++] = new KeyValuePair<TKey, TValue>(keys[iKey], values[iKey][iValue]);
                }
            }
            InterfaceTests.TestReadonlyCollectionGeneric<KeyValuePair<TKey, TValue>>(dict.KeyValuePairs, pairs, true, null);

            // Tests Contains, ContainsKey, TryGetValue for wrong values.
            Assert.IsFalse(dict.ContainsKey(nonKey));
            Assert.IsFalse(((IDictionary<TKey, ICollection<TValue>>)dict).TryGetValue(nonKey, out getValues));
            Assert.AreEqual(0, dict[nonKey].Count);
            Assert.IsFalse(dict.Remove(nonKey));
            for (iKey = 0; iKey < keys.Length; ++iKey) {
                Assert.IsFalse(dict.Contains(keys[iKey], nonValue));
                Assert.IsFalse(dict.Contains(new KeyValuePair<TKey, ICollection<TValue>>(keys[iKey], new TValue[1] { nonValue })));
            }

            if (cantAddNonKey) {
                // Make sure Add throws exception
                try {
                    dict[nonKey] = new TValue[1] { nonValue };
                    Assert.Fail("should throw");
                }
                catch (Exception e) {
                    Assert.IsTrue(e is ArgumentException);
                }

                try {
                    dict.Add(nonKey, nonValue);
                    Assert.Fail("should throw");
                }
                catch (Exception e) {
                    Assert.IsTrue(e is ArgumentException);
                }
            }
            
            // Test IDictionary<TKey,IEnumerable<TValue>> implementation
            InterfaceTests.TestReadWriteMultiDictionaryGeneric<TKey, TValue>(dict, keys, values, nonKey, nonValue, true, "OrderedMultiDictionary", null, null);
        }

        [Test]
        public void RangeFrom()
        {
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);
            dict1.Add("gib", 1.1);

            CheckView<string, double>(dict1.RangeFrom("bar", true),
                new string[] { "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] { -9 } },
                null, 5.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("bar", false),
                new string[] { "foo", "gib", "S" },
                new double[][] { new double[] { -1.2, 3.5, 8.8 }, new double[] {1.1, 7.1 }, new double[] { -9 } },
                "bar", 9.8, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("alpha", false),
                new string[] { "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] { -9 } },
                "aaa", 5.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("hello", false),
                new string[] { "S" },
                new double[][] {new double[] { -9 } },
                "foo", 3.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("S", true),
                new string[] { "S" },
                new double[][] { new double[] { -9 } },
                "foo", 3.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("Z", true),
                new string[] {  },
                new double[][] { },
                "foo", 3.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("bar", true).Reversed(),
                new string[] { "S", "gib", "foo", "bar" },
                new double[][] {new double[] { -9 }, new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 },new double[] { 9.8 }   },
                "alpha", 5.5, true, null, null);

            CheckView<string, double>(dict1.RangeFrom("bar", false). Reversed(),
                new string[] { "S", "gib", "foo" },
                new double[][] { new double[] { -9 }, new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 } },
                "bar", 9.8, true, null, null);

        }

        [Test]
        public void RangeTo()
        {
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);
            dict1.Add("gib", 1.1);

            CheckView<string, double>(dict1.RangeTo("gib", true),
                new string[] { null, "bar", "foo", "gib" },
                new double[][] { new double[] {5.5, 11.1}, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 } },
                "S", -9, true, null, null);

            CheckView<string, double>(dict1.RangeTo("gib", false),
                new string[] { null, "bar", "foo" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 } },
                "gib", 1.1, true, null, null);

            CheckView<string, double>(dict1.RangeTo("Z", false),
                new string[] { null, "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] {-9} },
                "Zelda", -11, true, null, null);

            CheckView<string, double>(dict1.RangeTo(null, false),
                new string[] {  },
                new double[][] { },
                null, 5.5, true, null, null);

            CheckView<string, double>(dict1.RangeTo("gib", true).Reversed(),
                new string[] { "gib", "foo", "bar", null },
                new double[][] { new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 }, new double[] { 5.5, 11.1 }  },
                "S", -9, true, null, null);

            CheckView<string, double>(dict1.RangeTo("gib", false).Reversed(),
                new string[] { "foo", "bar", null },
                new double[][] { new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 }, new double[] { 5.5, 11.1 } },
                "gib", 1.1, true, null, null);

        }

        [Test]
        public void Range()
        {
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);
            dict1.Add("gib", 1.1);

            CheckView<string, double>(dict1.Range(null, true, "S", true),
                new string[] { null, "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] { -9 } },
                "Speedo", -14, true, null, null);

            CheckView<string, double>(dict1.Range(null, false, "S", true),
                new string[] { "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] { -9 } },
                null, -14, true, null, null);

            CheckView<string, double>(dict1.Range(null, true, "S", false),
                new string[] { null, "bar", "foo", "gib"},
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 } },
                "S", -9, true, null, null);

            CheckView<string, double>(dict1.Range(null, false, "S", false),
                new string[] { "bar", "foo", "gib" },
                new double[][] { new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 } },
                "Speedo", -14, true, null, null);


            CheckView<string, double>(dict1.Range(null, true, "S", true).Reversed(),
                new string[] {"S", "gib", "foo", "bar", null },
                new double[][] { new double[] { -9 }, new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 }, new double[] { 5.5, 11.1 } },
                "Speedo", -14, true, null, null);

            CheckView<string, double>(dict1.Range(null, false, "S", true).Reversed(),
                new string[] { "S", "gib", "foo", "bar" },
                new double[][] { new double[] { -9 }, new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 } },
                null, -14, true, null, null);

            CheckView<string, double>(dict1.Range(null, true, "S", false).Reversed(),
                new string[] { "gib", "foo", "bar", null },
                new double[][] { new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 }, new double[] { 5.5, 11.1 } },
                "S", -9, true, null, null);

            CheckView<string, double>(dict1.Range(null, false, "S", false).Reversed(),
                new string[] { "gib", "foo", "bar" },
                new double[][] { new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 } },
               "Speedo", -14, true, null, null);
        }

        [Test]
        public void Reversed()
        {
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);
            dict1.Add("gib", 1.1);

            CheckView<string, double>(dict1.Reversed(),
                new string[] {"S", "gib", "foo", "bar", null },
                new double[][] { new double[] { -9 }, new double[] { 1.1, 7.1 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 9.8 }, new double[] { 5.5, 11.1 } },
                "Speedo", -14, false, null, null);

            CheckView<string, double>(dict1.Reversed().Reversed(),
                new string[] { null, "bar", "foo", "gib", "S" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 }, new double[] { -9 } },
                "Speedo", -14, false, null, null);
        }

        [Test]
        public void RangeClear()
        {
            OrderedMultiDictionary<string, double> dict1 = new OrderedMultiDictionary<string, double>(false);
            OrderedMultiDictionary<string, double> dict2;

            dict1.Add("foo", 3.5);
            dict1.Add("foo", -1.2);
            dict1.Add(null, 11.1);
            dict1.Add("foo", 8.8);
            dict1.Add(null, 11.1);
            dict1.Add("bar", 9.8);
            dict1.Add("foo", 8.8);
            dict1.Add("gib", 7.1);
            dict1.Add("S", -9);
            dict1.Add(null, 5.5);
            dict1.Add("gib", 1.1);

            dict2 = dict1.Clone();
            dict2.Range("bar", false, "gib", true).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { null, "bar", "S" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -9 } },
                "foo", 3.5, null, null);

            dict2 = dict1.Clone();
            dict2.RangeTo("gib", true).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { "S" },
                new double[][] {new double[] { -9 } },
                "foo", 3.5, null, null);

            dict2 = dict1.Clone();
            dict2.RangeTo("gib", false).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { "gib", "S" },
                new double[][] {new double[] { 1.1, 7.1 }, new double[] { -9 } },
                "foo", 3.5, null, null);

            dict2 = dict1.Clone();
            dict2.RangeFrom("gib", false).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { null, "bar", "foo", "gib"},
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 }, new double[] { 1.1, 7.1 } },
                "S", 3.7, null, null);

            dict2 = dict1.Clone();
            dict2.RangeFrom("gib", true).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { null, "bar", "foo" },
                new double[][] { new double[] { 5.5, 11.1 }, new double[] { 9.8 }, new double[] { -1.2, 3.5, 8.8 } },
                "S", 3.7, null, null);

            dict2 = dict1.Clone();
            dict2.Range(null, true, "S", true).Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { },
                new double[][] { },
                "S", 3.7, null, null);

            dict2 = dict1.Clone();
            dict2.Reversed().Clear();
            CheckOrderedMultiDictionaryContents<string, double>(dict2,
                new string[] { },
                new double[][] {  },
                "S", 3.7, null, null);
        }

        [Test]
        public void SerializeStrings()
        {
            OrderedMultiDictionary<string, double> d = new OrderedMultiDictionary<string, double>(true, StringComparer.InvariantCultureIgnoreCase);

            d.Add("hEllo", 13);
            d.Add("foo", 7);
            d.Add("world", -9.5);
            d.Add("hello", 11);
            d.Add("elvis", 0.9);
            d.Add("ELVIS", 1.4);
            d.Add(null, 1.4);
            d.Add("FOO", 7);
            d.Add("hello", 12);

            OrderedMultiDictionary<string, double> result = (OrderedMultiDictionary<string, double>)InterfaceTests.SerializeRoundTrip(d);

            CheckOrderedMultiDictionaryContents<String, double>(result,
                new string[] { null, "eLVis", "FOO", "Hello", "WORLD" },
                new double[][] { new double[] { 1.4 }, new double[] { 0.9, 1.4 }, new double[] { 7, 7 }, new double[] { 11, 12, 13 }, new double[] { -9.5 } },
                "zippy", 123, StringComparer.InvariantCultureIgnoreCase.Equals, null);
        }

    }

}

www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.