public RunOptions LoadAppSettings(string path)
        {

            RunOptions result = new RunOptions();

            ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
            configFileMap.ExeConfigFilename = result.AppSettingsFile;
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
            foreach (KeyValueConfigurationElement element in config.AppSettings.Settings)
            {
                foreach (var field in typeof(RunOptions).GetFields())
                {
                    var attr = GetAttr<AppConfigArgAttribute>(field);
                    if (attr != null && element.Key == attr.Key)
                    {
                        field.SetValue(result, element.Value);
                    }
                }
            }

            return result;
        }
        private RunOptions ParseArguments(string[] args)
        {
            RunOptions result = new RunOptions();
            OptionSet commandOptions = new OptionSet();

            foreach (var field in typeof(RunOptions).GetFields())
            {
                var attr = GetAttr<CommandLineArgAttribute>(field);
                if (attr != null)
                {
                    commandOptions.Add($"{attr.Key}=", attr.Description, (value) => { field.SetValue(result, value); });
                }
            }

            commandOptions.Add("?|h|help", "Display the information on how to use this executable.", value => result.ShowHelp = value != null);
            commandOptions.Add("v|verbose", "Display more messages when the executable runs.", value => result.Verbose = value != null);

            try
            {
                commandOptions.Parse(args);
            }
            catch (OptionException)
            {
                ShowHelpMessage("Error processing command line, usage is: IntegrationNugetInspector.exe [OPTIONS]", commandOptions);
                return null;
            }

            if (result.ShowHelp)
            {
                LogOptions(result);
                ShowHelpMessage("Usage is IntegrationNugetInspector.exe [OPTIONS]", commandOptions);
                return null;
            }

            return result;
        }
        public List<InspectionResult> Execute(string[] args)
        {
            RunOptions options = ParseArguments(args);

            if (options == null) return null;

            if (!string.IsNullOrWhiteSpace(options.AppSettingsFile))
            {
                RunOptions appOptions = LoadAppSettings(options.AppSettingsFile);
                options.Override(appOptions);
            }

            if (string.IsNullOrWhiteSpace(options.TargetPath))
            {
                options.TargetPath = Directory.GetCurrentDirectory();
            }

            InspectionOptions opts = new InspectionOptions()
            {
                ExcludedModules = options.ExcludedModules,
                IncludedModules = options.IncludedModules,
                IgnoreFailure = options.IgnoreFailures == "true",
                OutputDirectory = options.OutputDirectory,
                PackagesRepoUrl = options.PackagesRepoUrl,
                NugetConfigPath = options.NugetConfigPath,
                TargetPath = options.TargetPath,
                Verbose = options.Verbose
            };

            var searchService = new NugetSearchService(options.PackagesRepoUrl, options.NugetConfigPath);
            var inspectionResults = Dispatch.Inspect(opts, searchService);

            if (inspectionResults != null)
            {
                foreach (var result in inspectionResults)
                {
                    try
                    {
                        if (result.ResultName != null)
                        {
                            Console.WriteLine("Inspection: " + result.ResultName);
                        }
                        if (result.Status == InspectionResult.ResultStatus.Success)
                        {
                            Console.WriteLine("Inspection Result: Success");
                            var writer = new InspectionResultJsonWriter(result);
                            writer.Write();
                            Console.WriteLine("Info file created at {0}", writer.FilePath());
                        }
                        else
                        {
                            Console.WriteLine("Inspection Result: Error");
                            if (result.Exception != null)
                            {
                                Console.WriteLine("Exception:");
                                Console.WriteLine(result.Exception);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error processing inspection result.");
                        Console.WriteLine(e.Message);
                        Console.WriteLine(e.StackTrace);
                    }

                }
            }
            if (inspectionResults.Where(result => result.Status == InspectionResult.ResultStatus.Error).Any())
            {
                inspectionResults.Where(result => result.Status == InspectionResult.ResultStatus.Error)
                    .Select(result => {
                        if (result.Exception != null) return result.Exception.ToString(); else return result.ResultName + " encountered an unknown issue.";
                    }).ToList().ForEach(Console.Error.Write);

                Console.Error.Write("One or more inspection results failed.");
                if (options.IgnoreFailures == "true")
                {
                    Console.Error.Write("Ignoring failures, not exiting -1.");
                } else
                {
                    Environment.Exit(-1);
                }
                
            }


            return inspectionResults;
        }