public static Reference createReference(final Program program, final Reference ref,
			final Program otherProgram) {

		ReferenceManager otherRefMgr = otherProgram.getReferenceManager();

		if (ref.isExternalReference()) {
			Address extAddr = ref.getToAddress();
			Symbol s = program.getSymbolTable().getPrimarySymbol(extAddr);
			if (s == null || !s.isExternal()) {
				return null;
			}
			try {
				// Create external location if not found
				ExternalLocation extLoc = program.getExternalManager().getExternalLocation(s);
				Symbol otherExtSym = getSymbol(s, otherProgram);
				ExternalLocation otherExtLoc;
				if (otherExtSym == null) {
					otherExtLoc = createExtLocation(program, extLoc, otherProgram);
				}
				else {
					otherExtLoc =
						otherProgram.getExternalManager().getExternalLocation(otherExtSym);
				}
				return otherRefMgr.addExternalReference(ref.getFromAddress(), ref.getOperandIndex(),
					otherExtLoc, ref.getSource(), ref.getReferenceType());
			}
			catch (DuplicateNameException e) {
				return null;
			}
			catch (InvalidInputException e) {
				throw new AssertException(e);
			}
		}

		Address otherFromAddress =
			getCompatibleAddress(program, ref.getFromAddress(), otherProgram);
		if (otherFromAddress == null) {
			return null;
		}
		Address otherToAddress = getCompatibleAddress(program, ref.getToAddress(), otherProgram);
		if (otherToAddress == null && !ref.isStackReference()) {
			return null;
		}

		Reference newRef;
		if (ref.isOffsetReference()) {
			OffsetReference offRef = (OffsetReference) ref;
			newRef = otherRefMgr.addOffsetMemReference(otherFromAddress, offRef.getBaseAddress(),
				true, offRef.getOffset(), ref.getReferenceType(), ref.getSource(),
				ref.getOperandIndex());
		}
		else if (ref.isShiftedReference()) {
			newRef = otherRefMgr.addShiftedMemReference(otherFromAddress, otherToAddress,
				((ShiftedReference) ref).getShift(), ref.getReferenceType(), ref.getSource(),
				ref.getOperandIndex());
		}
		else if (ref.isStackReference()) {
			StackReference stackRef = (StackReference) ref;
			if (otherProgram.getFunctionManager().isInFunction(otherFromAddress)) {
				return otherRefMgr.addStackReference(otherFromAddress, ref.getOperandIndex(),
					stackRef.getStackOffset(), ref.getReferenceType(), ref.getSource());
			}
			return null;
		}
		else if (ref.isMemoryReference() || ref.isRegisterReference()) {
			newRef = otherRefMgr.addMemoryReference(otherFromAddress, otherToAddress,
				ref.getReferenceType(), ref.getSource(), ref.getOperandIndex());
		}
		else {
			return null;
		}

		long symId = ref.getSymbolID();
		if (symId > 0) {
			Symbol s = program.getSymbolTable().getSymbol(symId);
			if (s != null) {
				s = getSymbol(s, otherProgram);
				if (s != null) {
					otherRefMgr.setAssociation(s, ref);
					newRef = otherRefMgr.getReference(newRef.getFromAddress(),
						newRef.getToAddress(), newRef.getOperandIndex());
				}
			}
		}
		if (ref.isPrimary() != newRef.isPrimary()) {
			otherRefMgr.setPrimary(newRef, ref.isPrimary());
		}
		return newRef;
	}
Given a reference for a specified program, create a comparable reference in the 
specified otherProgram if possible. An open transaction on otherProgram must exist.
@param program program which contains the specified reference instance
@param ref reference to be added
@param otherProgram other program
@return new reference for otherProgram or null if unable to create reference.
Ghidra/Features/Base/src/main/java/ghidra/program/util/DiffUtility.java