protected void onReadAction()
    {
        int read;
        boolean closed;
        boolean readMore = true;
        int readBufferSize = getReadBufferSize();
        ByteBuffer buffer = getByteBuffers().acquire(readBufferSize, false);
        try
        {
            // The buffer can be smaller than the data available,
            // therefore we read until we cannot read anymore.
            while (true)
            {
                int start = buffer.position();
                closed = getChannel().read(buffer);
                read = buffer.position() - start;

                if (read > 0)
                {
                    if (logger.isDebugEnabled())
                        logger.debug("Channel {} read {} bytes into {}", new Object[]{getChannel(), read, buffer});
                    buffer.flip();
                    readMore = onRead(buffer);
                    buffer.clear();
                    buffer.limit(readBufferSize);
                }

                if (!readMore || read == 0 || closed)
                    break;
            }
        }
        finally
        {
            getByteBuffers().release(buffer);
        }

        if (closed)
        {
            if (logger.isDebugEnabled())
                logger.debug("Channel {} closed remotely", getChannel());
            onRemoteClose();
        }
        else
        {
            needsRead(readMore);
        }
    }