private static async Task ClassifySpansAsync(
            TaggerContext <IClassificationTag> context, DocumentSnapshotSpan spanToTag,
            IEditorClassificationService classificationService, ClassificationTypeMap typeMap)
        {
            try
            {
                var document     = spanToTag.Document;
                var snapshotSpan = spanToTag.SnapshotSpan;
                var snapshot     = snapshotSpan.Snapshot;

                var cancellationToken = context.CancellationToken;
                using (Logger.LogBlock(FunctionId.Tagger_SemanticClassification_TagProducer_ProduceTags, cancellationToken))
                {
                    var classifiedSpans = ClassificationUtilities.GetOrCreateClassifiedSpanList();

                    await classificationService.AddSemanticClassificationsAsync(
                        document, snapshotSpan.Span.ToTextSpan(), classifiedSpans, cancellationToken : cancellationToken).ConfigureAwait(false);

                    ClassificationUtilities.Convert(typeMap, snapshotSpan.Snapshot, classifiedSpans, context.AddTag);
                    ClassificationUtilities.ReturnClassifiedSpanList(classifiedSpans);

                    var version = await document.Project.GetDependentSemanticVersionAsync(cancellationToken).ConfigureAwait(false);

                    // Let the context know that this was the span we actually tried to tag.
                    context.SetSpansTagged(SpecializedCollections.SingletonEnumerable(spanToTag));
                    context.State = version;
                }
            }
            catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
            public override async Task <IEnumerable <ITagSpan <IClassificationTag> > > ProduceTagsAsync(
                Document document,
                SnapshotSpan snapshotSpan,
                int?caretPosition,
                CancellationToken cancellationToken)
            {
                try
                {
                    var snapshot = snapshotSpan.Snapshot;
                    if (document == null)
                    {
                        return(SpecializedCollections.EmptyEnumerable <ITagSpan <IClassificationTag> >());
                    }

                    if (_classificationService == null)
                    {
                        _classificationService = document.Project.LanguageServices.GetService <IEditorClassificationService>();
                    }

                    if (_classificationService == null)
                    {
                        return(SpecializedCollections.EmptyEnumerable <ITagSpan <IClassificationTag> >());
                    }

                    // we don't directly reference the semantic model here, we just keep it alive so
                    // the classification service does not need to block to produce it.
                    using (Logger.LogBlock(FunctionId.Tagger_SemanticClassification_TagProducer_ProduceTags, cancellationToken))
                    {
                        var textSpan         = snapshotSpan.Span.ToTextSpan();
                        var extensionManager = document.Project.Solution.Workspace.Services.GetService <IExtensionManager>();

                        var classifiedSpans = ClassificationUtilities.GetOrCreateClassifiedSpanList();

                        await _classificationService.AddSemanticClassificationsAsync(
                            document, textSpan, classifiedSpans, cancellationToken : cancellationToken).ConfigureAwait(false);

                        return(ClassificationUtilities.ConvertAndReturnList(_typeMap, snapshotSpan.Snapshot, classifiedSpans));
                    }
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
        private static async Task ClassifySpansAsync(TaggerContext<IClassificationTag> context, DocumentSnapshotSpan spanToTag,
            IEditorClassificationService classificationService, ClassificationTypeMap typeMap)
        {
            try
            {
                var document = spanToTag.Document;
                var snapshotSpan = spanToTag.SnapshotSpan;
                var snapshot = snapshotSpan.Snapshot;

                var cancellationToken = context.CancellationToken;
                using (Logger.LogBlock(FunctionId.Tagger_SemanticClassification_TagProducer_ProduceTags, cancellationToken))
                {
                    var classifiedSpans = ClassificationUtilities.GetOrCreateClassifiedSpanList();

                    await classificationService.AddSemanticClassificationsAsync(
                        document, snapshotSpan.Span.ToTextSpan(), classifiedSpans, cancellationToken: cancellationToken).ConfigureAwait(false);

                    ClassificationUtilities.Convert(typeMap, snapshotSpan.Snapshot, classifiedSpans, context.AddTag);
                    ClassificationUtilities.ReturnClassifiedSpanList(classifiedSpans);

                    var version = await document.Project.GetDependentSemanticVersionAsync(cancellationToken).ConfigureAwait(false);

                    // Let the context know that this was the span we actually tried to tag.
                    context.SetSpansTagged(SpecializedCollections.SingletonEnumerable(spanToTag));
                    context.State = version;
                }
            }
            catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }