/// <summary>
        ///     Converts value from one type to another using an optional <see cref="T:System.IFormatProvider" />.
        /// </summary>
        /// <param name="value">The original value.</param>
        /// <param name="type">The target type.</param>
        /// <param name="provider">A <see cref="T:System.IFormatProvider" /> used to format or parse the value.</param>
        /// <param name="format">Format string.</param>
        /// <param name="returnDbNUllIfNotValid">
        ///     Indicates whether exceptions should be avoided or catched and return value should be DBNull if
        ///     it cannot be converted to the target type.
        /// </param>
        /// <returns>The new value in the target type.</returns>
        public static object ChangeType(
            object value,
            Type type,
            IFormatProvider provider,
            string format,
            bool returnDbNUllIfNotValid)
        {
            var underlyingType = Nullable.GetUnderlyingType(type);

            if (underlyingType != null)
            {
                value = ChangeType(value, underlyingType, provider, true);
                return(NullableHelperInternal.FixDbNUllasNull(value, type));
            }

            if (value != null && !type.IsAssignableFrom(value.GetType()))
            {
                try
                {
                    if (value is string)
                    {
                        value = format == null || format.Length <= 0
                            ? Parse((string)value, type, provider, "", returnDbNUllIfNotValid)
                            : Parse((string)value, type, provider, format, returnDbNUllIfNotValid);
                    }
                    else if (!(value is DBNull))
                    {
                        if (type.GetTypeInfo().IsEnum)
                        {
                            value = Convert.ChangeType(value, typeof(int), provider);
                            value = Enum.ToObject(type, (int)value);
                        }
                        else
                        {
                            value = !(type == typeof(string)) || value is IConvertible
                                ?
                                    NullableHelperInternal.ChangeType(value, type, provider)
                                : value != null
                                    ? value.ToString()
                                    : "";
                        }
                    }
                }
                catch
                {
                    if (returnDbNUllIfNotValid)
                    {
                        return(DBNull.Value);
                    }
                    throw;
                }
            }

            if ((value == null || value is DBNull) && type == typeof(string))
            {
                return("");
            }
            return(value);
        }
 /// <summary>
 ///     Parse the given text using the resultTypes "Parse" method or using a type converter.
 /// </summary>
 /// <param name="s">The text to parse.</param>
 /// <param name="resultType">The requested result type.</param>
 /// <param name="provider">A <see cref="T:System.IFormatProvider" /> used to format or parse the value. Can be NULL.</param>
 /// <param name="formats">
 ///     A string array holding permissible formats used in a <see cref="M:System.Object.ToString" /> call. Right now
 ///     formats is only interpreted to enable roundtripping for formatted dates.
 /// </param>
 /// <param name="returnDbNUllIfNotValid">
 ///     Indicates whether DbNull should be returned if value cannot be parsed. Otherwise
 ///     an exception is thrown.
 /// </param>
 /// <returns>The new value in the target type.</returns>
 public static object Parse(
     string s,
     Type resultType,
     IFormatProvider provider,
     string[] formats,
     bool returnDbNUllIfNotValid)
 {
     return(NullableHelperInternal.FixDbNUllasNull(
                _Parse(s, resultType, provider, "", formats, returnDbNUllIfNotValid), resultType));
 }
        private static object _Parse(
            string s,
            Type resultType,
            IFormatProvider provider,
            string format,
            string[] formats,
            bool returnDbNUllIfNotValid)
        {
            if (resultType == null)
            {
                return(s);
            }
            try
            {
                if (typeof(double).IsAssignableFrom(resultType))
                {
                    if (IsEmpty(s))
                    {
                        return(DBNull.Value);
                    }
                    double result;
                    if (double.TryParse(s, NumberStyles.Any, provider, out result))
                    {
                        return(Convert.ChangeType(result, resultType, provider));
                    }
                    if (returnDbNUllIfNotValid && (resultType == typeof(double) || resultType == typeof(float)))
                    {
                        return(DBNull.Value);
                    }
                }
                else if (typeof(decimal).IsAssignableFrom(resultType))
                {
                    if (IsEmpty(s))
                    {
                        return(DBNull.Value);
                    }
                    decimal result;
                    if (decimal.TryParse(s, NumberStyles.Any, provider, out result))
                    {
                        return(Convert.ChangeType(result, resultType, provider));
                    }
                }
                else
                {
                    if (typeof(DateTime).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        if (formats == null || formats.GetLength(0) == 0 && format.Length > 0)
                        {
                            formats = new string[7]
                            {
                                format,
                                "G",
                                "g",
                                "f",
                                "F",
                                "d",
                                "D"
                            }
                        }
                        ;
                        DateTime result1;
                        if (formats != null && formats.GetLength(0) > 0 && DateTime.TryParseExact(s, formats, provider,
                                                                                                  DateTimeStyles.AllowWhiteSpaces, out result1))
                        {
                            return(result1);
                        }
                        DateTime result2;
                        DateTime.TryParse(s, provider, DateTimeStyles.AllowWhiteSpaces, out result2);
                        return(result2);
                    }

                    if (typeof(TimeSpan).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        var      flag = false;
                        TimeSpan result;
                        if (TimeSpan.TryParse(s, out result))
                        {
                            flag = true;
                        }
                        if (flag)
                        {
                            return(result);
                        }
                    }
                    else if (typeof(bool).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        if (s == "1" || s.ToUpper() == bool.TrueString.ToUpper())
                        {
                            return(true);
                        }
                        if (s == "0" || s.ToUpper() == bool.FalseString.ToUpper())
                        {
                            return(false);
                        }
                    }
                    else if (typeof(long).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        long result;
                        if (long.TryParse(s, NumberStyles.Any, provider, out result))
                        {
                            return(Convert.ChangeType(result, resultType, provider));
                        }
                        if (returnDbNUllIfNotValid && resultType.GetTypeInfo().IsPrimitive&&
                            !resultType.GetTypeInfo().IsEnum)
                        {
                            return(DBNull.Value);
                        }
                    }
                    else if (typeof(ulong).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        ulong result;
                        if (ulong.TryParse(s, NumberStyles.Any, provider, out result))
                        {
                            return(Convert.ChangeType(result, resultType, provider));
                        }
                        if (returnDbNUllIfNotValid && resultType.GetTypeInfo().IsPrimitive&&
                            !resultType.GetTypeInfo().IsEnum)
                        {
                            return(DBNull.Value);
                        }
                    }
                    else if (typeof(int).IsAssignableFrom(resultType) || typeof(short).IsAssignableFrom(resultType) ||
                             typeof(float).IsAssignableFrom(resultType) || typeof(uint).IsAssignableFrom(resultType) ||
                             typeof(ushort).IsAssignableFrom(resultType) || typeof(byte).IsAssignableFrom(resultType))
                    {
                        if (IsEmpty(s))
                        {
                            return(DBNull.Value);
                        }
                        double result;
                        if (double.TryParse(s, NumberStyles.Any, provider, out result))
                        {
                            return(Convert.ChangeType(result, resultType, provider));
                        }
                        if (returnDbNUllIfNotValid && resultType.GetTypeInfo().IsPrimitive&&
                            !resultType.GetTypeInfo().IsEnum)
                        {
                            return(DBNull.Value);
                        }
                    }
                    else if (resultType == typeof(Type))
                    {
                        return(Type.GetType(s));
                    }
                }

                var converter = TypeDescriptor.GetConverter(resultType);
                if (converter is NullableConverter)
                {
                    var underlyingType = NullableHelperInternal.GetUnderlyingType(resultType);
                    if (underlyingType != null)
                    {
                        return(_Parse(s, underlyingType, provider, format, formats, returnDbNUllIfNotValid));
                    }
                }

                if (converter != null && converter.CanConvertFrom(typeof(string)) && s != null && s.Length > 0)
                {
                    return(!(provider is CultureInfo)
                        ? converter.ConvertFrom(s)
                        : converter.ConvertFrom(null, (CultureInfo)provider, s));
                }
            }
            catch
            {
                if (returnDbNUllIfNotValid)
                {
                    return(DBNull.Value);
                }
                throw;
            }

            return(DBNull.Value);
        }