/// <summary>
        /// Converts to a <see cref="SqlParameter"/>.
        /// </summary>
        /// <param name="dateTimeOutputParameter">The nullable <see cref="DateTime"/> Output parameter.</param>
        /// <returns>SqlParameter.</returns>
        public static SqlParameter ToSqlParameter(
            this OutputParameterDefinition <DateTime?> dateTimeOutputParameter)
        {
            dateTimeOutputParameter.MustForArg(nameof(dateTimeOutputParameter)).NotBeNull();
            var name = dateTimeOutputParameter.Name;

            name = name.StartsWith("@", StringComparison.Ordinal) ? name : "@" + name;
            var result = SqlParameterExtensions.CreateOutputDateTimeSqlParameter(name);

            return(result);
        }
        /// <summary>
        /// Converts to a <see cref="SqlParameter"/>.
        /// </summary>
        /// <param name="decimalOutputParameter">The decimal Output parameter.</param>
        /// <returns>SqlParameter.</returns>
        public static SqlParameter ToSqlParameter(
            this OutputParameterDefinition <decimal> decimalOutputParameter)
        {
            decimalOutputParameter.MustForArg(nameof(decimalOutputParameter)).NotBeNull();
            var dataType = (DecimalSqlDataTypeRepresentation)decimalOutputParameter.SqlDataType;
            var name     = decimalOutputParameter.Name;

            name = name.StartsWith("@", StringComparison.Ordinal) ? name : "@" + name;
            var result = SqlParameterExtensions.CreateOutputDecimalSqlParameter(name, dataType.Precision, dataType.Scale);

            return(result);
        }
        /// <summary>
        /// Converts to a <see cref="SqlParameter"/>.
        /// </summary>
        /// <param name="binaryOutputParameter">The decimal Output parameter.</param>
        /// <returns>SqlParameter.</returns>
        public static SqlParameter ToSqlParameter(
            this OutputParameterDefinition <byte[]> binaryOutputParameter)
        {
            binaryOutputParameter.MustForArg(nameof(binaryOutputParameter)).NotBeNull();
            var dataType = (BinarySqlDataTypeRepresentation)binaryOutputParameter.SqlDataType;
            var name     = binaryOutputParameter.Name;

            name = name.StartsWith("@", StringComparison.Ordinal) ? name : "@" + name;
            var result = SqlParameterExtensions.CreateOutputByteArraySqlParameter(name, size: dataType.SupportedLength);

            return(result);
        }
        /// <summary>
        /// Converts to a <see cref="SqlParameter"/>.
        /// </summary>
        /// <param name="parameterDefinition">The parameter representation.</param>
        /// <returns>SqlParameter.</returns>
        public static SqlParameter ToSqlParameter(
            this ParameterDefinitionBase parameterDefinition)
        {
            parameterDefinition.MustForArg(nameof(parameterDefinition)).NotBeNull();

            if (parameterDefinition is InputParameterDefinition <byte[]> binaryRepresentationInput)
            {
                return(binaryRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <decimal> decimalRepresentationInput)
            {
                return(decimalRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <int> intRepresentationInput)
            {
                return(intRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <int?> intNullableRepresentationInput)
            {
                return(intNullableRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <long> longRepresentationInput)
            {
                return(longRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <long?> longNullableRepresentationInput)
            {
                return(longNullableRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <string> stringRepresentationInput)
            {
                return(stringRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <DateTime> dateTimeRepresentationInput)
            {
                return(dateTimeRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is InputParameterDefinition <DateTime?> dateTimeNullableRepresentationInput)
            {
                return(dateTimeNullableRepresentationInput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <byte[]> binaryRepresentationOutput)
            {
                return(binaryRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <decimal> decimalRepresentationOutput)
            {
                return(decimalRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <int> intRepresentationOutput)
            {
                return(intRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <int?> intNullableRepresentationOutput)
            {
                return(intNullableRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <long> longRepresentationOutput)
            {
                return(longRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <long?> longNullableRepresentationOutput)
            {
                return(longNullableRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <string> stringRepresentationOutput)
            {
                return(stringRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <DateTime> dateTimeRepresentationOutput)
            {
                return(dateTimeRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition is OutputParameterDefinition <DateTime?> dateTimeNullableRepresentationOutput)
            {
                return(dateTimeNullableRepresentationOutput.ToSqlParameter());
            }
            else if (parameterDefinition.GetType().GetGenericArguments().SingleOrDefault()?.IsEnum ?? false)
            {
                var genericDefinition = parameterDefinition.GetType().GetGenericTypeDefinition();
                if (genericDefinition == typeof(InputParameterDefinition <>))
                {
                    var enumValue = parameterDefinition.GetType()
                                    .GetProperty(nameof(InputParameterDefinition <string> .Value))
                                    ?.GetValue(parameterDefinition);
                    var stringParameter = new InputParameterDefinition <string>(parameterDefinition.Name, parameterDefinition.SqlDataType, enumValue?.ToString());
                    return(stringParameter.ToSqlParameter());
                }
                else if (genericDefinition == typeof(OutputParameterDefinition <>))
                {
                    var stringParameter = new OutputParameterDefinition <string>(parameterDefinition.Name, parameterDefinition.SqlDataType);
                    return(stringParameter.ToSqlParameter());
                }
                else
                {
                    throw new NotSupportedException(FormattableString.Invariant($"Param type {parameterDefinition.GetType().ToStringReadable()} is not supported."));
                }
            }
            else
            {
                throw new NotSupportedException(FormattableString.Invariant($"{nameof(ParameterDefinitionBase)} {nameof(parameterDefinition)} of type {parameterDefinition.GetType().ToStringReadable()} is not a supported type parameter."));
            }
        }
        static OutputParameterDefinitionTValueTest()
        {
            ConstructorArgumentValidationTestScenarios
            .RemoveAllScenarios()
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <OutputParameterDefinition <Version> >
            {
                Name             = "constructor should throw ArgumentNullException when parameter 'name' is null scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <OutputParameterDefinition <Version> >();

                    var result = new OutputParameterDefinition <Version>(
                        null,
                        referenceObject.SqlDataType);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentNullException),
                ExpectedExceptionMessageContains = new[] { "name", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <OutputParameterDefinition <Version> >
            {
                Name             = "constructor should throw ArgumentException when parameter 'name' is white space scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <OutputParameterDefinition <Version> >();

                    var result = new OutputParameterDefinition <Version>(
                        Invariant($"  {Environment.NewLine}  "),
                        referenceObject.SqlDataType);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentException),
                ExpectedExceptionMessageContains = new[] { "name", "white space", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <OutputParameterDefinition <Version> >
            {
                Name             = "constructor should throw ArgumentException when parameter 'name' is not alphanumeric nor @ nor _",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <OutputParameterDefinition <Version> >();

                    var result = new OutputParameterDefinition <Version>(
                        referenceObject.Name + "^",
                        referenceObject.SqlDataType);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentException),
                ExpectedExceptionMessageContains = new[] { "name", "alphanumeric", },
            })
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <OutputParameterDefinition <Version> >
            {
                Name             = "constructor should throw ArgumentNullException when parameter 'sqlDataType' is null scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <OutputParameterDefinition <Version> >();

                    var result = new OutputParameterDefinition <Version>(
                        referenceObject.Name,
                        null);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentNullException),
                ExpectedExceptionMessageContains = new[] { "sqlDataType", },
            });

            EquatableTestScenarios
            .RemoveAllScenarios()
            .AddScenario(() =>
                         new EquatableTestScenario <OutputParameterDefinition <Version> >
            {
                Name            = "Default Code Generated Scenario",
                ReferenceObject = ReferenceObjectForEquatableTestScenarios,
                ObjectsThatAreEqualToButNotTheSameAsReferenceObject = new OutputParameterDefinition <Version>[]
                {
                    new OutputParameterDefinition <Version>(
                        ReferenceObjectForEquatableTestScenarios.Name,
                        ReferenceObjectForEquatableTestScenarios.SqlDataType),
                },
                ObjectsThatAreNotEqualToReferenceObject = new OutputParameterDefinition <Version>[]
                {
                    new OutputParameterDefinition <Version>(
                        A.Dummy <OutputParameterDefinition <Version> >().Whose(_ => !_.Name.IsEqualTo(ReferenceObjectForEquatableTestScenarios.Name)).Name,
                        ReferenceObjectForEquatableTestScenarios.SqlDataType),
                },
                ObjectsThatAreNotOfTheSameTypeAsReferenceObject = new object[]
                {
                    A.Dummy <object>(),
                    A.Dummy <string>(),
                    A.Dummy <int>(),
                    A.Dummy <Version>(),
                    A.Dummy <Guid>(),
                    A.Dummy <InputParameterDefinition <Version> >(),
                },
            });
        }