private static void Throw(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemTypeReadableString = verifiableItem.ItemType.ToStringReadable();

            WorkflowExtensions.ThrowImproperUseOfFramework(Invariant($"verificationName: {verification.Name}, isElementInEnumerable: {verifiableItem.ItemIsElementInEnumerable}, verifiableItemTypeName: {verifiableItemTypeReadableString}"));
        }
 private static void ThrowIfTypeDoesNotHaveWorkingDefaultComparer(
     Verification verification,
     VerifiableItem verifiableItem,
     TypeValidation typeValidation)
 {
     if (!verifiableItem.ItemType.HasWorkingDefaultComparer())
     {
         ThrowSubjectUnexpectedType(verification, verifiableItem, AnyTypeWithWorkingDefaultComparerName);
     }
 }
 private static void ThrowIfValueType(
     Verification verification,
     VerifiableItem verifiableItem,
     TypeValidation typeValidation)
 {
     if (verifiableItem.ItemType.IsValueType)
     {
         ThrowSubjectUnexpectedType(verification, verifiableItem, AnyReferenceTypeName);
     }
 }
        private static void ThrowIfTypeCannotBeAssignedToNull(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            if (!verifiableItemType.IsClosedTypeAssignableToNull())
            {
                ThrowSubjectUnexpectedType(verification, verifiableItem, AnyReferenceTypeName, NullableGenericTypeName);
            }
        }
        private static void ThrowIfNotEqualToType(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            var validTypes = typeValidation.ReferenceTypes;

            if (validTypes.All(_ => verifiableItemType != _))
            {
                ThrowSubjectUnexpectedType(verification, verifiableItem, validTypes);
            }
        }
        private static void ThrowIfNotAssignableToType(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            var validTypes = typeValidation.ReferenceTypes;

            if (!validTypes.Any(_ => verifiableItemType.IsAssignableTo(_, treatGenericTypeDefinitionAsAssignableTo: true)))
            {
                ThrowSubjectUnexpectedType(verification, verifiableItem, validTypes);
            }
        }
        private static void ThrowIfDictionaryValueTypeCannotBeAssignedToNull(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            var dictionaryValueType = verifiableItemType.GetClosedDictionaryValueType();

            if (!dictionaryValueType.IsClosedTypeAssignableToNull())
            {
                ThrowSubjectUnexpectedType(verification, verifiableItem, DictionaryTypeName, DictionaryWithValueOfAnyReferenceTypeName, DictionaryWithValueOfNullableGenericTypeName, ReadOnlyDictionaryWithValueOfAnyReferenceTypeName, ReadOnlyDictionaryWithValueOfNullableGenericTypeName);
            }
        }
        private static void ThrowIfEnumerableElementTypeCannotBeAssignedToNull(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            var elementType = verifiableItemType.GetClosedEnumerableElementType();

            if (!elementType.IsClosedTypeAssignableToNull())
            {
                ThrowSubjectUnexpectedType(verification, verifiableItem, EnumerableOfAnyReferenceTypeName, EnumerableOfNullableGenericTypeName, EnumerableWhenNotEnumerableOfAnyValueTypeName);
            }
        }
        private static void ThrowIfDictionaryKeyTypeDoesNotEqualAllVerificationParameterTypes(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var keyType = verifiableItem.ItemType.GetClosedDictionaryKeyType();

            foreach (var verificationParameter in verification.VerificationParameters)
            {
                if (verificationParameter.ParameterType != keyType)
                {
                    ThrowVerificationParameterUnexpectedType(verification.Name, verificationParameter.ParameterType, verificationParameter.Name, keyType);
                }
            }
        }
        private static void ThrowIfEnumerableElementTypeDoesNotEqualAllVerificationParameterTypes(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var elementType = verifiableItem.ItemType.GetClosedEnumerableElementType();

            foreach (var verificationParameter in verification.VerificationParameters)
            {
                if (verificationParameter.ParameterType != elementType)
                {
                    ThrowVerificationParameterUnexpectedType(verification.Name, verificationParameter.ParameterType, verificationParameter.Name, elementType);
                }
            }
        }
        private static void ThrowIfTypeIsNotEqualToAllVerificationParameterType(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            foreach (var verificationParameter in verification.VerificationParameters)
            {
                if (verificationParameter.ParameterType != verifiableItemType)
                {
                    ThrowVerificationParameterUnexpectedType(verification.Name, verificationParameter.ParameterType, verificationParameter.Name, verifiableItemType);
                }
            }
        }
        private static void ThrowIfTypeIsNotEqualToAllVerificationParameterEnumerableElementTypes(
            Verification verification,
            VerifiableItem verifiableItem,
            TypeValidation typeValidation)
        {
            var verifiableItemType = verifiableItem.ItemType;

            foreach (var verificationParameter in verification.VerificationParameters)
            {
                var elementType = verificationParameter.ParameterType.GetClosedEnumerableElementType();

                if (verifiableItemType != elementType)
                {
                    var expectedType = verificationParameter.ParameterType.GetGenericTypeDefinition().MakeGenericType(verifiableItemType);

                    ThrowVerificationParameterUnexpectedType(verification.Name, verificationParameter.ParameterType, verificationParameter.Name, expectedType);
                }
            }
        }