class Http2ConnectionHandler extends ByteToMessageDecoder implements Http2LifecycleManager, ChannelOutboundHandler {

  @Override
  public ChannelFuture goAway(
      final ChannelHandlerContext ctx,
      final int lastStreamId,
      final long errorCode,
      final ByteBuf debugData,
      ChannelPromise promise) {
    promise = promise.unvoid();
    final Http2Connection connection = connection();
    try {
      if (!connection.goAwaySent(lastStreamId, errorCode, debugData)) {
        debugData.release();
        promise.trySuccess();
        return promise;
      }
    } catch (final Throwable cause) {
      debugData.release();
      promise.tryFailure(cause);
      return promise;
    }

    // Need to retain before we write the buffer because if we do it after the refCnt could already
    // be 0 and
    // result in an IllegalRefCountException.
    debugData.retain();
    final ChannelFuture future =
        frameWriter().writeGoAway(ctx, lastStreamId, errorCode, debugData, promise);

    if (future.isDone()) {
      processGoAwayWriteResult(ctx, lastStreamId, errorCode, debugData, future);
    } else {
      future.addListener(
          new ChannelFutureListener() {
            @Override
            public void operationComplete(final ChannelFuture future) throws Exception {
              processGoAwayWriteResult(ctx, lastStreamId, errorCode, debugData, future);
            }
          });
    }
    // if closeListener != null this means we have already initiated graceful closure.
    // doGracefulShutdown will apply
    // the gracefulShutdownTimeoutMillis on each invocation, however we only care to apply the
    // timeout on the
    // start of graceful shutdown.
    if (errorCode == Http2Error.NO_ERROR.code() && closeListener == null) {
      doGracefulShutdown(ctx, future, null);
    }

    return future;
  }

  protected  Http2ConnectionHandler(
      final Http2ConnectionDecoder decoder,
      final Http2ConnectionEncoder encoder,
      final Http2Settings initialSettings);
  protected  Http2ConnectionHandler(
      final Http2ConnectionDecoder decoder,
      final Http2ConnectionEncoder encoder,
      final Http2Settings initialSettings,
      final boolean decoupleCloseAndGoAway);

}