@Override
  public void onControlFrame(ControlFrame frame) {
    notifyIdle(idleListener, false);
    try {
      LOG.debug("Processing {}", frame);

      if (goAwaySent.get()) {
        LOG.debug("Skipped processing of {}", frame);
        return;
      }

      switch (frame.getType()) {
        case SYN_STREAM:
          {
            onSyn((SynStreamFrame) frame);
            break;
          }
        case SYN_REPLY:
          {
            onReply((SynReplyFrame) frame);
            break;
          }
        case RST_STREAM:
          {
            onRst((RstStreamFrame) frame);
            break;
          }
        case SETTINGS:
          {
            onSettings((SettingsFrame) frame);
            break;
          }
        case NOOP:
          {
            // Just ignore it
            break;
          }
        case PING:
          {
            onPing((PingFrame) frame);
            break;
          }
        case GO_AWAY:
          {
            onGoAway((GoAwayFrame) frame);
            break;
          }
        case HEADERS:
          {
            onHeaders((HeadersFrame) frame);
            break;
          }
        case WINDOW_UPDATE:
          {
            onWindowUpdate((WindowUpdateFrame) frame);
            break;
          }
        case CREDENTIAL:
          {
            onCredential((CredentialFrame) frame);
            break;
          }
        default:
          {
            throw new IllegalStateException();
          }
      }
    } finally {
      notifyIdle(idleListener, true);
    }
  }