FieldInfo GetField(string name)
        {
            Type type = GetType();

            foreach (FieldInfo fieldInfo in type.GetFields())
            {
                if (string.Compare(fieldInfo.Name, name, true) == 0)
                {
                    return(fieldInfo);
                }

                foreach (object attribute in fieldInfo.GetCustomAttributes(true))
                {
                    if (attribute is CommandLineOptionAttribute)
                    {
                        CommandLineOptionAttribute optionAttribute = (CommandLineOptionAttribute)attribute;
                        if (string.Compare(optionAttribute.Name, name, true) == 0)
                        {
                            return(fieldInfo);
                        }
                        else if (string.Compare(optionAttribute.Alias, name, true) == 0)
                        {
                            return(fieldInfo);
                        }
                    }
                }
            }

            return(null);
        }
        public void WriteUsage(string extraInformation)
        {
            Type type = GetType();

            FieldInfo helpFieldInfo    = GetField("?");
            bool      showExtendedHelp = helpFieldInfo != null ? (bool)helpFieldInfo.GetValue(this) : false;

            var categories = new Dictionary <string, List <CommandLineOptionAttribute> >();

            categories.Add("", new List <CommandLineOptionAttribute>());

            int maxWidth = 0;

            foreach (FieldInfo fieldInfo in type.GetFields())
            {
                foreach (object attribute in fieldInfo.GetCustomAttributes(true))
                {
                    if (attribute is CommandLineOptionAttribute)
                    {
                        CommandLineOptionAttribute optionAttribute = (CommandLineOptionAttribute)attribute;

                        if (optionAttribute.Name == null)
                        {
                            optionAttribute.Name = fieldInfo.Name;
                        }

                        maxWidth = Math.Max(maxWidth, optionAttribute.FriendlyName.Length);

                        string category = "";
                        if (showExtendedHelp && optionAttribute.Category != null)
                        {
                            category = optionAttribute.Category;
                        }

                        List <CommandLineOptionAttribute> options;
                        if (!categories.TryGetValue(category, out options))
                        {
                            options = new List <CommandLineOptionAttribute>();
                            categories.Add(category, options);
                        }

                        options.Add(optionAttribute);

                        break;
                    }
                }
            }

            foreach (KeyValuePair <string, List <CommandLineOptionAttribute> > category in categories)
            {
                if (category.Key != "")
                {
                    Console.WriteLine();
                    Console.WriteLine(new string(' ', maxWidth) + "===" + category.Key + "===");
                }

                foreach (CommandLineOptionAttribute optionAttribute in category.Value)
                {
                    if (!optionAttribute.Extended || showExtendedHelp)
                    {
                        string name        = optionAttribute.FriendlyName;
                        string description = optionAttribute.Description;
                        string space       = new string(' ', maxWidth - optionAttribute.FriendlyName.Length + 1);

                        string option = "    " + name + space;
                        Console.WriteLine(option + WrapString(option.Length, description));
                    }
                }
            }

            if (showExtendedHelp && extraInformation != null)
            {
                Console.WriteLine();
                Console.WriteLine(extraInformation);
            }
        }