public virtual TypeConverterResult GetTypeConverter(Type sourceType, Type destinationType)
        {
            ArgumentUtility.CheckNotNull("sourceType", sourceType);
            ArgumentUtility.CheckNotNull("destinationType", destinationType);

            TypeConverterResult additionalTypeConverterResult = GetAdditionalTypeConverter(sourceType, destinationType);

            if (!additionalTypeConverterResult.Equals(TypeConverterResult.Empty))
            {
                return(additionalTypeConverterResult);
            }

            TypeConverterResult typeConverterResult = GetTypeConverterFromFactory(sourceType, destinationType);

            if (!typeConverterResult.Equals(TypeConverterResult.Empty))
            {
                return(typeConverterResult);
            }

            TypeConverterResult stringConverterResult = GetStringConverter(sourceType, destinationType);

            if (!stringConverterResult.Equals(TypeConverterResult.Empty))
            {
                return(stringConverterResult);
            }

            return(TypeConverterResult.Empty);
        }
        public virtual object Convert(ITypeDescriptorContext context, CultureInfo culture, Type sourceType, Type destinationType, object value)
        {
            ArgumentUtility.CheckNotNull("sourceType", sourceType);
            ArgumentUtility.CheckNotNull("destinationType", destinationType);

            bool isNullableDestinationType = NullableTypeUtility.IsNullableType(destinationType);

            if (value == DBNull.Value && isNullableDestinationType)
            {
                return(GetValueOrEmptyString(destinationType, null));
            }

            if (value == null && !isNullableDestinationType)
            {
                throw new NotSupportedException(string.Format("Cannot convert value 'null' to non-nullable type '{0}'.", destinationType));
            }
            else if (value != null && !sourceType.IsInstanceOfType(value))
            {
                throw ArgumentUtility.CreateArgumentTypeException("value", value.GetType(), sourceType);
            }

            if (AreUnderlyingTypesEqual(sourceType, destinationType))
            {
                return(GetValueOrEmptyString(destinationType, value));
            }

            TypeConverterResult typeConverterResult = GetTypeConverter(sourceType, destinationType);

            if (!typeConverterResult.Equals(TypeConverterResult.Empty))
            {
                switch (typeConverterResult.TypeConverterType)
                {
                case TypeConverterType.SourceTypeConverter:
                    return(typeConverterResult.TypeConverter.ConvertTo(context, culture, value, destinationType));

                default:
                    Assertion.IsTrue(typeConverterResult.TypeConverterType == TypeConverterType.DestinationTypeConverter);
                    return(typeConverterResult.TypeConverter.ConvertFrom(context, culture, value));
                }
            }

            throw new NotSupportedException(string.Format("Cannot convert value '{0}' to type '{1}'.", value, destinationType));
        }
        public virtual bool CanConvert(Type sourceType, Type destinationType)
        {
            ArgumentUtility.CheckNotNull("sourceType", sourceType);
            ArgumentUtility.CheckNotNull("destinationType", destinationType);

            if (sourceType == typeof(DBNull))
            {
                return(NullableTypeUtility.IsNullableType(destinationType));
            }

            if (AreUnderlyingTypesEqual(destinationType, sourceType))
            {
                return(true);
            }

            TypeConverterResult typeConverterResult = GetTypeConverter(sourceType, destinationType);

            return(!typeConverterResult.Equals(TypeConverterResult.Empty));
        }