@Override
    protected List<PlcReadRequest> processReadRequest(PlcReadRequest readRequest, DriverContext driverContext) {
        ModbusContext modbusContext = (ModbusContext) driverContext;

        // Sort the different types of tags as all need to be requested separately anyway.
        TreeSet<ModbusTag> coils = null;
        TreeSet<ModbusTag> holdingRegisters = null;
        TreeSet<ModbusTag> inputRegisters = null;
        TreeSet<ModbusTag> extendedRegisters = null;
        TreeSet<ModbusTag> discreteInputs = null;
        for (PlcTag tag : readRequest.getTags()) {
            if (tag instanceof ModbusTagCoil) {
                if (coils == null) {
                    coils = new TreeSet<>(Comparator.comparingInt(ModbusTag::getAddress));
                }
                coils.add(((ModbusTagCoil) tag));
            } else if (tag instanceof ModbusTagHoldingRegister) {
                if (holdingRegisters == null) {
                    holdingRegisters = new TreeSet<>(Comparator.comparingInt(ModbusTag::getAddress));
                }
                holdingRegisters.add(((ModbusTagHoldingRegister) tag));
            } else if (tag instanceof ModbusTagInputRegister) {
                if (inputRegisters == null) {
                    inputRegisters = new TreeSet<>(Comparator.comparingInt(ModbusTag::getAddress));
                }
                inputRegisters.add(((ModbusTagInputRegister) tag));
            } else if (tag instanceof ModbusTagExtendedRegister) {
                if (extendedRegisters == null) {
                    extendedRegisters = new TreeSet<>(Comparator.comparingInt(ModbusTag::getAddress));
                }
                extendedRegisters.add(((ModbusTagExtendedRegister) tag));
            } else if (tag instanceof ModbusTagDiscreteInput) {
                if (discreteInputs == null) {
                    discreteInputs = new TreeSet<>(Comparator.comparingInt(ModbusTag::getAddress));
                }
                discreteInputs.add(((ModbusTagDiscreteInput) tag));
            }
        }

        // Add sub requests for every type of tag in this request.
        PlcReader reader = ((DefaultPlcReadRequest) readRequest).getReader();
        List<PlcReadRequest> subRequests = new ArrayList<>();
        if (coils != null) {
            subRequests.addAll(processCoilRequests(coils, reader, modbusContext));
        }
        if (holdingRegisters != null) {
            subRequests.addAll(processRegisterRequests(holdingRegisters, reader, (address, count, dataType) -> new ModbusTagHoldingRegister(address, count, dataType, Collections.emptyMap()), modbusContext));
        }
        if (inputRegisters != null) {
            subRequests.addAll(processRegisterRequests(inputRegisters, reader, (address, count, dataType) -> new ModbusTagInputRegister(address, count, dataType, Collections.emptyMap()), modbusContext));
        }
        if (extendedRegisters != null) {
            subRequests.addAll(processRegisterRequests(extendedRegisters, reader, (address, count, dataType) -> new ModbusTagExtendedRegister(address, count, dataType, Collections.emptyMap()), modbusContext));
        }
        if (discreteInputs != null) {
            subRequests.addAll(processRegisterRequests(discreteInputs, reader, (address, count, dataType) -> new ModbusTagDiscreteInput(address, count, dataType, Collections.emptyMap()), modbusContext));
        }
        return subRequests;
    }
Per default the number of registers that can be read are 125 registers.
The number of coils that can be read in one request are 2000 coils.
This optimizer will sort all request items, split them up into coils and registers.
Then it will try to group them together to produce the least amount of traffic
on the wire by requesting larger chunks of words and serving multiple items
with one request. The matching processReadResponses will then handle the splitting
of the results.

@param readRequest   the original read request
@param driverContext the driver context
@return a list of rewritten sub-requests
plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java