/// <summary>
        /// Parses arguments provided in command line based on configuration described in type T.
        /// </summary>
        /// <param name="args">Arguments.</param>
        /// <param name="option">Configuration.</param>
        /// <returns>True if parsing was sucessful and 'help' option was not detected. False when 'help' was encountered.</returns>
        public bool Parse <T>(T option, string[] args)
        {
            helpProvider = HelpOption.CreateInstance <T>();
            helpProvider.CustomFooterGenerator          = configuration.CustomFooterGenerator;
            helpProvider.CustomOptionEntryHelpGenerator = configuration.CustomOptionEntryHelpGenerator;
            helpProvider.CustomUsageLineGenerator       = configuration.CustomUsageLineGenerator;

            foreach (var property in typeof(T).GetProperties())
            {
                var positionalAttribute = property.GetCustomAttribute <PositionalArgumentAttribute>();
                if (positionalAttribute != null)
                {
                    var argument = new PositionalArgument(property);
                    if (values.Count > positionalAttribute.Position)
                    {
                        values.Insert(positionalAttribute.Position, argument);
                    }
                    else
                    {
                        values.Add(argument);
                    }
                }
                else
                {
                    options.Add(new CommandLineOptionDescriptor(property));
                }
            }

            if (option is IValidatedOptions)
            {
                customValidationMethod = ((IValidatedOptions)option).Validate;
            }

            if (configuration.GenerateHelp)
            {
                options.Add(helpProvider);
            }

            InnerParse(args);

            // set values
            foreach (var o in parsedOptions.Where(x => x.Flag.UnderlyingProperty != null).GroupBy(x => x.Flag))
            {
                // multi-values
                if (o.Count() > 1)
                {
                    if (!o.Key.UnderlyingProperty.PropertyType.IsArray)
                    {
                        // if it's not an array we will throw validation exception later
                        continue;
                    }

                    var finalValue = CreateDynamicList((dynamic)(((Array)o.First().Value).GetValue(0)));
                    foreach (var localValue in o.Select(x => x.Value))
                    {
                        finalValue.AddRange((dynamic)localValue);
                    }
                    o.Key.UnderlyingProperty.SetValue(option, finalValue.ToArray());
                }
                // single-value
                else
                {
                    o.Key.UnderlyingProperty.SetValue(option, o.First().Value);
                }
            }

            // set default values
            foreach (var o in options.Where(x => x.UnderlyingProperty != null && x.DefaultValue != null).Except(parsedOptions.Where(x => x.Value != null).Select(x => x.Flag)))
            {
                o.UnderlyingProperty.SetValue(option, o.DefaultValue);
            }

            foreach (var property in typeof(T).GetProperties())
            {
                var attribute = property.GetCustomAttribute <PositionalArgumentAttribute>();
                if (attribute != null && attribute.Position < values.Count)
                {
                    property.SetValue(option, values[attribute.Position].Value);
                }
            }

            return(Validate());
        }
 /// <summary>
 /// Parses arguments provided in command line.
 /// </summary>
 /// <param name="args">Arguments.</param>
 /// <returns>True if parsing was sucessful and 'help' option was not detected. False when 'help' was encountered.</returns>
 public bool Parse(string[] args)
 {
     helpProvider = HelpOption.CreateInstance();
     InnerParse(args);
     return(Validate());
 }