/**
   * @param timedOut whether the session has been timed out
   * @return True if the session was connected.
   */
  protected boolean removed(boolean timedOut) {
    if (!timedOut) _disconnected.set(true);
    boolean connected = _connected.getAndSet(false);
    boolean handshook = _handshook.getAndSet(false);
    if (connected || handshook) {
      for (ServerChannelImpl channel : _subscribedTo.keySet()) channel.unsubscribe(this);

      for (ServerSessionListener listener : _listeners) {
        if (listener instanceof ServerSession.RemoveListener)
          notifyRemoved((RemoveListener) listener, this, timedOut);
      }
    }
    return connected;
  }
  protected void sweep() {
    waitForInitialized();

    for (ServerSession session : _subscribers) {
      if (!session.isHandshook()) unsubscribe((ServerSessionImpl) session);
    }

    if (isPersistent()) return;

    if (_subscribers.size() > 0) return;

    if (_authorizers.size() > 0) return;

    for (ServerChannelListener listener : _listeners)
      if (!(listener instanceof ServerChannelListener.Weak)) return;

    if (_sweeperPasses.incrementAndGet() < 3) return;

    remove();
  }