protected List<PlcReadRequest> processCoilRequests(TreeSet<ModbusTag> tags, PlcReader reader, ModbusContext modbusContext) {
        List<PlcReadRequest> subRequests = new ArrayList<>();
        int firstCoil = -1;
        int lastCoil = -1;
        int maxCoilCurRequest = -1;
        for (ModbusTag tag : tags) {
            int sizeInCoils = tag.getDataType().getDataTypeSize() * 8;
            if (tag.getDataType() == ModbusDataType.BOOL) {
                sizeInCoils = 1;
            }
            // Initialize for the first item.
            if (firstCoil == -1) {
                firstCoil = tag.getAddress();
                lastCoil = tag.getAddress() + (sizeInCoils * tag.getNumberOfElements());
                // 2000 coils/request is the modbus limit.
                maxCoilCurRequest = tag.getAddress() + modbusContext.getMaxCoilsPerRequest();
            }

            // If adding the current coil would exceed the maximum number of coils that can be read by one request,
            // finish this one and start a new one.
            if (tag.getAddress() + (sizeInCoils * tag.getNumberOfElements()) > maxCoilCurRequest) {
                // Finish the current sub-request
                LinkedHashMap<String, PlcTagItem<PlcTag>> subTags = new LinkedHashMap<>();
                subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem<>(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())));
                subRequests.add(new DefaultPlcReadRequest(reader, subTags));

                // Re-initialize the structures for the next request.
                firstCoil = tag.getAddress();
                lastCoil = tag.getAddress() + (sizeInCoils * tag.getNumberOfElements());
                maxCoilCurRequest = tag.getAddress() + modbusContext.getMaxCoilsPerRequest();
            }
            // Otherwise update the end-marker for the current block.
            else {
                lastCoil = tag.getAddress() + tag.getNumberOfElements();
            }
        }

        // Finish the last sub-request
        LinkedHashMap<String, PlcTagItem<PlcTag>> subTags = new LinkedHashMap<>();
        subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem<>(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())));
        subRequests.add(new DefaultPlcReadRequest(reader, subTags));
        return subRequests;
    }
When reading large chunks of data, here we need to read the parts that were originally requested.

@param readRequest original read request
@param readResponses map of the sub-requests that were executed
@return post processed response reflecting the unmodified user request items
plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java