class WriteListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(WriteListener.class);
    protected final NettyResponseFuture<?> future;
    final ProgressAsyncHandler<?> progressAsyncHandler;
    final boolean notifyHeaders;

    WriteListener(NettyResponseFuture<?> future, boolean notifyHeaders) {
        this.future = future;
        progressAsyncHandler = future.getAsyncHandler() instanceof ProgressAsyncHandler ? (ProgressAsyncHandler<?>) future.getAsyncHandler() : null;
        this.notifyHeaders = notifyHeaders;
    }

    private void abortOnThrowable(Channel channel, Throwable cause) {
        if (future.getChannelState() == ChannelState.POOLED && (cause instanceof IllegalStateException ||
                cause instanceof ClosedChannelException ||
                cause instanceof SSLException ||
                StackTraceInspector.recoverOnReadOrWriteException(cause))) {
            LOGGER.debug("Write exception on pooled channel, letting retry trigger", cause);
        } else {
            future.abort(cause);
        }
        Channels.silentlyCloseChannel(channel);
    }

    void operationComplete(Channel channel, Throwable cause) {<FILL_FUNCTION_BODY>}
}

        future.touch();

        // The write operation failed. If the channel was pooled, it means it got asynchronously closed.
        // Let's retry a second time.
        if (cause != null) {
            abortOnThrowable(channel, cause);
            return;
        }

        if (progressAsyncHandler != null) {
            // We need to make sure we aren't in the middle of an authorization process before publishing events as we will re-publish again the same event after the authorization,
            // causing unpredictable behavior.
            boolean startPublishing = !future.isInAuth() && !future.isInProxyAuth();
            if (startPublishing) {

                if (notifyHeaders) {
                    progressAsyncHandler.onHeadersWritten();
                } else {
                    progressAsyncHandler.onContentWritten();
                }
            }
        }
    
<no_super_class>