@Override
	public boolean applyTo(Program program, TaskMonitor monitor) {

		if (program != location.getProgram()) {
			throw new AssertionError("program does not match location");
		}

		Function function =
			program.getFunctionManager().getFunctionContaining(location.getAddress());
		if (function == null) {
			setStatusMsg("Function not found at " + location.getAddress());
			return false;
		}

		FillOutStructureHelper fillStructureHelper =
			new FillOutStructureHelper(program, monitor);
		DecompInterface decompInterface = fillStructureHelper.setUpDecompiler(decompileOptions);
		try {
			HighVariable var = null;

			if (!(location instanceof DecompilerLocation dloc)) {
				// if we don't have one, make one, and map variable to a varnode
				Address storageAddr = computeStorageAddress(function);
				var =
					fillStructureHelper.computeHighVariable(storageAddr, function, decompInterface);
			}
			else {

				// get the Varnode under the cursor
				ClangToken token = dloc.getToken();
				if (token == null) {
					setStatusMsg("Unable to identify variable from decompiler token");
					return false;
				}

				var = token.getHighVariable();
				Varnode exactSpot = token.getVarnode();

				if ((var != null) && (exactSpot != null)) {
					HighFunction hfunc = var.getHighFunction();
					try { // Adjust HighVariable based on exact varnode selected, if there are merged groups
						var = hfunc.splitOutMergeGroup(var, exactSpot);
					}
					catch (PcodeException ex) {
						setStatusMsg("Unable to isolate variable from merged group");
						return false;
					}
				}
			}

			Structure structDT =
				fillStructureHelper.processStructure(var, function, false, true, decompInterface);
			if (structDT == null) {
				setStatusMsg("Failed to fill-out structure");
				return false;
			}

			DataType pointerDT = new PointerDataType(structDT);

			// Delay adding to the manager until full structure is accumulated
			pointerDT = program.getDataTypeManager()
					.addDataType(pointerDT, DataTypeConflictHandler.DEFAULT_HANDLER);

			boolean isThisParam = DecompilerUtils.isThisParameter(var, function);
			if (!isThisParam) {
				commitVariable(var, pointerDT, isThisParam);
			}

			return true;
		}
		catch (Exception e) {
			Msg.showError(this, null, "Auto Create Structure Failed",
				"Failed to create Structure variable", e);
		}
		finally {
			decompInterface.dispose();
		}
		return false;
	}
Constructor.

@param location the current program location.  Supported location types include:
  {@link DecompilerLocation}, {@link VariableLocation} or 
  {@link FunctionParameterFieldLocation}.
@param decompileOptions decompiler options.  
  (see {@link DecompilerUtils#getDecompileOptions(ServiceProvider, Program)})
Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/util/FillOutStructureCmd.java