private void callAfterRemove(final DefaultChannelHandlerContext ctx, boolean forward) {
    final ChannelHandler handler = ctx.handler();

    // Notify the complete removal.
    try {
      handler.afterRemove(ctx);
    } catch (Throwable t) {
      throw new ChannelPipelineException(
          ctx.handler().getClass().getName() + ".afterRemove() has thrown an exception.", t);
    }

    if (forward) {
      ctx.forwardBufferContent();
    } else {
      ctx.clearBuffer();
    }

    ctx.removed = true;

    // Free all buffers before completing removal.
    if (!channel.isRegistered()) {
      ctx.freeHandlerBuffersAfterRemoval();
    }
  }