/** {@inheritDoc} */
 @Override
 public void sessionClosed(IoSession session) throws Exception {
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   log.debug("Session closed: {} id: {}", session.getId(), sessionId);
   if (log.isTraceEnabled()) {
     log.trace("Session attributes: {}", session.getAttributeKeys());
   }
   if (sessionId != null) {
     RTMPMinaConnection conn =
         (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId);
     if (conn != null) {
       // fire-off closed event
       handler.connectionClosed(conn);
       // clear any session attributes we may have previously set
       // TODO: verify this cleanup code is necessary. The session is over and will be garbage
       // collected surely?
       if (session.containsAttribute(RTMPConnection.RTMP_HANDSHAKE)) {
         session.removeAttribute(RTMPConnection.RTMP_HANDSHAKE);
       }
       if (session.containsAttribute(RTMPConnection.RTMPE_CIPHER_IN)) {
         session.removeAttribute(RTMPConnection.RTMPE_CIPHER_IN);
         session.removeAttribute(RTMPConnection.RTMPE_CIPHER_OUT);
       }
     } else {
       log.warn("Connection was not found for {}", sessionId);
     }
     cleanSession(session, false);
   } else {
     log.debug("Connections session id was null in session, may already be closed");
   }
 }
 /** {@inheritDoc} */
 @Override
 public void sessionOpened(IoSession session) throws Exception {
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   log.debug("Session opened: {} id: {}", session.getId(), sessionId);
   RTMPConnManager connManager = (RTMPConnManager) RTMPConnManager.getInstance();
   session.setAttribute(
       RTMPConnection.RTMP_CONN_MANAGER,
       new WeakReference<IConnectionManager<RTMPConnection>>(connManager));
   RTMPMinaConnection conn = (RTMPMinaConnection) connManager.getConnectionBySessionId(sessionId);
   handler.connectionOpened(conn);
 }
 /** {@inheritDoc} */
 @Override
 public void messageSent(IoSession session, Object message) throws Exception {
   log.trace("messageSent session: {} message: {}", session, message);
   String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID);
   if (log.isTraceEnabled()) {
     log.trace("Message sent on session: {} id: {}", session.getId(), sessionId);
   }
   if (sessionId != null) {
     RTMPMinaConnection conn =
         (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId(sessionId);
     if (conn != null) {
       final byte state = conn.getStateCode();
       switch (state) {
         case RTMP.STATE_CONNECTED:
           if (message instanceof Packet) {
             handler.messageSent(conn, (Packet) message);
           } else if (log.isDebugEnabled()) {
             log.debug(
                 "Message was not of Packet type; its type: {}",
                 message != null ? message.getClass().getName() : "null");
           }
           break;
         case RTMP.STATE_CONNECT:
         case RTMP.STATE_HANDSHAKE:
           if (log.isTraceEnabled()) {
             log.trace("messageSent: {}", Hex.encodeHexString(((IoBuffer) message).array()));
           }
           break;
         case RTMP.STATE_DISCONNECTING:
         case RTMP.STATE_DISCONNECTED:
         default:
       }
     } else {
       log.warn(
           "Destination connection was null, it is already disposed. Session id: {}", sessionId);
     }
   }
 }