static SqlOutputParameterResultTValueTest()
        {
            ConstructorArgumentValidationTestScenarios
            .RemoveAllScenarios()
            .AddScenario(() =>
                         new ConstructorArgumentValidationTestScenario <SqlOutputParameterResult <Version> >
            {
                Name             = "constructor should throw ArgumentNullException when parameter 'outputParameter' is null scenario",
                ConstructionFunc = () =>
                {
                    var referenceObject = A.Dummy <SqlOutputParameterResult <Version> >();

                    var result = new SqlOutputParameterResult <Version>(
                        null,
                        referenceObject.Value);

                    return(result);
                },
                ExpectedExceptionType            = typeof(ArgumentNullException),
                ExpectedExceptionMessageContains = new[] { "outputParameter", },
            });
        }
        /// <summary>
        /// Creates a <see cref="ISqlOutputParameterResult"/> with the provided result.
        /// </summary>
        /// <param name="outputParameterDefinition">The output parameter representation.</param>
        /// <param name="valueFromActualStoredProcedureParameter">The value from actual stored procedure parameter.</param>
        /// <returns>A <see cref="ISqlOutputParameterResult"/> with the provided result.</returns>
        public static ISqlOutputParameterResult CreateResult(
            this OutputParameterDefinitionBase outputParameterDefinition,
            object valueFromActualStoredProcedureParameter)
        {
            // accommodate DBNull situation here.
            var rawValue = DBNull.Value.Equals(valueFromActualStoredProcedureParameter) ? null : valueFromActualStoredProcedureParameter;

            ISqlOutputParameterResult result = null;

            if (outputParameterDefinition is OutputParameterDefinition <byte[]> byteArrayOutputParameterRepresentation)
            {
                var byteArrayValue = (byte[])rawValue;
                result = new SqlOutputParameterResult <byte[]>(byteArrayOutputParameterRepresentation, byteArrayValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <decimal> decimalOutputParameterRepresentation)
            {
                rawValue.MustForArg(nameof(rawValue)).NotBeNull();
                var decimalValue = Convert.ToDecimal(rawValue, CultureInfo.InvariantCulture);
                result = new SqlOutputParameterResult <decimal>(decimalOutputParameterRepresentation, decimalValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <int> intOutputParameterRepresentation)
            {
                rawValue.MustForArg(nameof(rawValue)).NotBeNull();
                var intValue = Convert.ToInt32(rawValue, CultureInfo.InvariantCulture);
                result = new SqlOutputParameterResult <int>(intOutputParameterRepresentation, intValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <int?> nullableIntOutputParameterRepresentation)
            {
                var intValue = rawValue == null ? (int?)null : Convert.ToInt32(rawValue, CultureInfo.InvariantCulture);
                result = new SqlOutputParameterResult <int?>(nullableIntOutputParameterRepresentation, intValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <long> longOutputParameterRepresentation)
            {
                rawValue.MustForArg(nameof(rawValue)).NotBeNull();
                var longValue = Convert.ToInt64(rawValue, CultureInfo.InvariantCulture);
                result = new SqlOutputParameterResult <long>(longOutputParameterRepresentation, longValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <long?> nullableLongOutputParameterRepresentation)
            {
                var longValue = rawValue == null ? (long?)null : Convert.ToInt64(rawValue, CultureInfo.InvariantCulture);
                result = new SqlOutputParameterResult <long?>(nullableLongOutputParameterRepresentation, longValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <string> stringLongOutputParameterRepresentation)
            {
                var stringValue = rawValue?.ToString();
                result = new SqlOutputParameterResult <string>(stringLongOutputParameterRepresentation, stringValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <DateTime> dateTimeOutputParameterRepresentation)
            {
                rawValue.MustForArg(nameof(rawValue)).NotBeNull();
                var dateTimeValue = (DateTime)rawValue;
                result = new SqlOutputParameterResult <DateTime>(dateTimeOutputParameterRepresentation, dateTimeValue);
            }
            else if (outputParameterDefinition is OutputParameterDefinition <DateTime?> nullableDateTimeOutputParameterRepresentation)
            {
                var dateTimeNullableValue = (DateTime?)rawValue;
                result = new SqlOutputParameterResult <DateTime?>(nullableDateTimeOutputParameterRepresentation, dateTimeNullableValue);
            }
            else if (outputParameterDefinition.GetType().GetGenericArguments().SingleOrDefault()?.IsEnum ?? false)
            {
                rawValue.MustForArg(nameof(rawValue)).NotBeNull();

                var genericDefinition = outputParameterDefinition.GetType().GetGenericTypeDefinition();
                genericDefinition.MustForArg(nameof(genericDefinition)).BeEqualTo(typeof(OutputParameterDefinition <>));

                var genericArguments = outputParameterDefinition.GetType().GetGenericArguments().ToList();
                var enumType         = genericArguments.Single();
                var enumValue        = Enum.Parse(enumType, rawValue.ToString());
                var resultType       = typeof(SqlOutputParameterResult <>).MakeGenericType(enumType);
                var rawResult        = resultType.Construct(outputParameterDefinition, enumValue);
                result = (ISqlOutputParameterResult)rawResult;
            }
            else
            {
                throw new NotSupportedException(FormattableString.Invariant($"A {nameof(SqlDataTypeRepresentationBase)} {nameof(outputParameterDefinition)} of type {outputParameterDefinition.GetType().ToStringReadable()} is not supported."));
            }

            return(result);
        }