/// <devdoc>
 /// Converts a type from a string representation to a strong type using
 /// an appropriate TypeConverter. If the value is not a string, the value
 /// is left unchanged.
 /// </devdoc>
 private static object ConvertType(object value, Type type, string paramName, ParsingCulture parsingCulture) {
     string s = value as string;
     if (s != null) {
         // Get the type converter for the destination type
         TypeConverter converter = TypeDescriptor.GetConverter(type);
         Debug.Assert(converter != null);
         if (converter != null) {
             // Perform the conversion
             try {
                 if (parsingCulture == ParsingCulture.Current) {
                     value = converter.ConvertFromString(null, CultureInfo.CurrentCulture, s);
                 }
                 else {
                     value = converter.ConvertFromInvariantString(s);
                 }
             }
             catch (NotSupportedException) {
                 throw new InvalidOperationException(SR.GetString(SR.ObjectDataSourceView_CannotConvertType, paramName, typeof(string).FullName, type.FullName));
             }
             catch (FormatException) {
                 throw new InvalidOperationException(SR.GetString(SR.ObjectDataSourceView_CannotConvertType, paramName, typeof(string).FullName, type.FullName));
             }
         }
     }
     return value;
 }
        /// <devdoc>
        /// Builds a strongly typed value to be passed into a method either as a parameter
        /// or as part of a data object. This will attempt to perform appropriate type
        /// conversions based on the destination type and throw exceptions on fatal errors.
        /// </devdoc>
        private static object BuildObjectValue(object value, Type destinationType, string paramName, ParsingCulture parsingCulture) {
            // Only consider converting the type if the value is non-null and the types don't match
            if (value != null && (!destinationType.IsInstanceOfType(value))) {
                Type innerDestinationType = destinationType;
                bool isNullable = false;
                if (destinationType.IsGenericType && (destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))) {
                    innerDestinationType = destinationType.GetGenericArguments()[0];
                    isNullable = true;
                }
                else {
                    if (destinationType.IsByRef) {
                        innerDestinationType = destinationType.GetElementType();
                    }
                }

                // Try to convert from for example string to DateTime, so that
                // afterwards we can convert DateTime to Nullable<DateTime>

                // If the value is a string, we attempt to use a TypeConverter to convert it
                value = ConvertType(value, innerDestinationType, paramName, parsingCulture);

                // Special-case the value when the destination is Nullable<T>
                if (isNullable) {
                    Type paramValueType = value.GetType();
                    if (innerDestinationType != paramValueType) {
                        // Throw if for example, we are trying to convert from int to Nullable<bool>
                        throw new InvalidOperationException(SR.GetString(SR.ObjectDataSourceView_CannotConvertType, paramName, paramValueType.FullName, String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", destinationType.GetGenericArguments()[0].FullName)));
                    }
                }
            }
            return value;
        }