void determineFunctionConflicts(Function[] functions, boolean ignoreNames, TaskMonitor monitor)
			throws CancelledException {
		monitor.checkCancelled();
		boolean isExternalFunction = (functions[LATEST] != null) ? functions[LATEST].isExternal()
				: ((functions[MY] != null) ? functions[MY].isExternal()
						: functions[ORIGINAL].isExternal());

		int functionConflictFlags = 0;

		int latestMyChanges = getFunctionDiffs(functions[LATEST], functions[MY]);
		if (latestMyChanges != 0) {

			int originalLatestChanges = getFunctionDiffs(functions[ORIGINAL], functions[LATEST]);
			int originalMyChanges = getFunctionDiffs(functions[ORIGINAL], functions[MY]);

//					functionConflictFlags |=
//						determineFunctionConflict(functions, FUNC_RETURN_TYPE, latestMyChanges,
//							originalLatestChanges, originalMyChanges, monitor);
			functionConflictFlags |=
				determineFunctionConflict(functions, FUNC_RETURN_ADDRESS_OFFSET, latestMyChanges,
					originalLatestChanges, originalMyChanges, monitor);

			// For now, we are not allowing you to set the parameter offset or local size outright.
			//		functionConflictFlags |=
			//			determineFunctionConflict(entry, FUNC_PARAMETER_OFFSET, latestMyChanges,
			//				originalLatestChanges, originalMyChanges, monitor);
			//		functionConflictFlags |=
			//			determineFunctionConflict(entry, FUNC_LOCAL_SIZE, latestMyChanges,
			//				originalLatestChanges, originalMyChanges, monitor);
			functionConflictFlags |= determineFunctionConflict(functions, FUNC_STACK_PURGE_SIZE,
				latestMyChanges, originalLatestChanges, originalMyChanges, monitor);
			if (!ignoreNames) {
				functionConflictFlags |= determineFunctionConflict(functions, FUNC_NAME,
					latestMyChanges, originalLatestChanges, originalMyChanges, monitor);
			}
			functionConflictFlags |= determineFunctionConflict(functions, FUNC_INLINE,
				latestMyChanges, originalLatestChanges, originalMyChanges, monitor);
			functionConflictFlags |= determineFunctionConflict(functions, FUNC_NO_RETURN,
				latestMyChanges, originalLatestChanges, originalMyChanges, monitor);

			// If FUNC_CALLING_CONVENTION conflict we must delay checking any storage related conflicts
			functionConflictFlags |= determineFunctionConflict(functions, FUNC_CALLING_CONVENTION,
				latestMyChanges, originalLatestChanges, originalMyChanges, monitor);
			functionConflictFlags |= determineFunctionConflict(functions, FUNC_SIGNATURE_SOURCE,
				latestMyChanges, originalLatestChanges, originalMyChanges, monitor);
		}

		// If the calling-convention is in conflict we must defer any specific storage and variable checking
		if ((functionConflictFlags & (FUNC_CALLING_CONVENTION)) == 0) {

			FunctionVariableStorageConflicts variableStorageConflicts = null;
			boolean skipParamChecks = false;
			if (!isExternalFunction) {
				variableStorageConflicts = determineStorageConflict(functions, monitor);
				skipParamChecks = variableStorageConflicts != null &&
					variableStorageConflicts.hasParameterConflict();
			}

			if (!skipParamChecks && determineSignatureConflicts(functions, monitor)) {
				determineParameterInfoConflicts(functions, true, monitor);
			}

			determineReturnConflict(functions, true, monitor);

			if (!isExternalFunction) {
				determineLocalVariableInfoConflicts(functions, true, variableStorageConflicts,
					monitor);
			}
		}

		if (functionConflictFlags != 0) {
			saveFunctionDetailConflict(functions, functionConflictFlags);
		}
	}
Compares the functions (Latest, Original, My) to determine where conflicting changes
have been made to Latest and My. It then saves the conflict info within the merger for 
later resolution and processing.
@param functions the matching set of functions from Result, Latest, My, and Original.
(Use MergeConstants.RESULT, LATEST, MY, ORIGINAL to reference these.)
@param ignoreNames true indicates that function name differences should not be detected.
@param monitor the merge status monitor
@throws CancelledException if merge has been cancelled.
Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/AbstractFunctionMerger.java