@Override
  public void update() throws IOException {
    if (isNotReady()) {
      return;
    }

    listener.onUpdateBegin(this);

    boolean sleep = true;

    try {
      Client acceptedClient = null;

      while ((acceptedClient = tryAccept()) != null) {
        if (initializeClient(acceptedClient)) {
          sleep = false;
        }
      }
    } catch (Exception e) {
      listener.onAcceptError(this, e);
    }

    Iterator<Client> iter = clients.iterator();

    while (iter.hasNext()) {
      Client c = iter.next();

      if (!updateClient(c)) {
        iter.remove();
      } else if ((c.getPacketsRead() > 0) || (c.getCallsSent() > 0)) {
        sleep = false;
      }
    }

    listener.onUpdateEnd(this);

    if (sleep && idleSleepMillis > 0) {
      try {
        Thread.sleep(idleSleepMillis);
      } catch (Exception e) {
        // ignore
      }
    }
  }