private void followCodeBack(TaskMonitor monitor, AddressSet flowAddressSet, CodeUnit codeUnit,
			Address dataAddress) {

		if (codeUnit == null) {
			return;
		}
		Stack<CodeUnit> codeUnitStack = new Stack<CodeUnit>(); // additional code to be processed.
		if (codeUnit instanceof Data) {
			followDataBack(codeUnitStack, flowAddressSet, (Data) codeUnit, dataAddress);
			// Make sure we don't lose the data address from the original selection,
			// if followDataBack didn't put a pointer in the flow.
			if (dataAddress != null && !flowAddressSet.contains(dataAddress)) {
				flowAddressSet.add(dataAddress);
			}
		}
		else {
			codeUnitStack.push(codeUnit);
		}

		while (!monitor.isCancelled() && !codeUnitStack.isEmpty()) {
			codeUnit = codeUnitStack.pop();
			if (codeUnit instanceof Instruction) {
				// getAdjustedInstruction() will add the instruction and any delay slots to the 
				// flowAddressSet and then return the instruction to flow backwards from.
				Instruction currentInstr =
					getAdjustedInstruction((Instruction) codeUnit, flowAddressSet);
				if (currentInstr != null) {
					followInstructionBack(codeUnitStack, flowAddressSet, currentInstr);
				}
			}
			else if (codeUnit instanceof Data) {
				followDataBack(codeUnitStack, flowAddressSet, (Data) codeUnit, dataAddress);
			}
		}
	}
followCodeBack follows the program's code unit (instruction or data) flow backwards and
adds addresses to the address set for the flow to the indicated code unit.
The plugin's properties indicate which flow types should be followed for
code units.
@param monitor a cancellable task monitor
@param flowAddressSet the address set to be added to
@param codeUnit the code unit to flow to ( or flow back from).
       Appropriate flows into this code unit will be traversed.
@param dataAddress the data address if we are trying to follow a flow to data, or
       null if flowing to an instruction.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/FollowFlow.java