class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSizePolicy, Http2FrameWriter.Configuration {

  @Override
  public ChannelFuture writeFrame(
      final ChannelHandlerContext ctx,
      final byte frameType,
      final int streamId,
      final Http2Flags flags,
      final ByteBuf payload,
      final ChannelPromise promise) {
    final SimpleChannelPromiseAggregator promiseAggregator =
        new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor());
    try {
      verifyStreamOrConnectionId(streamId, STREAM_ID);
      final ByteBuf buf = ctx.alloc().buffer(FRAME_HEADER_LENGTH);
      // Assume nothing below will throw until buf is written. That way we don't have to take care
      // of ownership
      // in the catch block.
      writeFrameHeaderInternal(buf, payload.readableBytes(), frameType, flags, streamId);
      ctx.write(buf, promiseAggregator.newPromise());
    } catch (final Throwable t) {
      try {
        payload.release();
      } finally {
        promiseAggregator.setFailure(t);
        promiseAggregator.doneAllocatingPromises();
      }
      return promiseAggregator;
    }
    try {
      ctx.write(payload, promiseAggregator.newPromise());
    } catch (final Throwable t) {
      promiseAggregator.setFailure(t);
    }
    return promiseAggregator.doneAllocatingPromises();
  }

  public  DefaultHttp2FrameWriter();
  public  DefaultHttp2FrameWriter(
      final Http2HeadersEncoder.SensitivityDetector headersSensitivityDetector);
  public  DefaultHttp2FrameWriter(
      final Http2HeadersEncoder.SensitivityDetector headersSensitivityDetector,
      final boolean ignoreMaxHeaderListSize);
  public  DefaultHttp2FrameWriter(final Http2HeadersEncoder headersEncoder);

}