public override string GenerateErrorMessage(TestEnvironment environment)
        {
            var expected = ((IEnumerable)environment.Expected).Cast<object>().ToArray();
            var actual = ((IEnumerable)environment.Actual).Cast<object>().ToArray();
            var codePart = environment.GetCodePart();
            var expectedFormattedValue = expected.Inspect();

            var missingFromExpected = actual.Where(a => !expected.Any(e => Is.Equal(e, a))).ToArray();
            var missingFromActual = expected.Where(e => !actual.Any(a => Is.Equal(e, a))).ToArray();

            var actualMissingMessage = missingFromActual.Any() ? string.Format("{0} is missing {1}", codePart,
                missingFromActual.Inspect()) : string.Empty;
            var expectedMissingMessage = missingFromExpected.Any() ? string.Format("{0} is missing {1}", expectedFormattedValue,
                missingFromExpected.Inspect()) : string.Empty;

            //"first should be second (ignoring order) but first is missing [4] and second is missing [2]"

            const string format = @"
            {0}
            {1}
            {2} (ignoring order)
            but
            {3}";

            string missingMessage = !string.IsNullOrEmpty(actualMissingMessage) && !string.IsNullOrEmpty(expectedMissingMessage)
                ? string.Format("{0} and {1}", actualMissingMessage, expectedMissingMessage)
                : string.Format("{0}{1}", actualMissingMessage, expectedMissingMessage);
            return string.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), expectedFormattedValue, missingMessage);
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0}
            should {1}be within
            {2}
            of
            {3}
            but was
            {4}";

            var codePart = environment.GetCodePart();
            var tolerance = environment.Tolerance.Inspect();
            var expectedValue = environment.Expected.Inspect();
            var actualValue = environment.Actual.Inspect();
            var negated = environment.ShouldMethod.Contains("Not") ? "not " : string.Empty;

            var message = string.Format(format, codePart, negated, tolerance, expectedValue, actualValue);

            if (environment.Actual.CanGenerateDifferencesBetween(environment.Expected))
            {
                message += string.Format(@"
            difference
            {0}",
                    environment.Actual.HighlightDifferencesBetween(environment.Expected));
            }

            return message;
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            Dictionary
            ""{0}""
            should contain key
            ""{1}""
            with value
            ""{2}""
            {3}";

            var codePart = environment.GetCodePart();
            var expectedValue = environment.Expected.Inspect();
            var actualValue = environment.Actual.Inspect();
            var keyValue = environment.Key.Inspect();

            if (environment.HasKey)
            {
                var valueString = string.Format("but value was \"{0}\"", actualValue.Trim('"'));
                return String.Format(format, codePart, keyValue.Trim('"'), expectedValue.Trim('"'), valueString);
            }
            else
            {
                return String.Format(format, codePart, actualValue.Trim('"'), expectedValue.Trim('"'), "but the key does not exist");
            }
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0} should satisfy all the conditions specified, but does not.
            The following errors were found ...
            {1}";

            var codePart = environment.GetCodePart();
            var expectedValue = environment.Expected.ToString();

            return String.Format(format, codePart, expectedValue);
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0}
            {1}
            but {2}
            was duplicated";

            var codePart = environment.GetCodePart();
            var actual = environment.Actual.Inspect();

            return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), actual);
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0}
            {1}";

            var codePart = environment.GetCodePart();

            var isNegatedAssertion = environment.ShouldMethod.Contains("Not");
            if (isNegatedAssertion)
                return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced());

            return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced());
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0}
            {1}
            but was {2}";

            var codePart = environment.GetCodePart();
            var expectedValue = environment.Expected.Inspect();

            if (environment.IsNegatedAssertion)
                return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), environment.Expected == null ? "null" : "");

            return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), expectedValue);
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            Dictionary
            ""{0}""
            {1}
            ""{2}""
            but does {3}";

            var codePart = environment.GetCodePart();
            var expectedValue = environment.Expected.Inspect();

            if (environment.IsNegatedAssertion)
                return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), environment.Expected, "");

            return String.Format(format, codePart, environment.ShouldMethod.PascalToSpaced(), expectedValue.Trim('"'), "not");
        }
        public override string GenerateErrorMessage(TestEnvironment environment)
        {
            const string format = @"
            {0}
            should {1}contain
            {2}
            within
            {3}
            but was
            {4}";

            var codePart = environment.GetCodePart();
            var tolerance = environment.Tolerance.Inspect();
            var expectedValue = environment.Expected.Inspect();
            var actualValue = environment.Actual.Inspect();
            var negated = environment.ShouldMethod.Contains("Not") ? "not " : string.Empty;

            return string.Format(format, codePart, negated, expectedValue, tolerance, actualValue);
        }