/**
   * {@inheritDoc} Down-casts the received downstream event into more meaningful sub-type event and
   * calls an appropriate handler method with the down-casted event.
   */
  public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {

    if (e instanceof MessageEvent) {
      writeRequested(ctx, (MessageEvent) e);
    } else if (e instanceof ChannelStateEvent) {
      ChannelStateEvent evt = (ChannelStateEvent) e;
      switch (evt.getState()) {
        case OPEN:
          if (!Boolean.TRUE.equals(evt.getValue())) {
            closeRequested(ctx, evt);
          }
          break;
        case BOUND:
          if (evt.getValue() != null) {
            bindRequested(ctx, evt);
          } else {
            unbindRequested(ctx, evt);
          }
          break;
        case CONNECTED:
          if (evt.getValue() != null) {
            connectRequested(ctx, evt);
          } else {
            disconnectRequested(ctx, evt);
          }
          break;
        case INTEREST_OPS:
          setInterestOpsRequested(ctx, evt);
          break;
        default:
          ctx.sendDownstream(e);
      }
    } else {
      ctx.sendDownstream(e);
    }
  }