@Override
	public void programLocationChanged(ProgramLocation p2Loc, EventTrigger trigger) {
		if (trigger == EventTrigger.MODEL_CHANGE) {
			return; // don't trigger left-side when model on right side changes.
		}
		if ((primaryProgram == null) || (primaryProgram != currentProgram) ||
			!showingSecondProgram) {
			return;
		}
		Address p2LocationAddress = p2Loc.getAddress();
		////////////////////////////////////
		// NOTE: Need to fix this, so we really get an equivalent p1Loc (primary Program location).
		// The following use of the p2Loc as a p1Loc is NOT good, but seems to work for non-overlay
		// locations. If the location is for an overlay, we will convert to a simple address
		// ProgramLocation whenever the overlay spaces are not equal (which would be
		// due to one overlay space being longer than the other.) In the non-equal overlay case,
		// using a p2Loc as a p1Loc would result in an exception.
		// Instead this really should convert any location (p2Loc) to the equivalent location in
		// the other program (p1Loc). [i.e. a MnemonicFieldLocation, etc. isn't dumbed down to a
		// ProgramLocation.]
		////////////////////////////////////
		ProgramLocation p1Loc = p2Loc;
		if (p2LocationAddress.getAddressSpace().isOverlaySpace()) {
			ProgramLocation equivalentP1Loc = DiffUtility
					.getCompatibleProgramLocation(secondaryDiffProgram, p2Loc, primaryProgram);
			if (equivalentP1Loc != null) {
				AddressSpace p2Space = p2LocationAddress.getAddressSpace();
				AddressSpace p1Space = equivalentP1Loc.getAddress().getAddressSpace();
				if (!(p2Space.equals(p1Space))) {
					p1Loc = equivalentP1Loc;
				}
			}
		}
		if (!settingLocation && !p1Loc.equals(currentLocation)) {
			MarkerSet cursorMarkers = getCursorMarkers();
			Address p1LocationAddress = p1Loc.getAddress();
			cursorMarkers.setAddressSet(new AddressSet(p2LocationAddress));

			previousP1Location = currentLocation;
			currentLocation = p1Loc;
			if (diffControl != null) {
				try {
					settingLocation = true;
					diffControl.setLocation(p1LocationAddress);
				}
				finally {
					settingLocation = false;
				}
			}
			if (secondaryDiffProgram != null) {
				try {
					settingLocation = true;
					codeViewerServiceGoTo(p1Loc);
				}
				finally {
					settingLocation = false;
				}
			}
			if (diffDetailsProvider != null && diffDetails != null) {
				diffDetailsProvider.locationChanged(p1Loc);
			}
		}
	}
Creates the plugin for indicating program differences to the user.

@param tool the tool that owns this plugin.
Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java