private void processDeferredRemoves(TaskMonitor monitor) throws CancelledException {
		updateProgressMessage("Removing symbols that had been deferred...");
		monitor.setMessage("Symbol Merge: Processing removal of deferred symbols...");
		monitor.setProgress(0);

		// Save IDs to list since removal may mess up iterator.
		LongArrayList list = new LongArrayList();
		Iterator<Long> iter = deferredRemoveIDs.iterator();
		while (iter.hasNext()) {
			long id = iter.next().longValue();
			list.add(id);
		}
		// Loop and retry removing if some were removed since this may have
		// created empty namespaces that previously weren't empty.
		boolean removedSome;
		do {
			removedSome = false;
			// Check each deferred symbol still in the list.
			monitor.initialize(list.size());
			for (int i = 0; i < list.size(); i++) {
				monitor.setProgress(i);
				monitor.checkCancelled();
				long id = list.get(i);
				Symbol resultSymbol = resultSymTab.getSymbol(id);
				if (resultSymbol == null) {
					updateResolveIDs(originalPgm, id, -1);
					deferredRemoveIDs.remove(id);
					incrementProgress(1);
					continue;
				}
				Object obj = resultSymbol.getObject();
				if (obj instanceof Namespace) {
					SymbolIterator symIter = resultSymTab.getChildren(resultSymbol);
					if (!symIter.hasNext()) {
						// No longer has children so remove.
						resultSymbol.delete();
						updateResolveIDs(originalPgm, id, -1);
						deferredRemoveIDs.remove(id);
						list.remove(i--);
						removedSome |= true;
						incrementProgress(1);
					}
				}
			}
		}
		while (removedSome);
		monitor.setProgress(list.size());
	}
Determine the type of changes to the symbols in the LATEST and MY (CheckedOut) program.
Changes can be symbol removed, added, changed, renamed, and set to primary.
@param monitor task monitor for displaying progress to the user
@throws CancelledException if the user cancels the merge.
Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/SymbolMerger.java