private void registerHandler(HandlerRegistration handler) {
        AtomicReference<HandlerRegistration> deferred = new AtomicReference<>();
        CompletionCallback completionCallback = this.timeoutManager.register(new TimedOperation() {
            @Override
            public Consumer<TimeoutException> getOnTimeoutConsumer() {
                return onTimeout(deferred, handler.getOnTimeoutConsumer());
            }

            @Override
            public Duration getTimeout() {
                return handler.getTimeout();
            }
        });
        // wrap handler, so we can catch packet consumer call and inform completion callback.
        HandlerRegistration registration = new HandlerRegistration(
            handler.getName(),
            handler.getCommands(),
            handler.getExpectClazz(),
            completionCallback.andThen(handler.getPacketConsumer()),
            handler.getOnTimeoutConsumer(),
            handler.getErrorConsumer(),
            handler::confirmHandled,
            handler::confirmError,
            handler::cancel,
            handler.getTimeout()
        );
        deferred.set(registration);
        registeredHandlers.add(registration);
    }
Performs registration of packet handler and makes sure that its timeout will be handled properly.
Since timeouts are controlled by {@link TimeoutManager} there is a need to decorate handler
operations so both sides know what's going on.

@param handler Handler to be registered.
plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java