async Task <List <MSBuildCodeFix> > GetSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
        {
            // grab selection first as we are on the UI thread at this point, and can avoid switching to it later
            var possibleSelection = TryGetSelectedSpan();

            var result = await parser.GetOrProcessAsync(range.Snapshot, cancellationToken);

            List <MSBuildCodeFix> actions = null;

            var severities = CategoriesToSeverity(requestedActionCategories);

            if (severities != 0)
            {
                actions = await provider.CodeFixService.GetFixes(textBuffer, result, range, severities, cancellationToken);

                for (int i = 0; i < actions.Count; i++)
                {
                    if (!requestedActionCategories.Contains(actions[i].Category))
                    {
                        actions.RemoveAt(i);
                        i--;
                    }
                }
            }

            if (possibleSelection is SnapshotSpan selection && requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring))
            {
                var refactorings = await provider.RefactoringService.GetRefactorings(result, selection, cancellationToken);

                if (actions != null)
                {
                    actions.AddRange(refactorings);
                }
                else
                {
                    actions = refactorings;
                }
            }

            return(actions);
        }
        public async Task <QuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
        {
            var snapshot = textBuffer.CurrentSnapshot;

            var result = await parser.GetOrProcessAsync(snapshot, cancellationToken);

            var doc = result?.MSBuildDocument;

            if (doc == null)
            {
                return(null);
            }

            var trigger = session.GetTriggerPoint(textBuffer);
            var offset  = trigger.GetPosition(snapshot);

            var spine = parser.XmlParser.GetSpineParser(new SnapshotPoint(snapshot, offset));

            var annotations = MSBuildNavigation.GetAnnotationsAtOffset <NavigationAnnotation> (doc, offset)?.ToList();

            if (annotations != null && annotations.Count > 0)
            {
                return(CreateQuickInfo(snapshot, annotations));
            }

            //FIXME: can we avoid awaiting this unless we actually need to resolve a function? need to propagate async downwards
            await provider.FunctionTypeProvider.EnsureInitialized(cancellationToken);

            var rr = MSBuildResolver.Resolve(
                spine, snapshot.GetTextSource(), doc, provider.FunctionTypeProvider, cancellationToken
                );

            if (rr != null)
            {
                if (rr.ReferenceKind == MSBuildReferenceKind.NuGetID)
                {
                    return(await CreateNuGetQuickInfo(snapshot, doc, rr, cancellationToken));
                }
                var info = rr.GetResolvedReference(doc, provider.FunctionTypeProvider);
                if (info != null)
                {
                    var element = await provider.DisplayElementFactory.GetInfoTooltipElement(
                        session.TextView.TextBuffer, doc, info, rr, cancellationToken
                        );

                    return(new QuickInfoItem(
                               snapshot.CreateTrackingSpan(rr.ReferenceOffset, rr.ReferenceLength, SpanTrackingMode.EdgeInclusive),
                               element));
                }
            }
            return(null);
        }
        GetHighlightsAsync(SnapshotPoint caretLocation, CancellationToken token)
        {
            var snapshot    = caretLocation.Snapshot;
            var spineParser = parser.XmlParser.GetSpineParser(caretLocation);
            var textSource  = snapshot.GetTextSource();
            var doc         = parser.LastOutput?.MSBuildDocument;

            if (doc == null)
            {
                return(Empty);
            }

            var rr = MSBuildResolver.Resolve(spineParser, textSource, doc, provider.FunctionTypeProvider, token);

            if (!MSBuildReferenceCollector.CanCreate(rr))
            {
                return(Empty);
            }

            var parseResult = await parser.GetOrProcessAsync(snapshot, token).ConfigureAwait(false);

            doc = parseResult?.MSBuildDocument;
            if (doc == null)
            {
                return(Empty);
            }

            var references = new List <(ReferenceUsage usage, SnapshotSpan span)> ();
            var collector  = MSBuildReferenceCollector.Create(
                rr, provider.FunctionTypeProvider,
                r => references.Add((r.Usage, new SnapshotSpan(snapshot, r.Offset, r.Length))));

            await Task.Run(() => collector.Run(doc, token: token), token);

            return(
                new SnapshotSpan(caretLocation.Snapshot, rr.ReferenceOffset, rr.ReferenceLength),
                references.ToImmutableArray());
        }