private static int followIndirection(LinkedList<CodeBlockReferenceImpl> blockRefQueue, boolean includeExternals, CodeBlock srcBlock, 
    	Reference srcRef, FlowType indirectFlowType, TaskMonitor monitor) 
    	throws CancelledException {	
		
		SimpleBlockModel model = (SimpleBlockModel)srcBlock.getModel();
		Address addr = srcRef.getToAddress();
		Listing listing = model.getListing();
		Data data = listing.getDefinedDataContaining(addr);
		if (data == null)
			return 0;
			
    	int cnt = 0;
    	
// ?? Handle special cases - offset is 0 within array of pointers, or offset to pointer within array of structures
    	
    	int offset = (int)addr.subtract(data.getMinAddress());
    	Data primitive = data.getPrimitiveAt(offset);
    	if (primitive != null) {

			// Follow pointer - could have multiple references 			
			Reference refs[] = primitive.getReferencesFrom();
			for (int i = 0; i < refs.length; i++) {
				
				monitor.checkCancelled();
				
				CodeBlock destBlock = null;
				
				Address toAddr = refs[i].getToAddress();
				if (toAddr.isMemoryAddress()) {
				
					CodeUnit cu = listing.getCodeUnitAt(toAddr);
						
					if (cu != null) {
						
						// Handle instruction reference
						if (cu instanceof Instruction) {
							if (blockRefQueue != null) {
								destBlock = model.getFirstCodeBlockContaining(toAddr, monitor);
							}				
						}
						
						// Skip indirect defined-data destinations
						else if ((cu instanceof Data) && ((Data)cu).isDefined()) {
							continue;
						}
					}
				}
				else if (toAddr.isExternalAddress()) {
					if (!includeExternals) {
						continue;
					}
					if (blockRefQueue != null) {
						destBlock = model.getFirstCodeBlockContaining(toAddr, monitor);
					}	
				}
					
				// Queue block reference
				if (blockRefQueue != null) {
					
					if (destBlock == null) {						
						// means that there will not be a good destination block there,
				        //    make an invalid destination block
				        //  TODO: This might not be the right thing to do.  Return a
				        //        codeBlock that really isn't there, but should be if
				        //        there were valid instructions.  If you got it's start
				        //        address then got the block starting at from the model,
				        //        you would get null, so maybe the model should be changed
				        //        to return a block at this address....

						// Create artificial block at bad destination
						destBlock = model.createSimpleDataBlock(toAddr, toAddr);
					}

					blockRefQueue.add(
						new CodeBlockReferenceImpl(
							srcBlock,
							destBlock,
							indirectFlowType,
							toAddr,
							srcRef.getFromAddress()));
				}
				++cnt;
				
			}  			
    	}
    	return cnt;
    }
Process a data reference for possible indirection.  Update block reference queue 
with indirect block references.
@param blockRefQueue the CodeBlockReference queue, may be null
@param srcBlock referent/source block
@param srcRef possible indirect reference from srcBlock (is not verified)
@param indirectFlowType reference type to assign to indirect references discovered
@param includeExternals externals will be included if true
@param monitor task monitor which allows user to cancel operation.
@return number of references found, 0 if memRef does not correspond to a pointer.
@throws CancelledException if the monitor cancels the operation.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/block/SimpleDestReferenceIterator.java