private static bool CompareMethodCallExpectedCollectionArgument <T>(IEnumerable <T> expectedValues, IEnumerable <T> recordedValues, IEqualityComparerFactory equalityComparerFactory)
        {
            IEqualityComparer <T> equalityComparer = equalityComparerFactory.GetEqualityComparer <T>();

            List <T> expectedValuesList = new List <T>(expectedValues);
            List <T> recordedValuesList = new List <T>(recordedValues);

            while (expectedValuesList.Any())
            {
                T expectedValue = expectedValuesList.First();

                List <T> foundExpectedValues = expectedValuesList.FindAll(v => equalityComparer.Equals(expectedValue, v));
                List <T> foundRecordedValues = recordedValuesList.FindAll(v => equalityComparer.Equals(expectedValue, v));

                if (foundExpectedValues.Count != foundRecordedValues.Count)
                {
                    return(false);
                }

                expectedValuesList.RemoveRange(foundExpectedValues);
                recordedValuesList.RemoveRange(foundRecordedValues);
            }

            return(recordedValuesList.Count == 0);
        }
        private static bool CompareMethodCallDictionaryArgument <TKey, TValue>(IEnumerable <KeyValuePair <TKey, TValue> > expectedValues, IEnumerable <KeyValuePair <TKey, TValue> > recordedValues, IEqualityComparerFactory equalityComparerFactory)
        {
            IEqualityComparer <TValue> equalityComparer = equalityComparerFactory.GetEqualityComparer <TValue>();

            Dictionary <TKey, TValue> expectedDictionary = new Dictionary <TKey, TValue>();
            Dictionary <TKey, TValue> recordedDictionary = new Dictionary <TKey, TValue>();

            foreach (var expectedValue in expectedValues)
            {
                expectedDictionary.Add(expectedValue.Key, expectedValue.Value);
            }

            foreach (var recordedValue in recordedValues)
            {
                recordedDictionary.Add(recordedValue.Key, recordedValue.Value);
            }

            while (expectedDictionary.Any())
            {
                var expectedPair = expectedDictionary.First();

                TValue recordedValue;

                if (!recordedDictionary.TryGetValue(expectedPair.Key, out recordedValue))
                {
                    return(false);
                }

                if (!equalityComparer.Equals(expectedPair.Value, recordedValue))
                {
                    return(false);
                }

                expectedDictionary.Remove(expectedPair.Key);
                recordedDictionary.Remove(expectedPair.Key);
            }

            return(!recordedDictionary.Any());
        }
        private static bool CompareMethodCallArgument <T>(T expectedValue, T recordedValue, IEqualityComparerFactory equalityComparerFactory)
        {
            if (typeof(T).IsGenericType)
            {
                string assertMethodCallCollectionArgumentMethodName = null;

                if (typeof(T).GetGenericTypeDefinition() == typeof(IEnumerable <>))
                {
                    IExpectedCollection expectedCollection = expectedValue as IExpectedCollection;

                    if (expectedCollection == null)
                    {
                        throw new NotSupportedException("Cannot compare collection of type {0}. Use {1} instead.".FormatInvariant(expectedValue.GetType().Name, typeof(IExpectedCollection).Name));
                    }

                    assertMethodCallCollectionArgumentMethodName = expectedCollection.IsOrdered ? "CompareMethodCallExpectedOrderedCollectionArgument" : "CompareMethodCallExpectedCollectionArgument";
                }
                else if ((typeof(T).GetGenericTypeDefinition() == typeof(IReadOnlyDictionary <,>)) || (typeof(T).GetGenericTypeDefinition() == typeof(IDictionary <,>)))
                {
                    assertMethodCallCollectionArgumentMethodName = "CompareMethodCallDictionaryArgument";
                }

                if (!string.IsNullOrEmpty(assertMethodCallCollectionArgumentMethodName))
                {
                    MethodInfo compareCollectionsMethod = typeof(UnitTestHelpers).GetMethod(assertMethodCallCollectionArgumentMethodName, BindingFlags.Static | BindingFlags.NonPublic);

                    compareCollectionsMethod = compareCollectionsMethod.MakeGenericMethod(typeof(T).GetGenericArguments());

                    return((bool)compareCollectionsMethod.Invoke(null, new object[] { expectedValue, recordedValue, equalityComparerFactory }));
                }
            }

            IEqualityComparer <T> equalityComparer = equalityComparerFactory.GetEqualityComparer <T>();

            return(equalityComparer.Equals(expectedValue, recordedValue));
        }