/// <summary>
        /// You may override this method to provide your own comparison routine.
        /// </summary>
        protected virtual bool HasSameSignatureAs(ComparableObject compareTo)
        {
            if (compareTo == null)
            {
                return(false);
            }

            var signatureProperties = GetSignatureProperties();

            foreach (var pi in signatureProperties)
            {
                object thisValue = pi.GetValue(this);
                object thatValue = pi.GetValue(compareTo);

                if (thisValue == null && thatValue == null)
                {
                    continue;
                }

                if (thisValue == null ^ thatValue == null ||
                    !thisValue.Equals(thatValue))
                {
                    return(false);
                }
            }

            // If we've gotten this far and signature properties were found, then we can
            // assume that everything matched; otherwise, if there were no signature
            // properties, then simply return the default bahavior of Equals
            return(signatureProperties.Any() || base.Equals(compareTo));
        }
        public override bool Equals(object obj)
        {
            ComparableObject compareTo = obj as ComparableObject;

            if (ReferenceEquals(this, compareTo))
            {
                return(true);
            }

            return(compareTo != null && GetType().Equals(compareTo.GetTypeUnproxied()) &&
                   HasSameSignatureAs(compareTo));
        }