/// <summary>
        ///     Provide completions for the specified location.
        /// </summary>
        /// <param name="location">
        ///     The <see cref="XmlLocation"/> where completions are requested.
        /// </param>
        /// <param name="projectDocument">
        ///     The <see cref="ProjectDocument"/> that contains the <paramref name="location"/>.
        /// </param>
        /// <param name="cancellationToken">
        ///     A <see cref="CancellationToken"/> that can be used to cancel the operation.
        /// </param>
        /// <returns>
        ///     A <see cref="Task{TResult}"/> that resolves either a <see cref="CompletionList"/>s, or <c>null</c> if no completions are provided.
        /// </returns>
        public override async Task <CompletionList> ProvideCompletions(XmlLocation location, ProjectDocument projectDocument, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }

            if (projectDocument == null)
            {
                throw new ArgumentNullException(nameof(projectDocument));
            }

            List <CompletionItem> completions = new List <CompletionItem>();

            using (await projectDocument.Lock.ReaderLockAsync())
            {
                XSElement   element;
                XSAttribute replaceAttribute;
                PaddingType needsPadding;
                if (!location.CanCompleteAttribute(out element, out replaceAttribute, out needsPadding))
                {
                    return(null);
                }

                // Must be a valid item element.
                if (!element.IsValid || !element.HasParentPath(WellKnownElementPaths.ItemGroup))
                {
                    return(null);
                }

                Range replaceRange = replaceAttribute?.Range ?? location.Position.ToEmptyRange();

                completions.AddRange(
                    WellKnownItemAttributes.Except(
                        element.AttributeNames
                        )
                    .Select(attributeName => new CompletionItem
                {
                    Label         = attributeName,
                    Detail        = "Attribute",
                    Documentation =
                        MSBuildSchemaHelp.ForItemMetadata(itemType: element.Name, metadataName: attributeName)
                        ??
                        MSBuildSchemaHelp.ForAttribute(element.Name, attributeName),
                    Kind     = CompletionItemKind.Field,
                    SortText = GetItemSortText(attributeName),
                    TextEdit = new TextEdit
                    {
                        NewText = $"{attributeName}=\"$1\"$0".WithPadding(needsPadding),
                        Range   = replaceRange.ToLsp()
                    },
                    InsertTextFormat = InsertTextFormat.Snippet
                })
                    );
            }

            if (completions.Count == 0)
            {
                return(null);
            }

            return(new CompletionList(completions, isIncomplete: false));
        }