public async Task TestTagsChangedForEntireFile()
        {
            var code =
@"class Program2
{
    string x = @""/// <summary>$$
/// </summary>"";
}";
            using (var workspace = await TestWorkspace.CreateCSharpAsync(code))
            {
                var document = workspace.Documents.First();
                var subjectBuffer = document.TextBuffer;
                var checkpoint = new Checkpoint();
                var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer(
                    subjectBuffer,
                    workspace.GetService<IForegroundNotificationService>(),
                    AggregateAsynchronousOperationListener.CreateEmptyListener(),
                    null,
                    new SyntacticClassificationTaggerProvider(null, null, null));

                // Capture the expected value before the await, in case it changes.
                var expectedLength = subjectBuffer.CurrentSnapshot.Length;
                int? actualVersionNumber = null;
                int? actualLength = null;
                List<string> callstacks = new List<string>();
                tagComputer.TagsChanged += (s, e) =>
                {
                    actualVersionNumber = e.Span.Snapshot.Version.VersionNumber;
                    actualLength = e.Span.Length;
                    callstacks.Add(new StackTrace().ToString());
                    checkpoint.Release();
                };

                await checkpoint.Task;
                Assert.Equal(1, actualVersionNumber);
                Assert.Equal(expectedLength, actualLength);
                Assert.Equal(1, callstacks.Count);

                checkpoint = new Checkpoint();

                // Now apply an edit that require us to reclassify more that just the current line
                var snapshot = subjectBuffer.Insert(document.CursorPosition.Value, "\"");
                expectedLength = snapshot.Length;

                // NOTE: TagsChanged is raised on the UI thread, so there is no race between
                // assigning expected here and verifying in the event handler, because the
                // event handler can't run until we await.
                await checkpoint.Task;
                Assert.Equal(2, actualVersionNumber);
                Assert.Equal(expectedLength, actualLength);
                Assert.Equal(2, callstacks.Count);
            }
        }
        public async Task TestTagsChangedForEntireFile()
        {
            var code =
@"class Program2
{
    string x = @""/// <summary>$$
/// </summary>"";
}";
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(code))
            {
                var document = workspace.Documents.First();
                var subjectBuffer = document.TextBuffer;
                var checkpoint = new Checkpoint();
                var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer(
                    subjectBuffer,
                    workspace.GetService<IForegroundNotificationService>(),
                    AggregateAsynchronousOperationListener.CreateEmptyListener(),
                    typeMap: null,
                    taggerProvider: new SyntacticClassificationTaggerProvider(
                        notificationService: null,
                        typeMap: null,
                        viewSupportsClassificationServiceOpt: null,
                        associatedViewService: null,
                        allLanguageServices: ImmutableArray<Lazy<ILanguageService, LanguageServiceMetadata>>.Empty,
                        contentTypes: ImmutableArray<Lazy<ILanguageService, ContentTypeLanguageMetadata>>.Empty,
                        asyncListeners: ImmutableArray<Lazy<IAsynchronousOperationListener, FeatureMetadata>>.Empty),
                    viewSupportsClassificationServiceOpt: null,
                    associatedViewService: null,
                    editorClassificationService: null,
                    languageName: null);

                SnapshotSpan span = default(SnapshotSpan);
                tagComputer.TagsChanged += (s, e) =>
                {
                    span = e.Span;
                    checkpoint.Release();
                };

                await checkpoint.Task.ConfigureAwait(true);
                checkpoint = new Checkpoint();

                // Now apply an edit that require us to reclassify more that just the current line
                subjectBuffer.Insert(document.CursorPosition.Value, "\"");

                await checkpoint.Task.ConfigureAwait(true);
                Assert.Equal(subjectBuffer.CurrentSnapshot.Length, span.Length);
            }
        }
        public async Task TestTagsChangedForEntireFile()
        {
            var code =
@"class Program2
{
    string x = @""/// <summary>$$
/// </summary>"";
}";
            using (var workspace = await TestWorkspace.CreateCSharpAsync(code))
            {
                var document = workspace.Documents.First();
                var subjectBuffer = document.TextBuffer;
                var checkpoint = new Checkpoint();
                var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer(
                    subjectBuffer,
                    workspace.GetService<IForegroundNotificationService>(),
                    AggregateAsynchronousOperationListener.CreateEmptyListener(),
                    null,
                    new SyntacticClassificationTaggerProvider(null, null, null));

                SnapshotSpan span = default(SnapshotSpan);
                tagComputer.TagsChanged += (s, e) =>
                {
                    span = e.Span;
                    checkpoint.Release();
                };

                await checkpoint.Task;
                checkpoint = new Checkpoint();

                // Now apply an edit that require us to reclassify more that just the current line
                subjectBuffer.Insert(document.CursorPosition.Value, "\"");

                await checkpoint.Task;
                Assert.Equal(subjectBuffer.CurrentSnapshot.Length, span.Length);
            }
        }