/// <summary>
        /// Parses the given string value converting it to the given type.
        /// </summary>
        /// <param name="value">The string value to parse.</param>
        /// <param name="culture">The <see cref="CultureInfo"/> to use as the current culture.</param>
        /// <typeparam name="T">
        /// The <see cref="Type"/> to convert the string to.
        /// </typeparam>
        /// <returns>The converted instance or the default.</returns>
        public T ParseValue <T>(string value, CultureInfo culture)
        {
            if (culture == null)
            {
                culture = CultureInfo.InvariantCulture;
            }

            Type type = typeof(T);
            ICommandConverter converter = CommandDescriptor.GetConverter(type);

            try
            {
                return((T)converter.ConvertFrom(culture, WebUtility.UrlDecode(value), type));
            }
            catch
            {
                return(default);
        /// <summary>
        /// Parses the given string value converting it to the given type.
        /// </summary>
        /// <param name="type">
        /// The <see cref="Type"/> to convert the string to.
        /// </param>
        /// <param name="value">
        /// The <see cref="string"/> value to parse.
        /// </param>
        /// <param name="culture">
        /// The <see cref="CultureInfo"/> to use as the current culture.
        /// <remarks>If not set will parse using <see cref="CultureInfo.InvariantCulture"/></remarks>
        /// </param>
        /// <returns>
        /// The <see cref="object"/>.
        /// </returns>
        internal object ParseValue(Type type, string value, CultureInfo culture)
        {
            if (culture == null)
            {
                culture = CultureInfo.InvariantCulture;
            }

            ICommandConverter converter = CommandDescriptor.GetConverter(type);

            try
            {
                return(converter.ConvertFrom(culture, WebUtility.UrlDecode(value), type));
            }
            catch
            {
                // Return the default value
                return(TypeDefaultsCache.GetOrAdd(type, t => this.GetDefaultValue(type)));
            }
        }
 /// <summary>
 /// Adds a command converter to the parser.
 /// </summary>
 /// <param name="type">The <see cref="Type"/> to add a converter for. </param>
 /// <param name="converterType">The type of <see cref="CommandConverter"/> to add.</param>
 public void AddConverter(Type type, Type converterType)
 {
     CommandDescriptor.AddConverter(type, converterType);
 }