src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts/AbstractTaskService/customize
class AbstractTaskService:	public async customize(task: ContributedTask | CustomTask | ConfiguringTask, properties?: ICustomizationProperties, openConfig?: boolean): Promise<void> {
		if (!(await this._trust())) {
			return;
		}

		const workspaceFolder = task.getWorkspaceFolder();
		if (!workspaceFolder) {
			return Promise.resolve(undefined);
		}
		const configuration = this._getConfiguration(workspaceFolder, task._source.kind);
		if (configuration.hasParseErrors) {
			this._notificationService.warn(nls.localize('customizeParseErrors', 'The current task configuration has errors. Please fix the errors first before customizing a task.'));
			return Promise.resolve<void>(undefined);
		}

		const fileConfig = configuration.config;
		const toCustomize = this._createCustomizableTask(task);
		if (!toCustomize) {
			return Promise.resolve(undefined);
		}
		const index: number | undefined = CustomTask.is(task) ? task._source.config.index : undefined;
		if (properties) {
			for (const property of Object.getOwnPropertyNames(properties)) {
				const value = (<any>properties)[property];
				if (value !== undefined && value !== null) {
					(<any>toCustomize)[property] = value;
				}
			}
		}

		let promise: Promise<void> | undefined;
		if (!fileConfig) {
			const value = {
				version: '2.0.0',
				tasks: [toCustomize]
			};
			let content = [
				'{',
				nls.localize('tasksJsonComment', '\t// See https://go.microsoft.com/fwlink/?LinkId=733558 \n\t// for the documentation about the tasks.json format'),
			].join('\n') + JSON.stringify(value, null, '\t').substr(1);
			const editorConfig = this._configurationService.getValue<any>();
			if (editorConfig.editor.insertSpaces) {
				content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + ' '.repeat(s2.length * editorConfig.editor.tabSize));
			}
			promise = this._textFileService.create([{ resource: workspaceFolder.toResource('.vscode/tasks.json'), value: content }]).then(() => { });
		} else {
			// We have a global task configuration
			if ((index === -1) && properties) {
				if (properties.problemMatcher !== undefined) {
					fileConfig.problemMatcher = properties.problemMatcher;
					promise = this._writeConfiguration(workspaceFolder, 'tasks.problemMatchers', fileConfig.problemMatcher, task._source.kind);
				} else if (properties.group !== undefined) {
					fileConfig.group = properties.group;
					promise = this._writeConfiguration(workspaceFolder, 'tasks.group', fileConfig.group, task._source.kind);
				}
			} else {
				if (!Array.isArray(fileConfig.tasks)) {
					fileConfig.tasks = [];
				}
				if (index === undefined) {
					fileConfig.tasks.push(toCustomize);
				} else {
					fileConfig.tasks[index] = toCustomize;
				}
				promise = this._writeConfiguration(workspaceFolder, 'tasks.tasks', fileConfig.tasks, task._source.kind);
			}
		}
		if (!promise) {
			return Promise.resolve(undefined);
		}
		return promise.then(() => {
			if (openConfig) {
				this._openEditorAtTask(this._getResourceForTask(task), toCustomize);
			}
		});
	}