/// <summary>
        /// Tests whether two collections contain the same elements and throws an exception if either collection contains an element not in the other collection.
        /// </summary>
        /// <param name="expected">
        /// The first collection to compare. This contains the elements the test expects.
        /// </param>
        /// <param name="actual">
        /// The second collection to compare. This is the collection produced by the code under test.
        /// </param>
        /// <exception cref="T:Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException">
        /// Thrown if an element was found in one of the collections but not the other.
        /// </exception>
        public static void AreEnumerablesEquivalent <TItem>(IEnumerable <TItem> expected, IEnumerable <TItem> actual)
        {
            if ((expected == null) != (actual == null))
            {
                Assert.Fail(
                    $"{nameof(CollectionAsserter.AreEnumerablesEquivalent)} failed. Cannot compare enumerables for equivalency as {nameof(expected)} or {nameof(actual)} provided is null.");
            }

            if (CollectionAsserter.Equals(expected, actual))
            {
                return;
            }

            var expectedList = expected.ToList();
            var actualList   = actual.ToList();

            if (expectedList.Count != actualList.Count)
            {
                Assert.Fail(
                    $"{nameof(CollectionAsserter.AreEnumerablesEquivalent)} failed. The number of elements are different.");
            }

            if (expectedList.Count == 0 || !FindMismatchedElement(
                    expectedList,
                    actualList,
                    out _,
                    out _,
                    out object mismatchedElement))
            {
                return;
            }

            Assert.Fail(
                $"{nameof(CollectionAsserter.AreEnumerablesEquivalent)} failed. The collections contain mismatched elements. {mismatchedElement ?? "Element was null."}");
        }
        /// <summary>
        /// Tests whether the specified enumerables are equal and throws an exception if the two enumerables are not equal. Equality is defined as having the same elements, compared using the given <see cref="IComparer"/>, in the same order and same quantity.
        /// </summary>
        /// <typeparam name="T">
        /// The type associated with items in the enumerable.
        /// </typeparam>
        /// <param name="expected">
        /// The first collection to compare. This is the collection the tests expects.
        /// </param>
        /// <param name="actual">
        /// The second collection to compare. This is the collection produced by the code under test.
        /// </param>
        /// <param name="comparer">
        /// The compare implementation to use when comparing elements of the collection.
        /// </param>
        /// <exception cref="T:Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException">
        /// Thrown if <paramref name="expected"/> is not equal to <paramref name="actual"/>.
        /// </exception>
        public static void AreEnumerablesEqual <T>(IEnumerable <T> expected, IEnumerable <T> actual, IComparer comparer)
        {
            string reason = string.Empty;

            if (CollectionAsserter.CompareEnumerables(expected, actual, comparer, ref reason))
            {
                return;
            }

            Assert.Fail($"{nameof(CollectionAsserter.AreEnumerablesEqual)} failed. {reason}");
        }
        private static bool CompareEnumerables <TType>(
            IEnumerable <TType> expected,
            IEnumerable <TType> actual,
            IComparer comparer,
            ref string reason)
        {
            if (comparer == null)
            {
                Assert.Fail($"Cannot compare enumerables as the {nameof(comparer)} provided is null.");
            }

            if (CollectionAsserter.Equals(expected, actual))
            {
                reason = "Both enumerables are the same reference.";
                return(true);
            }

            if (expected == null || actual == null)
            {
                return(false);
            }

            var expectedList = expected.ToList();
            var actualList   = actual.ToList();

            if (expectedList.Count != actualList.Count)
            {
                reason = "The number of elements are different.";
                return(false);
            }

            IEnumerator enumerator1 = expectedList.GetEnumerator();
            IEnumerator enumerator2 = actualList.GetEnumerator();
            int         num         = 0;

            while (enumerator1.MoveNext() && enumerator2.MoveNext())
            {
                if (comparer.Compare(enumerator1.Current, enumerator2.Current) != 0)
                {
                    return(false);
                }

                ++num;
            }

            reason = "Both enumerables contain the same elements.";
            return(true);
        }