public int Run(IReadOnlyList <string> args)
        {
            try
            {
                var argsReader = new ArgsReader(args);
                if (argsReader.ReadHelpFlag())
                {
                    WriteUsage(Console.Out);
                    return(0);
                }

                bool isVerify = argsReader.ReadVerifyFlag();

                var settings = new XmlDocMarkdownSettings();
                settings.NewLine         = argsReader.ReadNewLineOption();
                settings.SourceCodePath  = argsReader.ReadSourceOption();
                settings.RootNamespace   = argsReader.ReadNamespaceOption();
                settings.IncludeObsolete = argsReader.ReadObsoleteFlag();
                settings.SkipUnbrowsable = argsReader.ReadSkipUnbrowsableFlag();
                settings.VisibilityLevel = argsReader.ReadVisibilityOption();
                settings.ShouldClean     = argsReader.ReadCleanFlag();
                settings.IsQuiet         = argsReader.ReadQuietFlag();
                settings.IsDryRun        = isVerify || argsReader.ReadDryRunFlag();
                settings.FrontMatter     = argsReader.ReadFrontMatter();
                settings.PermalinkStyle  = argsReader.ReadPermalinkStyle();
                settings.GenerateToc     = argsReader.ReadGeneratyeTocFlag();
                settings.TocPrefix       = argsReader.ReadTocPrefix();
                settings.NamespacePages  = argsReader.ReadNamespacePageFlag();

                var    externalDocs = new List <ExternalDocumentation>();
                string externalOption;
                while ((externalOption = argsReader.ReadExternalOption()) != null)
                {
                    externalDocs.Add(new ExternalDocumentation {
                        Namespace = externalOption
                    });
                }
                if (externalDocs.Count != 0)
                {
                    settings.ExternalDocs = externalDocs;
                }

                string inputPath = argsReader.ReadArgument();
                if (inputPath == null)
                {
                    throw new ArgsReaderException("Missing input path.");
                }

                string outputPath = argsReader.ReadArgument();
                if (outputPath == null)
                {
                    throw new ArgsReaderException("Missing output path.");
                }

                argsReader.VerifyComplete();

                var result = XmlDocMarkdownGenerator.Generate(inputPath, outputPath, settings);

                foreach (string message in result.Messages)
                {
                    Console.WriteLine(message);
                }

                return(isVerify && result.Added.Count + result.Changed.Count + result.Removed.Count != 0 ? 1 : 0);
            }
            catch (Exception exception)
            {
                if (exception is ArgsReaderException)
                {
                    Console.Error.WriteLine(exception.Message);
                    Console.Error.WriteLine();
                    WriteUsage(Console.Error);
                    return(2);
                }
                else if (exception is ApplicationException || exception is IOException || exception is UnauthorizedAccessException)
                {
                    Console.Error.WriteLine(exception.Message);
                    return(3);
                }
                else
                {
                    Console.Error.WriteLine(exception.ToString());
                    return(3);
                }
            }
        }