code: void closedHandler(Object context, String input, Object frame, String stateName) {
          if (getReadyState() == ReadyState.CLOSED) {
              return;
          }
          
          // TODO: Determine whether channels need to be cleaned up.
          if (this.channels.size() != 0) {
              for (int i = 1; i <= this.channels.size(); i++) { // 1-based
                  AmqpChannel channel = this.channels.get(i);
                  AmqpFrame   f = new AmqpFrame();
                  
                  // Close each channel which should result in CLOSE event
                  // to be fired for each of the registered ChannelListener(s).
                  f.setMethodName("closeChannel");
                  f.setChannelId((short) i);
                  channel.channelClosedHandler(this, "", f, "closeChannel");
              }
          }
          
          try {
              // Mark the readyState to be CLOSED.
              readyState = ReadyState.CLOSED;
              
              // Fire CLOSE event for the ConnectionListener(s) registered
              // on AmqpClient object.
              fireOnClosed(new ConnectionEvent(this, Kind.CLOSE));
  
              // If the WebSocket(or ByteSocket) is still not closed, then 
              // invoke the close() method. The callback in this case will be a
              // a no-op as we have completed the book-keeping here.
              if (websocket != null) {
                  websocket.close();
              }
          }
          catch (Exception e1) {
              throw new IllegalStateException(e1);
          }
          finally {
              websocket = null;
          }
  
      }
docs: should be the order following in all our client implementations.