src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts/BaseConfigurationResolverService/showUserInput
class BaseConfigurationResolverService:	private showUserInput(variable: string, inputInfos: ConfiguredInput[]): Promise<string | undefined> {

		if (!inputInfos) {
			return Promise.reject(new Error(nls.localize('inputVariable.noInputSection', "Variable '{0}' must be defined in an '{1}' section of the debug or task configuration.", variable, 'input')));
		}

		// find info for the given input variable
		const info = inputInfos.filter(item => item.id === variable).pop();
		if (info) {

			const missingAttribute = (attrName: string) => {
				throw new Error(nls.localize('inputVariable.missingAttribute', "Input variable '{0}' is of type '{1}' and must include '{2}'.", variable, info.type, attrName));
			};

			switch (info.type) {

				case 'promptString': {
					if (!Types.isString(info.description)) {
						missingAttribute('description');
					}
					const inputOptions: IInputOptions = { prompt: info.description, ignoreFocusLost: true };
					if (info.default) {
						inputOptions.value = info.default;
					}
					if (info.password) {
						inputOptions.password = info.password;
					}
					return this.quickInputService.input(inputOptions).then(resolvedInput => {
						return resolvedInput;
					});
				}

				case 'pickString': {
					if (!Types.isString(info.description)) {
						missingAttribute('description');
					}
					if (Types.isArray(info.options)) {
						info.options.forEach(pickOption => {
							if (!Types.isString(pickOption) && !Types.isString(pickOption.value)) {
								missingAttribute('value');
							}
						});
					} else {
						missingAttribute('options');
					}
					interface PickStringItem extends IQuickPickItem {
						value: string;
					}
					const picks = new Array<PickStringItem>();
					info.options.forEach(pickOption => {
						const value = Types.isString(pickOption) ? pickOption : pickOption.value;
						const label = Types.isString(pickOption) ? undefined : pickOption.label;

						// If there is no label defined, use value as label
						const item: PickStringItem = {
							label: label ? `${label}: ${value}` : value,
							value: value
						};

						if (value === info.default) {
							item.description = nls.localize('inputVariable.defaultInputValue', "(Default)");
							picks.unshift(item);
						} else {
							picks.push(item);
						}
					});
					const pickOptions: IPickOptions<PickStringItem> = { placeHolder: info.description, matchOnDetail: true, ignoreFocusLost: true };
					return this.quickInputService.pick(picks, pickOptions, undefined).then(resolvedInput => {
						if (resolvedInput) {
							return resolvedInput.value;
						}
						return undefined;
					});
				}

				case 'command': {
					if (!Types.isString(info.command)) {
						missingAttribute('command');
					}
					return this.commandService.executeCommand<string>(info.command, info.args).then(result => {
						if (typeof result === 'string' || Types.isUndefinedOrNull(result)) {
							return result;
						}
						throw new Error(nls.localize('inputVariable.command.noStringType', "Cannot substitute input variable '{0}' because command '{1}' did not return a result of type string.", variable, info.command));
					});
				}

				default:
					throw new Error(nls.localize('inputVariable.unknownType', "Input variable '{0}' can only be of type 'promptString', 'pickString', or 'command'.", variable));
			}
		}
		return Promise.reject(new Error(nls.localize('inputVariable.undefinedVariable', "Undefined input variable '{0}' encountered. Remove or define '{0}' to continue.", variable)));
	}