private void TestAnnotations(
            string expectedText,
            IList <TextSpan> expectedSpans,
            SyntaxNode fixedRoot,
            string annotationKind,
            bool compareTokens,
            ParseOptions parseOptions = null)
        {
            expectedSpans = expectedSpans ?? new List <TextSpan>();
            var annotatedTokens = fixedRoot.GetAnnotatedNodesAndTokens(annotationKind).Select(n => (SyntaxToken)n).ToList();

            Assert.Equal(expectedSpans.Count, annotatedTokens.Count);

            if (expectedSpans.Count > 0)
            {
                var expectedTokens = TokenUtilities.GetTokens(TokenUtilities.GetSyntaxRoot(expectedText, GetLanguage(), parseOptions));
                var actualTokens   = TokenUtilities.GetTokens(fixedRoot);

                for (var i = 0; i < Math.Min(expectedTokens.Count, actualTokens.Count); i++)
                {
                    var expectedToken = expectedTokens[i];
                    var actualToken   = actualTokens[i];

                    var actualIsConflict   = annotatedTokens.Contains(actualToken);
                    var expectedIsConflict = expectedSpans.Contains(expectedToken.Span);
                    Assert.Equal(expectedIsConflict, actualIsConflict);
                }
            }
        }
        protected async Task <Tuple <Solution, Solution> > TestOperationsAsync(
            TestWorkspace workspace,
            string expectedText,
            ImmutableArray <CodeActionOperation> operations,
            ImmutableArray <TextSpan> conflictSpans,
            ImmutableArray <TextSpan> renameSpans,
            ImmutableArray <TextSpan> warningSpans,
            ImmutableArray <TextSpan> navigationSpans,
            DocumentId expectedChangedDocumentId,
            ParseOptions parseOptions = null)
        {
            var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations);
            var oldSolution    = appliedChanges.Item1;
            var newSolution    = appliedChanges.Item2;

            if (TestWorkspace.IsWorkspaceElement(expectedText))
            {
                await VerifyAgainstWorkspaceDefinitionAsync(expectedText, newSolution);

                return(Tuple.Create(oldSolution, newSolution));
            }

            var document = GetDocumentToVerify(expectedChangedDocumentId, oldSolution, newSolution);

            var fixedRoot = await document.GetSyntaxRootAsync();

            var actualText = fixedRoot.ToFullString();

            Assert.Equal(expectedText, actualText);

            TestAnnotations(conflictSpans, ConflictAnnotation.Kind);
            TestAnnotations(renameSpans, RenameAnnotation.Kind);
            TestAnnotations(warningSpans, WarningAnnotation.Kind);
            TestAnnotations(navigationSpans, NavigationAnnotation.Kind);

            return(Tuple.Create(oldSolution, newSolution));

            void TestAnnotations(ImmutableArray <TextSpan> expectedSpans, string annotationKind)
            {
                var annotatedTokens = fixedRoot.GetAnnotatedNodesAndTokens(annotationKind).Select(n => (SyntaxToken)n).ToList();

                Assert.Equal(expectedSpans.Length, annotatedTokens.Count);

                if (expectedSpans.Length > 0)
                {
                    var expectedTokens = TokenUtilities.GetTokens(TokenUtilities.GetSyntaxRoot(expectedText, GetLanguage(), parseOptions));
                    var actualTokens   = TokenUtilities.GetTokens(fixedRoot);

                    for (var i = 0; i < Math.Min(expectedTokens.Count, actualTokens.Count); i++)
                    {
                        var expectedToken = expectedTokens[i];
                        var actualToken   = actualTokens[i];

                        var actualIsConflict   = annotatedTokens.Contains(actualToken);
                        var expectedIsConflict = expectedSpans.Contains(expectedToken.Span);
                        Assert.Equal(expectedIsConflict, actualIsConflict);
                    }
                }
            }
        }