/// <summary>Attempts to convert argument to parameter type.</summary>
        /// <param name="parameter">Parameter to convert argument to.</param>
        /// <param name="argIndex">Index of argument.</param>
        /// <param name="values">Builder values. Must contain Args and ArgumentConverterProvider.</param>
        /// <param name="result">Result of the conversion. Null if conversion failed.</param>
        /// <param name="error">Exception that occured when converting. Null if there was no exception.</param>
        /// <returns>True if converting was successful; otherwise false.</returns>
        protected static bool TryConvertArgument(ParameterInfo parameter, int argIndex, ParameterBuilderValues values, out object result, out Exception error)
        {
            if (argIndex < 0)
            {
                throw new ArgumentException("Argument index cannot be negative", nameof(argIndex));
            }
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            error  = null;
            result = null;

            // check if we didn't run out of args
            if (values.Args == null || values.Args.Length - 1 < argIndex)
            {
                return(false);
            }

            // get from provider
            IArgumentConverterProvider provider  = values.ArgumentConverterProvider;
            IArgumentConverter         converter = provider?.GetConverter(parameter);

            if (converter == null)
            {
                return(false);
            }

            try
            {
                result = converter.Convert(parameter, values.Args[argIndex]);
                return(true);
            }
            catch (Exception ex)
            {
                error = ex;
                return(false);
            }
        }