public bool Equals(T x, T y)
 {
     if (!typeof(T).IsValueType ||
         (typeof(T).IsGenericType &&
          typeof(T).GetGenericTypeDefinition().IsAssignableFrom(typeof(Nullable <>))))
     {
         if (Object.Equals(x, default(T)))
         {
             return(Object.Equals(y, default(T)));
         }
         if (Object.Equals(y, default(T)))
         {
             return(false);
         }
     }
     if (x.GetType() != y.GetType())
     {
         return(false);
     }
     if (x is IEnumerable && y is IEnumerable)
     {
         GenericEqualityComparer <object> Comparer = new GenericEqualityComparer <object>();
         IEnumerator XEnumerator = ((IEnumerable)x).GetEnumerator();
         IEnumerator YEnumerator = ((IEnumerable)y).GetEnumerator();
         while (true)
         {
             bool XFinished = !XEnumerator.MoveNext();
             bool YFinished = !YEnumerator.MoveNext();
             if (XFinished || YFinished)
             {
                 return(XFinished & YFinished);
             }
             if (!Comparer.Equals(XEnumerator.Current, YEnumerator.Current))
             {
                 return(false);
             }
         }
     }
     if (x is IEquatable <T> )
     {
         return(((IEquatable <T>)x).Equals(y));
     }
     if (x is IComparable <T> )
     {
         return(((IComparable <T>)x).CompareTo(y) == 0);
     }
     if (x is IComparable)
     {
         return(((IComparable)x).CompareTo(y) == 0);
     }
     return(x.Equals(y));
 }
        /// <summary>
        /// Determines if the two items are equal
        /// </summary>
        /// <param name="x">Object 1</param>
        /// <param name="y">Object 2</param>
        /// <returns>True if they are, false otherwise</returns>
        public bool Equals(T x, T y)
        {
            if (!typeof(T).IsValueType ||
                (typeof(T).IsGenericType &&
                 typeof(T).GetGenericTypeDefinition().IsAssignableFrom(typeof(Nullable <>))))
            {
                if (Object.Equals(x, default(T)))
                {
                    return(Object.Equals(y, default(T)));
                }
                if (Object.Equals(y, default(T)))
                {
                    return(false);
                }
            }
            if (x.GetType() != y.GetType())
            {
                return(false);
            }
            var IEnumerablex = x as IEnumerable;
            var IEnumerabley = y as IEnumerable;

            if (IEnumerablex != null && IEnumerabley != null)
            {
                var         Comparer    = new GenericEqualityComparer <object>();
                IEnumerator XEnumerator = IEnumerablex.GetEnumerator();
                IEnumerator YEnumerator = IEnumerabley.GetEnumerator();
                while (true)
                {
                    bool XFinished = !XEnumerator.MoveNext();
                    bool YFinished = !YEnumerator.MoveNext();
                    if (XFinished || YFinished)
                    {
                        return(XFinished & YFinished);
                    }
                    if (!Comparer.Equals(XEnumerator.Current, YEnumerator.Current))
                    {
                        return(false);
                    }
                }
            }
            var TempEquality = x as IEqualityComparer <T>;

            if (TempEquality != null)
            {
                return(TempEquality.Equals(y));
            }
            var TempComparable = x as IComparable <T>;

            if (TempComparable != null)
            {
                return(TempComparable.CompareTo(y) == 0);
            }
            var TempComparable2 = x as IComparable;

            if (TempComparable2 != null)
            {
                return(TempComparable2.CompareTo(y) == 0);
            }
            return(x.Equals(y));
        }