<commit_before>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace JA.Clizby
{
    public class OptionReader<T> where T : new()
    {
        public IDictionary<string, string> Aliases { get; set; }
        public IDictionary<string, IMapper<T>> Mappers { get; set; }
        public IDictionary<string, PropertyInfo> Properties { get; set; }

        public OptionReader()
        {
            Mappers = new Dictionary<string, IMapper<T>>();
            Aliases = typeof(T).GetFields().Where(f => f.GetCustomAttribute(typeof(Alias)) != null).SelectMany(f => ((Alias)f.GetCustomAttribute(typeof(Alias))).Names.Select(n => new { Key = n, Value = f.Name }))
                .Concat(typeof(T).GetProperties().Where(p => p.GetCustomAttribute(typeof(Alias)) != null).SelectMany(p => ((Alias)p.GetCustomAttribute(typeof(Alias))).Names.Select(n => new { Key = n, Value = p.Name })))
                .ToDictionary(kv => kv.Key, kv => kv.Value);
        }

        /// <summary>
        /// Creates a new OptionReader the provided mappers.
        /// </summary>
        public OptionReader(IEnumerable<IMapper<T>> mappers)
            : this()
        {
            Mappers = mappers.ToDictionary(m => m.Name);
        }

        /// <summary>
        /// Creates a new OptionReader the provided mappers.
        /// </summary>
        public OptionReader(params IMapper<T>[] mappers)
            : this()
        {
            Mappers = mappers.ToDictionary(m => m.Name);
        }

        /// <summary>
        /// Parses command line options, returning a new instance of T
        /// containing the processed arguments.
        /// </summary>
        /// <typeparam name="T">Type to be created.</typeparam>
        /// <param name="argsCollection">Arguments to be processed.</param>
        /// <returns>Instance of T</returns>
        public T Parse(IEnumerable<string> argsCollection)
        {
            var properties = typeof(T).GetProperties().ToDictionary(p => p.Name);
            var options = ApplyPositionalArguments(new T(), argsCollection);

            var parameters = argsCollection
                .Zip(argsCollection.Skip(1).Concat(new[] { String.Empty }), (a, b) => new { a, b })
                .Where(pair => pair.a.StartsWith("-") || pair.a.StartsWith("/"))
                .Select(pair => new Parameter(GetOptionMapping(pair.a), pair.b));

            foreach (var parameter in parameters)
            {
                var propertyName = GetPropertyName(parameter.Key);

                if (properties.ContainsKey(propertyName))
                {
                    if (Mappers.ContainsKey(propertyName))
                        Mappers[propertyName].Set(options, parameter.Value);

                    else properties[propertyName].SetValue(options, parameter.Read(properties[propertyName].PropertyType));
                }
            }

            return Validate(options);
        }

        private T ApplyPositionalArguments(T options, IEnumerable<string> argsCollection)
        {<commit_msg>Parse will now configure existing instance<commit_after>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace JA.Clizby
{
    public class OptionReader<T> where T : new()
    {
        public IDictionary<string, string> Aliases { get; set; }
        public IDictionary<string, IMapper<T>> Mappers { get; set; }
        public IDictionary<string, PropertyInfo> Properties { get; set; }

        public OptionReader()
        {
            Mappers = new Dictionary<string, IMapper<T>>();
            Aliases = typeof(T).GetFields().Where(f => f.GetCustomAttribute(typeof(Alias)) != null).SelectMany(f => ((Alias)f.GetCustomAttribute(typeof(Alias))).Names.Select(n => new { Key = n, Value = f.Name }))
                .Concat(typeof(T).GetProperties().Where(p => p.GetCustomAttribute(typeof(Alias)) != null).SelectMany(p => ((Alias)p.GetCustomAttribute(typeof(Alias))).Names.Select(n => new { Key = n, Value = p.Name })))
                .ToDictionary(kv => kv.Key, kv => kv.Value);
        }

        /// <summary>
        /// Creates a new OptionReader the provided mappers.
        /// </summary>
        public OptionReader(IEnumerable<IMapper<T>> mappers)
            : this()
        {
            Mappers = mappers.ToDictionary(m => m.Name);
        }

        /// <summary>
        /// Creates a new OptionReader the provided mappers.
        /// </summary>
        public OptionReader(params IMapper<T>[] mappers)
            : this()
        {
            Mappers = mappers.ToDictionary(m => m.Name);
        }

        /// <summary>
        /// Parses command line options, returning a new instance of T
        /// containing the processed arguments
        /// </summary>
        /// <param name="argsCollection">Arguments to be processed</param>
        /// <returns>Instance of T</returns>
        public T Parse(IEnumerable<string> argsCollection)
        {
            return Parse(new T(), argsCollection);
        }

        /// <summary>
        /// Parses command line options, returning the provided instance of T
        /// containing the processed arguments.
        /// </summary>
        /// <param name="options">The instance of T to be configured</param>
        /// <param name="argsCollection">The arguments to be processed</param>
        /// <returns></returns>
        public T Parse(T options, IEnumerable<string> argsCollection)
        {
            var properties = typeof(T).GetProperties().ToDictionary(p => p.Name);
            ApplyPositionalArguments(options, argsCollection);

            var parameters = argsCollection
                .Zip(argsCollection.Skip(1).Concat(new[] { String.Empty }), (a, b) => new { a, b })
                .Where(pair => pair.a.StartsWith("-") || pair.a.StartsWith("/"))
                .Select(pair => new Parameter(GetOptionMapping(pair.a), pair.b));

            foreach (var parameter in parameters)
            {
                var propertyName = GetPropertyName(parameter.Key);

                if (properties.ContainsKey(propertyName))
                {
                    if (Mappers.ContainsKey(propertyName))
                        Mappers[propertyName].Set(options, parameter.Value);

                    else properties[propertyName].SetValue(options, parameter.Read(properties[propertyName].PropertyType));
                }
            }

            return Validate(options);
        }

        private T ApplyPositionalArguments(T options, IEnumerable<string> argsCollection)
        {
{'fraction_non_alphanumeric': 0.13051967557825173, 'fraction_numerical': 0.00030039050765995795, 'mean_word_length': 2.1469754253308126, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 86, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5969618', 'n_tokens_mistral': 1742, 'n_tokens_neox': 1726, 'n_words': 402}