Configuration that can be read from the file or built using Options.
        private async Task<List<ProjectAnalysisResult>> AnalyseSolutionAsync(Solution solution, ImmutableArray<DiagnosticAnalyzer> analyzers, Configuration configuration)
        {
            var ruleIds = analyzers
                .SelectMany(a => a.SupportedDiagnostics.Select(d => d.Id))
                .Where(d => !_configuration.DisabledDiagnostics.Contains(d))
                .ToImmutableHashSet();

            var projectAnalysisTasks = solution.Projects
                // First, Running analysis
                .Select(p => new { Project = p, Task = AnalyzeProjectAsync(p, analyzers) })
                .ToList()
                // Then we need to print all the results
                .Select(p => new { Project = p.Project, Task = p.Task.ContinueWith(t =>
                    {
                        var diagnostics = t.Result.Where(d => ruleIds.Contains(d.Id)).ToImmutableArray();
                        if (configuration.RunInfoLevelDiagnostics)
                        {
                            diagnostics = diagnostics.Where(d => d.Severity != DiagnosticSeverity.Info).ToImmutableArray();
                        }
                        LogDiagnostics(p.Project, diagnostics);

                        return t;
                    }).Unwrap()})
                .ToList();

            // And need to wait when all the analysis and printing tasks would be finished
            await Task.WhenAll(projectAnalysisTasks.Select(p => p.Task));

            // And only after now we can build the result
            var result =
                projectAnalysisTasks
                .Select(r => new ProjectAnalysisResult(r.Project, r.Task.Result.Where(d => ruleIds.Contains(d.Id)).ToImmutableArray())).ToList();

            return result;
        }
 public AnalyzerRunner(Configuration configuration)
 {
     Contract.Requires(configuration != null);
     _configuration = configuration;
 }
        private async Task AnalyzeSolutionAsync(Configuration configuration)
        {
            var analyzers = GetAnalyzers(configuration.Analyzer).ToImmutableArray();

            // Loading the solution
            var sw = Stopwatch.StartNew();

            var workspace = MSBuildWorkspace.Create();

            WriteInfo($"Opening solution '{configuration.Solution}'...");

            var solution = await workspace.OpenSolutionAsync(configuration.Solution);

            WriteInfo($"Loaded solution in {sw.ElapsedMilliseconds}ms with '{solution.ProjectIds.Count}' projects and '{solution.DocumentsCount()}' documents");

            WriteInfo("Running the analysis...");

            // Running the analysis
            sw.Restart();

            var diagnostics = await AnalyseSolutionAsync(solution, analyzers, configuration);

            WriteInfo($"Found {diagnostics.SelectMany(d => d.Diagnostics).Count()} diagnostics in {sw.ElapsedMilliseconds}ms");

            PrintStatistics(diagnostics, analyzers);
        }