src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts/AbstractTaskService/_attachProblemMatcher
class AbstractTaskService:	private async _attachProblemMatcher(task: ContributedTask | CustomTask): Promise<Task | undefined> {
		interface IProblemMatcherPickEntry extends IQuickPickItem {
			matcher: INamedProblemMatcher | undefined;
			never?: boolean;
			learnMore?: boolean;
			setting?: string;
		}
		let entries: QuickPickInput<IProblemMatcherPickEntry>[] = [];
		for (const key of ProblemMatcherRegistry.keys()) {
			const matcher = ProblemMatcherRegistry.get(key);
			if (matcher.deprecated) {
				continue;
			}
			if (matcher.name === matcher.label) {
				entries.push({ label: matcher.name, matcher: matcher });
			} else {
				entries.push({
					label: matcher.label,
					description: `$${matcher.name}`,
					matcher: matcher
				});
			}
		}
		if (entries.length === 0) {
			return;
		}
		entries = entries.sort((a, b) => {
			if (a.label && b.label) {
				return a.label.localeCompare(b.label);
			} else {
				return 0;
			}
		});
		entries.unshift({ type: 'separator', label: nls.localize('TaskService.associate', 'associate') });
		let taskType: string;
		if (CustomTask.is(task)) {
			const configProperties: TaskConfig.IConfigurationProperties = task._source.config.element;
			taskType = (<any>configProperties).type;
		} else {
			taskType = task.getDefinition().type;
		}
		entries.unshift(
			{ label: nls.localize('TaskService.attachProblemMatcher.continueWithout', 'Continue without scanning the task output'), matcher: undefined },
			{ label: nls.localize('TaskService.attachProblemMatcher.never', 'Never scan the task output for this task'), matcher: undefined, never: true },
			{ label: nls.localize('TaskService.attachProblemMatcher.neverType', 'Never scan the task output for {0} tasks', taskType), matcher: undefined, setting: taskType },
			{ label: nls.localize('TaskService.attachProblemMatcher.learnMoreAbout', 'Learn more about scanning the task output'), matcher: undefined, learnMore: true }
		);
		const problemMatcher = await this._quickInputService.pick(entries, { placeHolder: nls.localize('selectProblemMatcher', 'Select for which kind of errors and warnings to scan the task output') });
		if (!problemMatcher) {
			return task;
		}
		if (problemMatcher.learnMore) {
			this._openDocumentation();
			return undefined;
		}
		if (problemMatcher.never) {
			this.customize(task, { problemMatcher: [] }, true);
			return task;
		}
		if (problemMatcher.matcher) {
			const newTask = task.clone();
			const matcherReference = `$${problemMatcher.matcher.name}`;
			const properties: ICustomizationProperties = { problemMatcher: [matcherReference] };
			newTask.configurationProperties.problemMatchers = [matcherReference];
			const matcher = ProblemMatcherRegistry.get(problemMatcher.matcher.name);
			if (matcher && matcher.watching !== undefined) {
				properties.isBackground = true;
				newTask.configurationProperties.isBackground = true;
			}
			this.customize(task, properties, true);
			return newTask;
		}
		if (problemMatcher.setting) {
			await this._updateNeverProblemMatcherSetting(problemMatcher.setting);
		}
		return task;
	}