private static async Task HandleSingleTypeAsync(CompletionContext context, SemanticModel semanticModel, SyntaxToken token, ITypeSymbol type, CancellationToken cancellationToken)
        {
            // If we have a Nullable<T>, unwrap it.
            if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
            {
                var typeArg = type.GetTypeArguments().FirstOrDefault();
                if (typeArg == null)
                {
                    return;
                }

                type = typeArg;
            }

            // When true, this completion provider shows both the type (e.g. DayOfWeek) and its qualified members (e.g.
            // DayOfWeek.Friday). We set this to false for enum-like cases (static members of structs and classes) so we
            // only show the qualified members in these cases.
            var showType           = true;
            var position           = context.Position;
            var enclosingNamedType = semanticModel.GetEnclosingNamedType(position, cancellationToken);

            if (type.TypeKind != TypeKind.Enum)
            {
                var enumType = TryGetEnumTypeInEnumInitializer(semanticModel, token, type, cancellationToken) ??
                               TryGetCompletionListType(type, enclosingNamedType, semanticModel.Compilation);

                if (enumType == null)
                {
                    if (context.Trigger.Kind == CompletionTriggerKind.Insertion && s_triggerCharacters.Contains(context.Trigger.Character))
                    {
                        // This completion provider understands static members of matching types, but doesn't
                        // proactively trigger completion for them to avoid interfering with common typing patterns.
                        return;
                    }

                    // If this isn't an enum or marked with completionlist, also check if it contains static members of
                    // a matching type. These 'enum-like' types have similar characteristics to enum completion, but do
                    // not show the containing type as a separate item in completion.
                    showType = false;
                    enumType = TryGetTypeWithStaticMembers(type);
                    if (enumType == null)
                    {
                        return;
                    }
                }

                type = enumType;
            }

            var hideAdvancedMembers = context.CompletionOptions.HideAdvancedMembers;

            if (!type.IsEditorBrowsable(hideAdvancedMembers, semanticModel.Compilation))
            {
                return;
            }

            // Does type have any aliases?
            var alias = await type.FindApplicableAliasAsync(position, semanticModel, cancellationToken).ConfigureAwait(false);

            var displayText = alias != null
                ? alias.Name
                : type.ToMinimalDisplayString(semanticModel, position);

            // Add the enum itself.
            var symbol   = alias ?? type;
            var sortText = symbol.Name;

            if (showType)
            {
                context.AddItem(SymbolCompletionItem.CreateWithSymbolId(
                                    displayText,
                                    displayTextSuffix: "",
                                    symbols: ImmutableArray.Create(symbol),
                                    rules: s_enumTypeRules,
                                    contextPosition: position,
                                    sortText: sortText));
            }

            // And now all the accessible members of the enum.
            if (type.TypeKind == TypeKind.Enum)
            {
                // We'll want to build a list of the actual enum members and all accessible instances of that enum, too
                var index = 0;

                var fields = type.GetMembers().OfType <IFieldSymbol>().Where(f => f.IsConst).Where(f => f.HasConstantValue);
                foreach (var field in fields.OrderBy(f => IntegerUtilities.ToInt64(f.ConstantValue)))
                {
                    index++;
                    if (!field.IsEditorBrowsable(hideAdvancedMembers, semanticModel.Compilation))
                    {
                        continue;
                    }

                    var memberDisplayName = $"{displayText}.{field.Name}";
                    context.AddItem(SymbolCompletionItem.CreateWithSymbolId(
                                        displayText: memberDisplayName,
                                        displayTextSuffix: "",
                                        symbols: ImmutableArray.Create <ISymbol>(field),
                                        rules: CompletionItemRules.Default,
                                        contextPosition: position,
                                        sortText: $"{sortText}_{index:0000}",
                                        filterText: memberDisplayName));
                }
            }
            else if (enclosingNamedType is not null)
            {
                // Build a list of the members with the same type as the target
                foreach (var member in type.GetMembers())
                {
                    ISymbol     staticSymbol;
                    ITypeSymbol symbolType;
                    if (member is IFieldSymbol {
                        IsStatic: true
                    } field)
                    {
                        staticSymbol = field;
                        symbolType   = field.Type;
                    }
                    else if (member is IPropertySymbol {
                        IsStatic: true, IsIndexer: false
                    } property)
                    {
                        staticSymbol = property;
                        symbolType   = property.Type;
                    }