/// <summary>
        /// Verifies that `x.Equals(y)` 3 times on an instance of the type returns same
        /// value, if the supplied method is an override of the 
        /// <see cref="object.Equals(object)"/>.
        /// </summary>
        /// <param name="methodInfo">The method to verify</param>
        public override void Verify(MethodInfo methodInfo)
        {
            if (methodInfo == null)
                throw new ArgumentNullException("methodInfo");

            if (methodInfo.ReflectedType == null ||
                !methodInfo.IsObjectEqualsOverrideMethod())
            {
                // The method is not an override of the Object.Equals(object) method
                return;
            }

            var instance = this.builder.CreateAnonymous(methodInfo.ReflectedType);
            var other = this.builder.CreateAnonymous(methodInfo.ReflectedType);

            var results = Enumerable.Range(1, 3)
                .Select(i => instance.Equals(other))
                .ToArray();

            if (results.Any(result => result != results[0]))
            {
                throw new EqualsOverrideException(string.Format(CultureInfo.CurrentCulture,
                    "The type '{0}' overrides the object.Equals(object) method incorrectly, " +
                    "calling x.Equals(y) multiple times should return the same value.",
                    methodInfo.ReflectedType.FullName));
            }
        }
        /// <summary>
        /// Verifies that calling `x.Equals(null)` on the method returns false, if the supplied
        /// method is an override of the <see cref="object.Equals(object)"/>.
        /// </summary>
        /// <param name="methodInfo">The Equals method to verify</param>
        public override void Verify(MethodInfo methodInfo)
        {
            if (methodInfo == null)
                throw new ArgumentNullException("methodInfo");

            if (methodInfo.ReflectedType == null || 
                !methodInfo.IsObjectEqualsOverrideMethod())
            {
                // The method is not an override of the Object.Equals(object) method
                return;
            }

            var instance = this.builder.CreateAnonymous(methodInfo.ReflectedType);
            var equalsResult = instance.Equals(null);
            if (equalsResult)
            {
                throw new EqualsOverrideException(string.Format(CultureInfo.CurrentCulture,
                    "The type '{0}' overrides the object.Equals(object) method incorrectly, " +
                    "calling x.Equals(null) should return false.",
                    methodInfo.DeclaringType.FullName));
            }
        }
        public override void Verify(MethodInfo methodInfo)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException("methodInfo");
            }

            if (methodInfo.ReflectedType == null && !methodInfo.IsObjectEqualsOverrideMethod())
            {
                return;
            }

            var recordReplayBuilder = new RecordReplayConstructorSpecimensForTypeBuilder(builder,
                new ExactTypeSpecification(methodInfo.ReflectedType));

            var firstInstance = recordReplayBuilder.CreateInstanceOfType(methodInfo.ReflectedType);
            var secondInstance = recordReplayBuilder.CreateInstanceOfType(methodInfo.ReflectedType);
            var thirdInstance = recordReplayBuilder.CreateInstanceOfType(methodInfo.ReflectedType);

            var firstToSecondComparisonResult = firstInstance.Equals(secondInstance);
            var secondToThirdComparisonResult = secondInstance.Equals(firstInstance);
            var firstToThirdComparisonResult = firstInstance.Equals(thirdInstance);

            if ((firstToSecondComparisonResult && secondToThirdComparisonResult) != true)
            {
                throw new EqualsTransitiveException(
                    "Can't check transitive property of Equals implementation due to object created with the same values doesn't result true, propably they are performing identity check instead of value check");
            }

            if ((firstToSecondComparisonResult && secondToThirdComparisonResult) != firstToThirdComparisonResult)
            {
                throw new EqualsTransitiveException(string.Format(
                    "Equals implementation of type {0} is not transitive. It breaks following rule x.Equals(y) && y.Equals(z) == true then x.Equals(z) == true",
                    methodInfo.ReflectedType));
            }
        }