/** Disconnects from the world model. */
  protected void _disconnect() {
    IoSession currentSession = this.session;
    this.session = null;
    this.sentHandshake = null;
    this.receivedHandshake = null;
    this.attributeAliasValues.clear();
    this.originAliasValues.clear();

    if (currentSession != null && !currentSession.isClosing()) {

      log.info(
          "Closing connection to World Model (client) at {} (waiting {}ms).",
          currentSession.getRemoteAddress(),
          Long.valueOf(this.connectionTimeout));
      while (!currentSession.close(false).awaitUninterruptibly(this.connectionTimeout)) {
        log.error("Connection didn't close after {}ms.", Long.valueOf(this.connectionTimeout));
      }
    }

    if (currentSession != null) {
      for (ConnectionListener listener : this.connectionListeners) {
        listener.connectionInterrupted(this);
      }
    }
  }
 /**
  * Close and clean-up the IoSession.
  *
  * @param session
  * @param immediately close without waiting for the write queue to flush
  */
 @SuppressWarnings("deprecation")
 private void cleanSession(final IoSession session, boolean immediately) {
   // clean up
   final String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   if (log.isDebugEnabled()) {
     log.debug("Forcing close on session: {} id: {}", session.getId(), sessionId);
     log.debug("Session closing: {}", session.isClosing());
   }
   // get the write request queue
   final WriteRequestQueue writeQueue = session.getWriteRequestQueue();
   if (writeQueue != null && !writeQueue.isEmpty(session)) {
     log.debug("Clearing write queue");
     try {
       writeQueue.clear(session);
     } catch (Exception ex) {
       // clear seems to cause a write to closed session ex in some cases
       log.warn("Exception clearing write queue for {}", sessionId, ex);
     }
   }
   // force close the session
   final CloseFuture future = immediately ? session.close(false) : session.close(true);
   IoFutureListener<CloseFuture> listener =
       new IoFutureListener<CloseFuture>() {
         @SuppressWarnings({"unchecked", "rawtypes"})
         public void operationComplete(CloseFuture future) {
           // now connection should be closed
           log.debug("Close operation completed {}: {}", sessionId, future.isClosed());
           future.removeListener(this);
           for (Object key : session.getAttributeKeys()) {
             Object obj = session.getAttribute(key);
             log.debug("{}: {}", key, obj);
             if (obj != null) {
               if (log.isTraceEnabled()) {
                 log.trace("Attribute: {}", obj.getClass().getName());
               }
               if (obj instanceof IoProcessor) {
                 log.debug("Flushing session in processor");
                 ((IoProcessor) obj).flush(session);
                 log.debug("Removing session from processor");
                 ((IoProcessor) obj).remove(session);
               } else if (obj instanceof IoBuffer) {
                 log.debug("Clearing session buffer");
                 ((IoBuffer) obj).clear();
                 ((IoBuffer) obj).free();
               }
             }
           }
         }
       };
   future.addListener(listener);
 }