extensions/npm/src/features/bowerJSONContribution.ts/BowerJSONContribution/collectPropertySuggestions
class BowerJSONContribution:	public collectPropertySuggestions(_resource: Uri, location: Location, currentWord: string, addValue: boolean, isLast: boolean, collector: ISuggestionsCollector): Thenable<any> | null {
		if (!this.isEnabled()) {
			return null;
		}
		if ((location.matches(['dependencies']) || location.matches(['devDependencies']))) {
			if (currentWord.length > 0) {
				const queryUrl = 'https://registry.bower.io/packages/search/' + encodeURIComponent(currentWord);

				return this.xhr({
					url: queryUrl,
					headers: { agent: USER_AGENT }
				}).then((success) => {
					if (success.status === 200) {
						try {
							const obj = JSON.parse(success.responseText);
							if (Array.isArray(obj)) {
								const results = <{ name: string; description: string }[]>obj;
								for (const result of results) {
									const name = result.name;
									const description = result.description || '';
									const insertText = new SnippetString().appendText(JSON.stringify(name));
									if (addValue) {
										insertText.appendText(': ').appendPlaceholder('latest');
										if (!isLast) {
											insertText.appendText(',');
										}
									}
									const proposal = new CompletionItem(name);
									proposal.kind = CompletionItemKind.Property;
									proposal.insertText = insertText;
									proposal.filterText = JSON.stringify(name);
									proposal.documentation = description;
									collector.add(proposal);
								}
								collector.setAsIncomplete();
							}
						} catch (e) {
							// ignore
						}
					} else {
						collector.error(localize('json.bower.error.repoaccess', 'Request to the bower repository failed: {0}', success.responseText));
						return 0;
					}
					return undefined;
				}, (error) => {
					collector.error(localize('json.bower.error.repoaccess', 'Request to the bower repository failed: {0}', error.responseText));
					return 0;
				});
			} else {
				this.topRanked.forEach((name) => {
					const insertText = new SnippetString().appendText(JSON.stringify(name));
					if (addValue) {
						insertText.appendText(': ').appendPlaceholder('latest');
						if (!isLast) {
							insertText.appendText(',');
						}
					}

					const proposal = new CompletionItem(name);
					proposal.kind = CompletionItemKind.Property;
					proposal.insertText = insertText;
					proposal.filterText = JSON.stringify(name);
					proposal.documentation = '';
					collector.add(proposal);
				});
				collector.setAsIncomplete();
				return Promise.resolve(null);
			}
		}
		return null;
	}