private static Address getFlowingAddrFromFinalState(Program program, Instruction instr,
			FlowType flowType, boolean checkForSideEffects, HashSet<Varnode> setRegisters,
			HashSet<Varnode> usedRegisters) {

		// conditional jumps/call terminators can't be thunks,
		// unless not checkingForSideEffects and just trying to get possible thunk address.
		
		boolean isJump = flowType.isJump();
		boolean isCall = flowType.isCall();
		boolean isConditional = flowType.isConditional();
		
		// only jump/call are allowed
		if (!(isJump || isCall)) {
			return null;
		}
		
		// no conditional jumps allowed
		if (isJump && isConditional) {
			return null;
		}
		
		if (isCall) {
			// Any conditional call considered as having side-effects
			if (isConditional && checkForSideEffects) {
				return null;
			}
			// CALL_TERMINATOR, COMPUTED_CALL_TERMINATOR
			else if (!flowType.isTerminal()) {
				if (flowType == COMPUTED_CALL ||
					flowType == UNCONDITIONAL_CALL) {
					// consider any simple call having side-effects
					if (checkForSideEffects) {
						return null;
					}
				}
			}
		}
		
		// program counter should be assumed to be used
		// assume PC is used when considering registers that have been set
		Register PC = program.getLanguage().getProgramCounter();
		if (PC != null) {
			usedRegisters.add(new Varnode(PC.getAddress(), PC.getMinimumByteSize()));
		}
		setRegisters.removeAll(usedRegisters);

		// check that the setRegisters are all hidden, meaning don't care.
		for (Iterator<Varnode> iterator = setRegisters.iterator(); iterator.hasNext();) {
			Varnode rvnode = iterator.next();
			Register reg = program.getRegister(rvnode);
			// the register pcode access could have fallen in the middle of a valid register
			//  thus no register will exist at the varnode
			if (reg != null && reg.isHidden()) {
				iterator.remove();
			}
		}

		Address flowingAddr = null;
		
		// if not checking for sideEffect registers set, or there are no side-effects
		if (!checkForSideEffects || setRegisters.size() == 0) {
			flowingAddr = getFlowingAddress(program, instr);
		}
		
		return flowingAddr;
	}
Handle conversion of label within reserved EXTERNAL block to a real 
external function which can be thunked.  This may be necessary when a
loaded symbol failed to identify itself as a function.  This will 
only handle single symbols contained within the global namespace.

@param program the program
@param entry function being created
@return newly created external function address or null
Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateThunkFunctionCmd.java