docs: protected final boolean readLine() throws IOException {
  		if (this.stream == null || this.overLimit) {
  			return false;
  		}
  
  		int countInWrapBuffer = 0;
  
  		// position of matching positions in the delimiter byte array
  		int delimPos = 0;
  
  		while (true) {
  			if (this.readPos >= this.limit) {
  				// readBuffer is completely consumed. Fill it again but keep partially read delimiter bytes.
  				if (!fillBuffer(delimPos)) {
  					int countInReadBuffer = delimPos;
  					if (countInWrapBuffer + countInReadBuffer > 0) {
  						// we have bytes left to emit
  						if (countInReadBuffer > 0) {
  							// we have bytes left in the readBuffer. Move them into the wrapBuffer
  							if (this.wrapBuffer.length - countInWrapBuffer < countInReadBuffer) {
  								// reallocate
  								byte[] tmp = new byte[countInWrapBuffer + countInReadBuffer];
  								System.arraycopy(this.wrapBuffer, 0, tmp, 0, countInWrapBuffer);
  								this.wrapBuffer = tmp;
  							}
  
  							// copy readBuffer bytes to wrapBuffer
  							System.arraycopy(this.readBuffer, 0, this.wrapBuffer, countInWrapBuffer, countInReadBuffer);
  							countInWrapBuffer += countInReadBuffer;
  						}
  
  						this.offset += countInWrapBuffer;
  						setResult(this.wrapBuffer, 0, countInWrapBuffer);
  						return true;
  					} else {
  						return false;
  					}
  				}
  			}
  
  			int startPos = this.readPos - delimPos;
  			int count;
  
  			// Search for next occurrence of delimiter in read buffer.
  			while (this.readPos < this.limit && delimPos < this.delimiter.length) {
  				if ((this.readBuffer[this.readPos]) == this.delimiter[delimPos]) {
  					// Found the expected delimiter character. Continue looking for the next character of delimiter.
  					delimPos++;
  				} else {
  					// Delimiter does not match.
  					// We have to reset the read position to the character after the first matching character
  					//   and search for the whole delimiter again.
  					readPos -= delimPos;
  					delimPos = 0;
  				}
  				readPos++;
  			}
  
  			// check why we dropped out
  			if (delimPos == this.delimiter.length) {
  				// we found a delimiter
  				int readBufferBytesRead = this.readPos - startPos;
  				this.offset += countInWrapBuffer + readBufferBytesRead;
  				count = readBufferBytesRead - this.delimiter.length;
  
  				// copy to byte array
  				if (countInWrapBuffer > 0) {
  					// check wrap buffer size
  					if (this.wrapBuffer.length < countInWrapBuffer + count) {
  						final byte[] nb = new byte[countInWrapBuffer + count];
  						System.arraycopy(this.wrapBuffer, 0, nb, 0, countInWrapBuffer);
  						this.wrapBuffer = nb;
  					}
  					if (count >= 0) {
  						System.arraycopy(this.readBuffer, 0, this.wrapBuffer, countInWrapBuffer, count);
  					}
  					setResult(this.wrapBuffer, 0, countInWrapBuffer + count);
  					return true;
  				} else {
  					setResult(this.readBuffer, startPos, count);
  					return true;
  				}
  			} else {
  				// we reached the end of the readBuffer
  				count = this.limit - startPos;
  				
  				// check against the maximum record length
  				if (((long) countInWrapBuffer) + count > this.lineLengthLimit) {
  					throw new IOException("The record length exceeded the maximum record length (" + 
  							this.lineLengthLimit + ").");
  				}
  
  				// Compute number of bytes to move to wrapBuffer
  				// Chars of partially read delimiter must remain in the readBuffer. We might need to go back.
  				int bytesToMove = count - delimPos;
  				// ensure wrapBuffer is large enough
  				if (this.wrapBuffer.length - countInWrapBuffer < bytesToMove) {
  					// reallocate
  					byte[] tmp = new byte[Math.max(this.wrapBuffer.length * 2, countInWrapBuffer + bytesToMove)];
  					System.arraycopy(this.wrapBuffer, 0, tmp, 0, countInWrapBuffer);
  					this.wrapBuffer = tmp;
  				}
  
  				// copy readBuffer to wrapBuffer (except delimiter chars)
  				System.arraycopy(this.readBuffer, startPos, this.wrapBuffer, countInWrapBuffer, bytesToMove);
  				countInWrapBuffer += bytesToMove;
  				// move delimiter chars to the beginning of the readBuffer
  				System.arraycopy(this.readBuffer, this.readPos - delimPos, this.readBuffer, 0, delimPos);
  
  			}
  		}
  	}