@Override
    public final String readLine() throws IOException {
        if (lineBuffer == null) {
            lineBuffer = new char[LINE_BUFFER_INCREMENT_SIZE];
        }

        char[] buf = lineBuffer;
        int room = buf.length;
        int offset = 0;
        int c;

        loop: while (true) {
            c = read();
            switch (c) {
                case -1:
                case '\n':
                    break loop;

                case '\r':
                    read();
                    break loop;

                default:
                    if (--room < 0) {
                        buf = new char[offset + LINE_BUFFER_INCREMENT_SIZE];
                        room = buf.length - offset - 1;
                        System.arraycopy(lineBuffer, 0, buf, 0, offset);
                        lineBuffer = buf;
                    }
                    buf[offset++] = (char) c;
                    break;
            }
        }
        if ((c == -1) && (offset == 0)) {
            return null;
        }
        return String.copyValueOf(buf, 0, offset);
    }