code: public void handleIO() throws IOException {
      if (shutDown) {
        getLogger().debug("No IO while shut down.");
        return;
      }
  
      handleInputQueue();
      getLogger().debug("Done dealing with queue.");
  
      long delay = wakeupDelay;
      if (!reconnectQueue.isEmpty()) {
        long now = System.currentTimeMillis();
        long then = reconnectQueue.firstKey();
        delay = Math.max(then - now, 1);
      }
      getLogger().debug("Selecting with delay of %sms", delay);
      assert selectorsMakeSense() : "Selectors don't make sense.";
      int selected = selector.select(delay);
  
      if (shutDown) {
        return;
      } else if (selected == 0 && addedQueue.isEmpty()) {
        handleWokenUpSelector();
      } else if (selector.selectedKeys().isEmpty()) {
        handleEmptySelects();
      } else {
        getLogger().debug("Selected %d, selected %d keys", selected,
          selector.selectedKeys().size());
        emptySelects = 0;
  
        Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
        while(iterator.hasNext()) {
          SelectionKey sk = iterator.next();
          handleIO(sk);
          iterator.remove();
        }
      }
  
      handleOperationalTasks();
    }
docs: Handle all IO that flows through the connection.
  
  This method is called in an endless loop, listens on NIO selectors and
  dispatches the underlying read/write calls if needed.