internal static ICommandBuilder ToCommand(this ICommandDef commandDef, Command parent, CommandContext commandContext)
        {
            var command = new Command(
                commandDef.Name,
                commandDef.CustomAttributes,
                commandDef.IsExecutable,
                parent,
                commandDef.SourcePath);

            command.Services.AddOrUpdate(commandDef);

            var commandAttribute = commandDef.GetCustomAttribute <CommandAttribute>()
                                   ?? commandDef.GetCustomAttribute <ApplicationMetadataAttribute>();

            if (commandAttribute != null)
            {
                command.Description               = commandAttribute.Description;
                command.Usage                     = commandAttribute.Usage;
                command.ExtendedHelpText          = commandAttribute.ExtendedHelpText;
                command.IgnoreUnexpectedOperands  = commandAttribute.IgnoreUnexpectedOperandsAsNullable;
                command.ArgumentSeparatorStrategy = commandAttribute.ArgumentSeparatorStrategyAsNullable;
            }

            var commandBuilder = new CommandBuilder(command);

            commandDef.InvokeMethodDef.ArgumentDefs
            .Select(a => a.ToArgument(command, commandContext.AppConfig, false))
            .ForEach(commandBuilder.AddArgument);

            commandDef.InterceptorMethodDef.ArgumentDefs
            .Select(a => a.ToArgument(command, commandContext.AppConfig, true))
            .ForEach(commandBuilder.AddArgument);

            commandDef.SubCommands
            .Select(c => c.ToCommand(command, commandContext).Command)
            .ForEach(commandBuilder.AddSubCommand);

            commandContext.AppConfig.BuildEvents.CommandCreated(commandContext, commandBuilder);

            return(commandBuilder);
        }
        internal static ICommandBuilder ToCommand(this ICommandDef commandDef, Command?parent, CommandContext commandContext)
        {
            var command = new Command(
                commandDef.Name,
                commandDef.CustomAttributes,
                commandDef.IsExecutable,
                parent,
                commandDef.SourcePath);

            command.Services.AddOrUpdate(commandDef);

            var commandAttribute = commandDef.GetCustomAttribute <CommandAttribute>();

            if (commandAttribute != null)
            {
                command.Description      = JoinFromAttribute(commandDef, nameof(commandAttribute.Description), commandAttribute.Description, commandAttribute.DescriptionLines);
                command.Usage            = JoinFromAttribute(commandDef, nameof(commandAttribute.Usage), commandAttribute.Usage, commandAttribute.UsageLines);
                command.ExtendedHelpText = JoinFromAttribute(commandDef, nameof(commandAttribute.ExtendedHelpText), commandAttribute.ExtendedHelpText, commandAttribute.ExtendedHelpTextLines);
            }

            var appSettings = commandContext.AppConfig.AppSettings;

            command.IgnoreUnexpectedOperands  = commandAttribute?.IgnoreUnexpectedOperandsAsNullable ?? appSettings.Parser.IgnoreUnexpectedOperands;
            command.ArgumentSeparatorStrategy = commandAttribute?.ArgumentSeparatorStrategyAsNullable ?? appSettings.Parser.DefaultArgumentSeparatorStrategy;

            var commandBuilder = new CommandBuilder(command);

            commandDef.InvokeMethodDef?.Arguments
            .ForEach(commandBuilder.AddArgument);

            commandDef.InterceptorMethodDef?.Arguments
            .ForEach(commandBuilder.AddArgument);

            commandDef.SubCommands
            .Select(c => c.ToCommand(command, commandContext).Command)
            .ForEach(commandBuilder.AddSubCommand);

            commandContext.AppConfig.BuildEvents.CommandCreated(commandContext, commandBuilder);

            return(commandBuilder);
        }