/// <summary>
        /// Implementation of IEquatable
        /// </summary>
        /// <param name="other">The other IFingerprint object to compare against</param>
        /// <returns>true if 2 objects are fully equivalent</returns>
        public bool Equals(IFingerprint other)
        {
            if (other == null)
            {
                return(false);
            }

            // Our check only works for ScanResultFingerprint objects
            ScanResultFingerprint typedOther = other as ScanResultFingerprint;

            if (typedOther == null)
            {
                return(false);
            }

            if (TypedCompareTo(typedOther) != 0)
            {
                return(false);
            }

            // Do the expensive check last!
            for (int loop = 0; loop < Contributions.Count; loop++)
            {
                if (!Contributions[loop].Equals(other.Contributions[loop]))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Strongly typed version of CompareTo. Used by both CompareTo and Equals
        /// </summary>
        /// <param name="other">The other object to consider for comparison</param>
        /// <returns>-1: this is before other
        ///           0: this is in same position as other
        ///           1: this is after other</returns>
        private int TypedCompareTo(ScanResultFingerprint other)
        {
            int hash      = GetHashCode();
            int otherHash = other.GetHashCode();

            if (Contributions.Count == other.Contributions.Count)
            {
                return(hash.CompareTo(otherHash));
            }

            return(Contributions.Count.CompareTo(other.Contributions.Count));
        }
        /// <summary>
        /// Implementation of IComparable
        /// </summary>
        /// <param name="other">The other object to consider for comparison</param>
        /// <returns>-1: this is before other
        ///           0: this is in same position as other
        ///           1: this is after other</returns>
        public int CompareTo(IFingerprint other)
        {
            other.ArgumentIsNotNull(nameof(other));

            ScanResultFingerprint typedOther = other as ScanResultFingerprint;

            if (typedOther == null)
            {
                throw new InvalidOperationException("This operation is only supported on ScanResultFingerprint objects");
            }

            return(TypedCompareTo(typedOther));
        }