/// <summary>
        /// Given a list of symbols, and a mapping from each symbol to its original SemanticModel,
        /// creates the list of completion items for them.
        /// </summary>
        private ImmutableArray <CompletionItem> CreateItems(
            CompletionContext completionContext,
            IEnumerable <ISymbol> symbols,
            Func <ISymbol, SyntaxContext> contextLookup,
            Dictionary <ISymbol, List <ProjectId> > invalidProjectMap,
            List <ProjectId> totalProjects,
            bool preselect,
            Lazy <ImmutableArray <ITypeSymbol> > inferredTypes,
            TelemetryCounter telemetryCounter)
        {
            // We might get symbol w/o name but CanBeReferencedByName is still set to true,
            // need to filter them out.
            // https://github.com/dotnet/roslyn/issues/47690
            var symbolGroups = from symbol in symbols
                               let texts = GetDisplayAndSuffixAndInsertionText(symbol, contextLookup(symbol))
                                           where !string.IsNullOrWhiteSpace(texts.displayText)
                                           group symbol by texts into g
                                           select g;

            var itemListBuilder         = ImmutableArray.CreateBuilder <CompletionItem>();
            var typeConvertibilityCache = new Dictionary <ITypeSymbol, bool>(SymbolEqualityComparer.Default);

            foreach (var symbolGroup in symbolGroups)
            {
                var arbitraryFirstContext = contextLookup(symbolGroup.First());
                var item = CreateItem(
                    completionContext, symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText,
                    symbolGroup.ToList(), arbitraryFirstContext, invalidProjectMap, totalProjects, preselect);

                if (IsTargetTypeCompletionFilterExperimentEnabled(arbitraryFirstContext.Workspace))
                {
                    var tick = Environment.TickCount;

                    foreach (var symbol in symbolGroup)
                    {
                        var syntaxContext = contextLookup(symbol);
                        if (ShouldIncludeInTargetTypedCompletionList(symbol, inferredTypes.Value, syntaxContext.SemanticModel, syntaxContext.Position, typeConvertibilityCache))
                        {
                            item = item.AddTag(WellKnownTags.TargetTypeMatch);
                            break;
                        }
                    }

                    telemetryCounter.AddTick(Environment.TickCount - tick);
                }

                itemListBuilder.Add(item);
            }

            return(itemListBuilder.ToImmutable());
        }
        /// <summary>
        /// Given a list of symbols, and a mapping from each symbol to its original SemanticModel,
        /// creates the list of completion items for them.
        /// </summary>
        private ImmutableArray <CompletionItem> CreateItems(
            IEnumerable <ISymbol> symbols,
            Func <ISymbol, SyntaxContext> contextLookup,
            Dictionary <ISymbol, List <ProjectId> > invalidProjectMap,
            List <ProjectId> totalProjects,
            bool preselect,
            Lazy <ImmutableArray <ITypeSymbol> > inferredTypes,
            TelemetryCounter telemetryCounter)
        {
            var symbolGroups = from symbol in symbols
                               let texts = GetDisplayAndSuffixAndInsertionText(symbol, contextLookup(symbol))
                                           group symbol by texts into g
                                           select g;

            var itemListBuilder         = ImmutableArray.CreateBuilder <CompletionItem>();
            var typeConvertibilityCache = new Dictionary <ITypeSymbol, bool>();

            foreach (var symbolGroup in symbolGroups)
            {
                var arbitraryFirstContext = contextLookup(symbolGroup.First());
                var item = this.CreateItem(
                    symbolGroup.Key.displayText, symbolGroup.Key.suffix, symbolGroup.Key.insertionText, symbolGroup.ToList(),
                    arbitraryFirstContext, invalidProjectMap, totalProjects, preselect);

                if (IsTargetTypeCompletionFilterExperimentEnabled(arbitraryFirstContext.Workspace))
                {
                    var tick = Environment.TickCount;
                    var inferredTypesWithoutNullability = inferredTypes.Value.SelectAsArray(t => t.WithoutNullability());

                    foreach (var symbol in symbolGroup)
                    {
                        var syntaxContext = contextLookup(symbol);
                        if (ShouldIncludeInTargetTypedCompletionList(symbol, inferredTypesWithoutNullability, syntaxContext.SemanticModel, syntaxContext.Position, typeConvertibilityCache))
                        {
                            item = item.AddTag(WellKnownTags.TargetTypeMatch);
                            break;
                        }
                    }

                    telemetryCounter.AddTick(Environment.TickCount - tick);
                }

                itemListBuilder.Add(item);
            }

            return(itemListBuilder.ToImmutable());
        }