private void determineExternalAddConflicts(TaskMonitor monitor) throws CancelledException {
		monitor.checkCancelled();
		if (totalChanges <= 0) {
			return;
		}
		mergeManager.updateProgress((changeNum / totalChanges) * 100,
			"Finding conflicts for added externals.");

		// LATEST adds are already in RESULT.
		changeNum += latestAddIDs.size();
		mergeManager.updateProgress((changeNum / totalChanges) * 100);

		// MY adds may conflict with LATEST adds that are already in RESULT.
		Iterator<Long> myIterator = myAddIDs.iterator();
		while (myIterator.hasNext()) {
			monitor.checkCancelled();
			long myID = myIterator.next();
			Symbol mySymbol = symbolTables[MY].getSymbol(myID);
			// Non-primary symbols are "original" symbols and we don't need to match these.
			if (!mySymbol.isPrimary()) {
				continue;
			}
			ExternalLocation myExternalLocation =
				externalManagers[MY].getExternalLocation(mySymbol);
			if (myExternalLocation == null) {
				throw new AssertException("Why don't we have an external location?");
			}
			// Get the external symbol in LATEST that we think most likely matches MY external.
			// Only try to match it with externals that were also added in LATEST.
			Symbol latestSymbol = SimpleDiffUtility.getMatchingExternalSymbol(programs[MY],
				mySymbol, programs[LATEST], false, latestAddIDs);
			ExternalLocation latestExternalLocation = null;
			if (latestSymbol != null) {
				// We have a possible matching external from LATEST.
				SymbolType symbolType = latestSymbol.getSymbolType();
				if (symbolType == SymbolType.LABEL || symbolType == SymbolType.FUNCTION) {
					latestExternalLocation =
						externalManagers[LATEST].getExternalLocation(latestSymbol);
				}
			}
			if (latestExternalLocation == null) {
				// Couldn't find an external in LATEST that we think matches this one in MY.
				// So just add this one and give it a conflict name if necessary.
				try {
					ExternalLocation resultExternalLocation =
						addExternal(myExternalLocation, monitor);

					ExternalLocation[] externalLocations = new ExternalLocation[] {
						resultExternalLocation, latestExternalLocation, myExternalLocation, null };
					adjustIDMapsForAdd(externalLocations, resultExternalLocation, MY);
				}
				catch (DuplicateNameException e) {
					Msg.error(this, "Couldn't add external '" +
						myExternalLocation.getSymbol().getName(true) + ",. " + e.getMessage());
				}
				catch (InvalidInputException e) {
					Msg.error(this, "Couldn't add external '" +
						myExternalLocation.getSymbol().getName(true) + ",. " + e.getMessage());
				}
				continue;
			}

			// Check the externals for add conflicts. If there are any then present them with a
			// choice between Keep Latest, Keep My, Keep Both, or Merge Together.
			boolean hasExternalAddConflicts =
				hasExternalAddConflicts(latestExternalLocation, myExternalLocation);
			if (hasExternalAddConflicts) {
				// Check to see if this is a new external function versus a new external data label.
				if (isAddConflictSpecialFunctionVsData(latestExternalLocation, myExternalLocation,
					monitor)) {
					// Only give the latest vs my choices. Don't allow KeepBoth or MergeBoth.
					saveExternalFunctionVersusDataTypeConflict(
						myExternalLocation.getExternalSpaceAddress());
					continue;
				}
				saveExternalAddConflict(latestExternalLocation, myExternalLocation, monitor);
				continue;
			}

			// Otherwise, merge MY and RESULT (originally matched LATEST).
			mergeAddsAndDetermineConflicts(latestExternalLocation, myExternalLocation, monitor);

			mergeManager.updateProgress((++changeNum / totalChanges) * 100);
		}
	}
<CODE>replaceExternalDataType</CODE> replaces the data type of the
external label in program1 with the data type of the external label in program2
at the specified external space address.
@param resultExternalLocation
@param fromExternalLocation
@param monitor the task monitor for notifying the user of this merge's progress.
@throws CancelledException
Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ExternalFunctionMerger.java