final NIOConnection nioConnection = (NIOConnection) connection;
        // create and initialize the write queue record
        final AsyncWriteQueueRecord queueRecord = createRecord(
                nioConnection, message, completionHandler,
                dstAddress, pushBackHandler,
                !message.hasRemaining() || message.isExternal());
        if (nioConnection == null) {
            queueRecord.notifyFailure(new IOException("Connection is null"));
            return;
        }
        if (!nioConnection.isOpen()) {
            onWriteFailure(nioConnection, queueRecord,
                    nioConnection.getCloseReason().getCause());
            return;
        }
        // Get connection async write queue
        final TaskQueue<AsyncWriteQueueRecord> writeTaskQueue =
                nioConnection.getAsyncWriteQueue();
        final boolean isEmptyRecord = queueRecord.isEmptyRecord();
        final int messageSize = message.remaining();
        // For empty buffer reserve 1 byte space
        final int bytesToReserve = isEmptyRecord ?
                 EMPTY_RECORD_SPACE_VALUE : messageSize;
        final int pendingBytes = writeTaskQueue.reserveSpace(bytesToReserve);
        final boolean isCurrent = (pendingBytes == bytesToReserve);
        final boolean isLogFine = LOGGER.isLoggable(Level.FINEST);
        if (isLogFine) {
            doFineLog("AsyncQueueWriter.write connection={0} record={1} directWrite={2}",
                    nioConnection, queueRecord, isCurrent);
        }
        final Reentrant reentrants = Reentrant.getWriteReentrant();
        try {
            if (!reentrants.inc()) {
                // Max number of reentrants is reached
                queueRecord.setMessage(
                        cloneRecordIfNeeded(nioConnection, cloner, message));
                if (isCurrent) { //current but not finished.
                    writeTaskQueue.setCurrentElement(queueRecord);
                    nioConnection.simulateIOEvent(IOEvent.WRITE);
                } else {
                    writeTaskQueue.offer(queueRecord);
                }
                return;
            }
            if (isCurrent && isAllowDirectWrite) {
                // If we can write directly - do it w/o creating queue record (simple)
                final int written = messageSize > 0 ?
                        (int) write0(nioConnection, queueRecord) :
                        0;
                final boolean isFinished = queueRecord.isFinished();
                final int bytesToRelease = !isEmptyRecord ?
                        written :
                        (isFinished ? EMPTY_RECORD_SPACE_VALUE : 0);
                final boolean isQueueEmpty =
                        (writeTaskQueue.releaseSpaceAndNotify(bytesToRelease) == 0);
                if (isFinished) {
                    queueRecord.notifyCompleteAndRecycle();
                    if (!isQueueEmpty) {
                        nioConnection.simulateIOEvent(IOEvent.WRITE);
                    }
                    return;
                }
            }
            queueRecord.setMessage(
                    cloneRecordIfNeeded(nioConnection, cloner, message));
            if (isCurrent) { //current but not finished.
                writeTaskQueue.setCurrentElement(queueRecord);
                onReadyToWrite(nioConnection);