/// <summary>
            /// General verifier for codefixes.
            /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes.
            /// Then gets the string after the codefix is applied and compares it with the expected result.
            /// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true.
            /// </summary>
            /// <param name="analyzer">The analyzer to be applied to the source code</param>
            /// <param name="codeFixProvider">The codefix to be applied to the code wherever the relevant Diagnostic is found</param>
            /// <param name="oldSource">A class in the form of a string before the CodeFix was applied to it</param>
            /// <param name="newSource">A class in the form of a string after the CodeFix was applied to it</param>
            private void VerifyFix(TAnalyzer analyzer, TCodeFix codeFixProvider, string oldSource, string newSource)
            {
                var document            = GetDocument();
                var analyzerDiagnostics = GetSortedDiagnosticsFromDocument(analyzer, document);
                var compilerDiagnostics = GetCompilerDiagnostics(document);
                var attempts            = analyzerDiagnostics.Length;

                for (int i = 0; i < attempts; ++i)
                {
                    var actions = new List <CodeAction>();
                    var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
                    codeFixProvider.RegisterCodeFixesAsync(context).Wait();

                    if (!actions.Any())
                    {
                        break;
                    }

                    document            = ApplyFix(document, actions.ElementAt(0));
                    analyzerDiagnostics = GetSortedDiagnosticsFromDocument(analyzer, document);

                    //check if there are analyzer diagnostics left after the code fix
                    if (!analyzerDiagnostics.Any())
                    {
                        break;
                    }
                }

                //after applying all of the code fixes, compare the resulting string to the inputted one
                var actual = GetStringFromDocument(document);

                Assert.Equal(newSource, actual);

                Document ApplyFix(Document document, CodeAction codeAction)
                {
                    var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
                    var solution   = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution;

                    return(solution.GetDocument(document.Id));
                }

                string GetStringFromDocument(Document document)
                {
                    var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
                    var root          = simplifiedDoc.GetSyntaxRootAsync().Result;

                    root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
                    return(root.GetText().ToString());
                }

                IEnumerable <Diagnostic> GetCompilerDiagnostics(Document document)
                {
                    return(document.GetSemanticModelAsync().Result.GetDiagnostics());
                }
            }
            public void Run()
            {
                var analyzer      = new TAnalyzer();
                var fix           = new TCodeFix();
                var actualResults = GetSortedDiagnostics(analyzer);

                VerifyDiagnosticResults(actualResults, analyzer, ExpectedDiagnostics.ToArray());

                if (FixedCode != null)
                {
                    VerifyFix(analyzer, fix, TestCode, FixedCode);
                }
            }