private void checkDoApplyFunctionDefinition(TaskMonitor monitor, String functionName,
			FunctionDefinition fdef, Symbol sym) {

		monitor.setMessage("Apply Function Signature '" + functionName + "'");

		// function
		//    maybe change its signature
		Address address = sym.getAddress();

		Function func = program.getFunctionManager().getFunctionAt(address);
		if (func != null) {
			if (func.isThunk() || func.getSignature(true).equals(fdef)) {
				return;
			}

			SourceType mostTrusted = getMostTrustedParameterSource(func);
			// Do not replace function if one with same SourceType exists
			if (alwaysReplace || source.isHigherPriorityThan(mostTrusted)) {
				applyFunction(sym, fdef);
			}
			return;
		}

		// check if already part of a function
		func = program.getFunctionManager().getFunctionContaining(address);
		if (func != null) {
			// overlap, don't apply
			return;
		}

		if (!isValidFunctionStart(monitor, address)) {
			return;
		}

		// no function
		//    maybe apply
		CreateFunctionCmd functionCmd = new CreateFunctionCmd(address);
		Listing listing = program.getListing();
		if (sym.isExternal() || listing.getInstructionAt(address) != null) {
			// instruction or external - create function, change its signature
			functionCmd.applyTo(program);
			applyFunction(sym, fdef);
			return;
		}

		// symbols in uninitialized blocks are pushed into externals by importer
		MemoryBlock block = program.getMemory().getBlock(address);
		if (block != null && !block.isInitialized()) {
			return;
		}

		if (listing.getUndefinedDataAt(address) != null) {
			// undefined data - check for likely code
			PseudoDisassembler pdis = new PseudoDisassembler(program);
			if (pdis.isValidSubroutine(address)) {
				DisassembleCommand disassembleCmd = new DisassembleCommand(address, null, true);
				disassembleCmd.applyTo(program);
				functionCmd.applyTo(program);
				applyFunction(sym, fdef);
			}
		}
	}
Apply all descendants starting at each category node.
@param monitor task monitor
@param symbolMap symbol map where possible function definitions may be applied
@throws CancelledException if task cancelled
Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java