internal void VerifyUnchangedDocument(
            string source,
            ActiveStatement[] oldActiveStatements,
            TextSpan?[] trackingSpansOpt,
            TextSpan[] expectedNewActiveStatements,
            ImmutableArray <TextSpan>[] expectedOldExceptionRegions,
            ImmutableArray <TextSpan>[] expectedNewExceptionRegions)
        {
            var text = SourceText.From(source);
            var tree = ParseText(source);
            var root = tree.GetRoot();

            tree.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Verify();

            DocumentId documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            TestActiveStatementTrackingService trackingService;

            if (trackingSpansOpt != null)
            {
                trackingService = new TestActiveStatementTrackingService(documentId, trackingSpansOpt);
            }
            else
            {
                trackingService = null;
            }

            var actualNewActiveStatements = new ActiveStatement[oldActiveStatements.Length];
            var actualNewExceptionRegions = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];

            Analyzer.GetTestAccessor().AnalyzeUnchangedDocument(
                oldActiveStatements.AsImmutable(),
                text,
                root,
                documentId,
                trackingService,
                actualNewActiveStatements,
                actualNewExceptionRegions);

            // check active statements:
            AssertSpansEqual(expectedNewActiveStatements, actualNewActiveStatements.Select(s => s.Span), source, text);

            // check new exception regions:
            Assert.Equal(expectedNewExceptionRegions.Length, actualNewExceptionRegions.Length);
            for (int i = 0; i < expectedNewExceptionRegions.Length; i++)
            {
                AssertSpansEqual(expectedNewExceptionRegions[i], actualNewExceptionRegions[i], source, text);
            }
        }
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldStatements;

            if (description.OldTrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.OldTrackingSpans.Length);
            }

            string newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            string oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new List <RudeEditDiagnostic>();
            var actualNewActiveStatements  = new ActiveStatement[oldActiveStatements.Length];
            var actualNewExceptionRegions  = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];
            var updatedActiveMethodMatches = new List <AbstractEditAndContinueAnalyzer.UpdatedMemberInfo>();
            var editMap = Analyzer.BuildEditMap(editScript);

            DocumentId documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            TestActiveStatementTrackingService trackingService;

            if (description.OldTrackingSpans != null)
            {
                trackingService = new TestActiveStatementTrackingService(documentId, description.OldTrackingSpans);
            }
            else
            {
                trackingService = null;
            }

            Analyzer.GetTestAccessor().AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                documentId,
                trackingService,
                oldActiveStatements.AsImmutable(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements.Select(s => s.Span), newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isNonLeaf: oldActiveStatements[i].IsNonLeaf,
                        out _);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Length);
                for (int i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }

            if (description.OldTrackingSpans != null)
            {
                // Verify that the new tracking spans are equal to the new active statements.
                AssertEx.Equal(trackingService.TrackingSpans, description.NewSpans.Select(s => (TextSpan?)s));
            }
        }
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldSpans;

            if (description.TrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.TrackingSpans.Length);
            }

            string newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            string oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new List <RudeEditDiagnostic>();
            var actualNewActiveStatements  = new LinePositionSpan[oldActiveStatements.Length];
            var actualNewExceptionRegions  = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];
            var updatedActiveMethodMatches = new List <ValueTuple <int, IReadOnlyDictionary <SyntaxNode, SyntaxNode> > >();
            var editMap = Analyzer.BuildEditMap(editScript);

            DocumentId documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            TestActiveStatementTrackingService trackingService;

            if (description.TrackingSpans != null)
            {
                trackingService = new TestActiveStatementTrackingService(documentId, description.TrackingSpans);
            }
            else
            {
                trackingService = null;
            }

            Analyzer.AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                documentId,
                trackingService,
                oldActiveStatements.AsImmutable(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements, newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isLeaf: (oldActiveStatements[i].Flags & ActiveStatementFlags.LeafFrame) != 0);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Length);
                for (int i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }

            if (description.TrackingSpans != null)
            {
                AssertEx.Equal(trackingService.TrackingSpans, description.NewSpans.Select(s => (TextSpan?)s));
            }
        }