@Override
    public void run() {
      try {
        long now = System.currentTimeMillis();

        synchronized (monitor) {

          // Send due empty acknowledgements
          Iterator<Map.Entry<Long, Collection<IncomingReliableMessageExchange>>>
              dueAcknowledgements =
                  emptyAcknowledgementSchedule.asMap().headMap(now, true).entrySet().iterator();

          while (dueAcknowledgements.hasNext()) {
            Map.Entry<Long, Collection<IncomingReliableMessageExchange>> part =
                dueAcknowledgements.next();

            for (IncomingReliableMessageExchange messageExchange : part.getValue()) {
              if (!messageExchange.isAcknowledgementSent()) {
                InetSocketAddress remoteEndpoint = messageExchange.getRemoteEndpoint();
                int messageID = messageExchange.getMessageID();

                writeEmptyAcknowledgement(remoteEndpoint, messageID);

                messageExchange.setAcknowledgementSent();
              }
            }

            dueAcknowledgements.remove();
          }

          // Retire open NON messages

        }
      } catch (Exception e) {
        log.error("Error in reliability task for incoming message exchanges!", e);
      }
    }
  private void handleOutgoingCoapResponse(ChannelHandlerContext ctx, MessageEvent me) {

    CoapResponse coapResponse = (CoapResponse) me.getMessage();
    InetSocketAddress remoteEndpoint = (InetSocketAddress) me.getRemoteAddress();

    IncomingMessageExchange messageExchange;
    synchronized (monitor) {
      messageExchange = ongoingMessageExchanges.remove(remoteEndpoint, coapResponse.getMessageID());
    }

    if (messageExchange instanceof IncomingReliableMessageExchange) {

      // if the ongoing message exchange is reliable and the empty ACK was not yet sent make
      // response piggy-
      // backed and suppress scheduled empty ACK
      if (!((IncomingReliableMessageExchange) messageExchange).isAcknowledgementSent()) {
        coapResponse.setMessageType(MessageType.Name.ACK.getNumber());
        ((IncomingReliableMessageExchange) messageExchange).setAcknowledgementSent();
      }
    }

    ctx.sendDownstream(me);
  }