/// <summary>
    /// Determines whether the source contains the same elements as the specified sequence in any order.
    /// Both enumerable sequences must contain the exact same count of each element for this to return true.
    /// </summary>
    /// <typeparam name="T">The type of the enumerable values.</typeparam>
    /// <param name="source">The source enumerable to check.</param>
    /// <param name="contains">The sequence of elements to check the source for in any order.</param>
    /// <param name="comparer">The comparer to use for equality checks.</param>
    /// <returns>True if the sequence contains the same elements in any order; otherwise false.</returns>
    public static bool ElementsEqualPerOccurrence <T>(
        this IEnumerable <T> source, IEnumerable <T> contains, IEqualityComparer <T> comparer)
    {
        Contracts.Requires.That(source != null);
        Contracts.Requires.That(contains != null);
        Contracts.Requires.That(comparer != null);

        var sourceCount   = new CountingCollection <T>(source, comparer);
        var sequenceCount = new CountingCollection <T>(contains, comparer);

        return(sourceCount.ContainsSameCountAs(sequenceCount));
    }
    /// <summary>
    /// Removes the elements from the specified enumerable on a per occurrence basis from this enumerable.
    /// </summary>
    /// <typeparam name="T">The type of enumerable values.</typeparam>
    /// <param name="source">The source enumerable to subtract from.</param>
    /// <param name="subtract">The enumerable of elements to subtract.</param>
    /// <param name="comparer">The comparer to use for equality checks.</param>
    /// <returns>An enumeration of the remaining elements after subtracting.</returns>
    /// <remarks>
    /// <para>
    /// Per occurrence subtraction means for example that if the subtract enumerable contains an element once
    /// and the source enumerable contains it twice, the result from subtracting will contain the element once.
    /// </para><para>
    /// The resulting enumerable makes no guarantees about the order in which the resulting elements are enumerated.
    /// </para>
    /// </remarks>
    public static IEnumerable <T> RemovePerOccurrence <T>(
        this IEnumerable <T> source, IEnumerable <T> subtract, IEqualityComparer <T> comparer)
    {
        Contracts.Requires.That(source != null);
        Contracts.Requires.That(subtract != null);
        Contracts.Requires.That(comparer != null);

        var sourceCount   = new CountingCollection <T>(source, comparer);
        var subtractCount = new CountingCollection <T>(subtract, comparer);

        sourceCount.SubtractCountFrom(subtractCount);
        return(sourceCount.Expand);
    }
    /// <summary>
    /// Determines whether the source contains the elements from the specified enumerable on a per occurrence basis.
    /// </summary>
    /// <typeparam name="T">The type of the enumerable values.</typeparam>
    /// <param name="source">The source enumerable to check.</param>
    /// <param name="contains">The sequence of elements to check the source for.</param>
    /// <param name="comparer">The comparer to use for equality checks.</param>
    /// <returns>True if the sequence contains the same element counts in any order; otherwise false.</returns>
    public static bool ContainsPerOccurrence <T>(
        this IEnumerable <T> source, IEnumerable <T> contains, IEqualityComparer <T> comparer)
    {
        Contracts.Requires.That(source != null);
        Contracts.Requires.That(contains != null);
        Contracts.Requires.That(comparer != null);

        var containsCount = new CountingCollection <T>(contains, comparer);

        foreach (T value in source)
        {
            if (containsCount.Remove(value) && containsCount.Count == 0)
            {
                return(true);
            }
        }

        // still something left in containsCount
        return(false);
    }