private bool BindProvider(Type type, string providerName, ICustomAttributeProvider provider, out object value)
        {
            if (type == typeof(Command))
            {
                value = this;
                return(true);
            }

            var converter = TypeDescriptor.GetConverter(type);

            if (converter == null || !converter.CanConvertFrom(typeof(string)))
            {
                var message = string.Format("No conversion possible for '{0}'.", providerName);
                throw new InvalidOperationException(message);
            }

            var attributes = ArgumentAttribute.For(provider).Select(attribute => Tuple.Create(attribute, attribute.Name));

            if (!attributes.Any())
            {
                attributes = new[] { new Tuple <ArgumentAttribute, string>(null, providerName) };
            }

            foreach (var pair in attributes)
            {
                var    attribute = pair.Item1;
                var    name      = pair.Item2;
                string text;

                if (!Options.TryGetValue(name, out text))
                {
                    if (attribute != null && attribute.IsOptional)
                    {
                        value = null;
                        return(true);
                    }

                    continue;
                }

                if (type == typeof(bool))
                {
                    if (string.IsNullOrWhiteSpace(text))
                    {
                        value = true;
                        return(true);
                    }

                    value = Convert.ToBoolean(text);
                    return(true);
                }

                value = converter.ConvertFromInvariantString(text);
                return(true);
            }

            value = null;
            return(false);
        }
        /// <summary>
        /// Find all the constructors for the specified <see cref="Type" /> that have all their parameters
        /// represented as an option.
        /// </summary>
        private IEnumerable <ConstructorInfo> FindSuitableConstructors(Type type)
        {
            return(type.GetConstructors().Where(constructor =>
                                                constructor.GetParameters().All(parameter =>
            {
                if (parameter.ParameterType == typeof(Command))
                {
                    return true;
                }

                var attributes = ArgumentAttribute.For(parameter);

                return attributes.Any()
                        ? attributes.Any(attribute => Options.ContainsKey(attribute.Name))
                        : Options.ContainsKey(parameter.Name);
            })));
        }
        private void BindProperty(PropertyInfo property, object instance)
        {
            foreach (var attribute in ArgumentAttribute.For(property))
            {
                string text;

                if (!Options.TryGetValue(attribute.Name, out text))
                {
                    continue;
                }

                object value;

                if (BindProvider(property.PropertyType, property.Name, property, out value))
                {
                    property.SetValue(instance, value, null);
                }
            }
        }