public boolean read() {
            if (state_ == READING_FRAME_SIZE) {
                // try to read the frame size completely
                if (!internalRead()) {
                    return false;
                }

                // if the frame size has been read completely, then prepare to read the
                // actual frame.
                if (buffer_.remaining() == 0) {
                    // pull out the frame size as an integer.
                    int frameSize = buffer_.getInt(0);
                    if (frameSize <= 0) {
                        LOGGER.error("Read an invalid frame size of " + frameSize
                                + ". Are you using TFramedTransport on the client side?");
                        return false;
                    }

                    // if this frame will always be too large for this server, log the
                    // error and close the connection.
                    if (frameSize > MAX_READ_BUFFER_BYTES) {
                        LOGGER.error("Read a frame size of " + frameSize
                                + ", which is bigger than the maximum allowable buffer size for ALL connections.");
                        return false;
                    }

                    // if this frame will push us over the memory limit, then return.
                    // with luck, more memory will free up the next time around.
                    if (readBufferBytesAllocated + frameSize > MAX_READ_BUFFER_BYTES) {
                        return true;
                    }

                    // incremement the amount of memory allocated to read buffers
                    readBufferBytesAllocated += frameSize;

                    // reallocate the readbuffer as a frame-sized buffer
                    buffer_ = ByteBuffer.allocate(frameSize);

                    state_ = READING_FRAME;
                } else {
                    // this skips the check of READING_FRAME state below, since we can't
                    // possibly go on to that state if there's data left to be read at
                    // this one.
                    return true;
                }
            }

            // it is possible to fall through from the READING_FRAME_SIZE section
            // to READING_FRAME if there's already some frame data available once
            // READING_FRAME_SIZE is complete.

            if (state_ == READING_FRAME) {
                if (!internalRead()) {
                    return false;
                }

                // since we're already in the select loop here for sure, we can just
                // modify our selection key directly.
                if (buffer_.remaining() == 0) {
                    // get rid of the read select interests
                    selectionKey_.interestOps(0);
                    state_ = READ_FRAME_COMPLETE;
                }

                return true;
            }

            // if we fall through to this point, then the state must be invalid.
            LOGGER.error("Read was called but state is invalid (" + state_ + ")");
            return false;
        }