/// <summary>
        /// Returns true iff the given Collections contain exactly the same elements with exactly the same cardinalities.
        /// i.e.,, iff the cardinality of e in a is equal to the cardinality of e in b, for each element e in a or b.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="a">a - the first collection, must not be null</param>
        /// <param name="b">b - the second collection, must not be null</param>
        /// <returns>true iff the collections contain the same elements with the same cardinalities.</returns>
        public static bool IsEqualCollection <T>(ICollection <T> a, ICollection <T> b)
        {
            if (a.Count() != b.Count())
            {
                return(false);
            }
            var helper = new CardinalityHelper <T>(a, b);

            return(helper.CardinalityA.Count() == helper.CardinalityB.Count() && helper.CardinalityA.Keys.All(obj => helper.FreqA(obj) == helper.FreqB(obj)));
        }
        /// <summary>
        /// Returns true iff a is a sub-collection of b, that is, iff the cardinality of e in a is less than or equal to the cardinality of e in b, for each element e in a.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="a">a - the first (sub?) collection, must not be null</param>
        /// <param name="b">b - the second (super?) collection, must not be null</param>
        /// <returns>true iff a is a sub-collection of b</returns>
        public static bool IsSubCollection <T>(ICollection <T> a, ICollection <T> b)
        {
            CardinalityHelper <T> helper = new CardinalityHelper <T>(a, b);

            return(a.All(obj => helper.FreqA(obj) <= helper.FreqB(obj)));
        }