public <T> List<T> askChoices(String title, String message, List<T> choices)
			throws CancelledException {

		// The value parser function is only a two parameter list (String,List<T>).  We have another
		// parameter for this method's parse function.  So, curry it.
		StringTransformer<List<T>> curry = s -> parseChoices(s, choices);

		String key = join(title, message);
		List<T> existingValue = loadAskValue(curry, key);
		if (isRunningHeadless()) {
			return existingValue;
		}

		Class<?> clazz = choices.get(0).getClass();
		List<T> choice = doAsk(clazz, title, message, existingValue, lastValue -> {

			MultipleOptionsDialog<T> dialog =
				new MultipleOptionsDialog<>(title, message, choices, true);
			dialog.show();
			if (dialog.isCanceled()) {
				throw new CancelledException();
			}

			return dialog.getUserChoices();
		});

		return choice;
	}
Returns an array of Objects representing one or more choices from the given list. The actual
behavior of the method depends on your environment, which can be GUI or headless.
<p>
Regardless of environment -- if script arguments have been set, this method will use the
next argument in the array and advance the array index so the next call to an ask method
will get the next argument.  If there are no script arguments and a .properties file
sharing the same base name as the Ghidra Script exists (i.e., Script1.properties for
Script1.java), then this method will then look there for the String value to return.
The method will look in the .properties file by searching for a property name that is a
space-separated concatenation of the input String parameters (title + " " + message).
If that property name exists and its value represents valid choices, then the
.properties value will be used in the following way:
<ol>
		<li>In the GUI environment, this method displays a pop-up dialog that presents the user
		    with checkbox choices (to allow a more flexible option where the user can pick
			some, all, or none).</li>
		<li>In the headless environment, if a .properties file sharing the same base name as the
			Ghidra Script exists (i.e., Script1.properties for Script1.java), then this method
			looks there for the choices to return. The method will look in the .properties file
			by searching for a property name equal to a space-separated concatenation of the
			String parameters (title + " " + message). If that property name exists and
			represents a list (one or more) of valid choice(s) in the form
			"choice1;choice2;choice3;..." (&lt;-- note the quotes surrounding the choices), then
			an Object array of those choices is returned. Otherwise, an Exception is thrown if
			there is an invalid or missing .properties value.</li>
</ol>

@param title the title of the dialog (in GUI mode) or the first part of the variable name
			(in headless mode or when using .properties file)
@param message the message to display with the choices (in GUI mode) or the second
			part of the variable name (in headless mode or when using .properties file)
@param choices set of choices (toString() value of each object will be displayed in the dialog)
@return the user-selected value(s); an empty list if no selection was made

@throws CancelledException if the user hits the 'cancel' button
@throws IllegalArgumentException if in headless mode, there was a missing or invalid	set of
			choices specified in the .properties file
Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java