@Override
	public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
			throws CancelledException {
		Listing listing = program.getListing();
		String filler = "0x" + fillerValue;

		if (fillerValue.equalsIgnoreCase(DEFAULT_FILL_VALUE)) {
			String fillerBytes = determineFillerValue(listing);
			if (fillerBytes == null) {
				return false;
			}

			filler = "0x" + fillerBytes;
		}

		// Create array of minBytes length initialized to fillerByte    	    	    	
		byte[] testBytes = new byte[minBytes];
		byte fillerByte = Integer.decode(filler).byteValue();
		Arrays.fill(testBytes, fillerByte);

		byte[] programBytes = new byte[minBytes];

		FunctionIterator iterator = listing.getFunctions(true);
		while (iterator.hasNext() && !monitor.isCancelled()) {

			// Get undefined byte immediately following function
			Function functioin = iterator.next();
			Address fillerAddress = functioin.getBody().getMaxAddress().next();
			Data undefined = listing.getUndefinedDataAt(fillerAddress);
			if (undefined == null) {
				// No undefined filler bytes found, keep going to next function
				continue;
			}

			String undefinedRepresentation = undefined.getDefaultValueRepresentation();

			if (!getBytes(program.getMemory(), fillerAddress, programBytes)) {
				continue;
			}

			if (!Arrays.equals(programBytes, testBytes)) {
				// the bytes we found do not match the chosen filler type--ignore
				continue;
			}

			// Determine actual length of filler bytes
			int fillerLength = countUndefineds(program, fillerAddress, undefinedRepresentation);

			replaceFillerBytes(listing, fillerAddress, fillerLength);
		}

		return true;
	}
This function tries to determine the fill value used by the current program.
The byte value occurring most is the winner.

@return filler value
@throws Exception
Ghidra/Features/Base/src/main/java/ghidra/app/analyzers/CondenseFillerBytesAnalyzer.java