@Override
    public char[] getBuffer() {
        if (lastOverflowSize == overflowSize && buffer != null) {
            return buffer;
        }

        if (buffer == null) {
            if (reader == null) {
                throw new SourceAccessException("Reader is not specified, source: " + sourceName);
            }

            // read buffer and close it
            final char[] tmpBuffer = new char[length + overflowSize];

            try {
                final int charsRead;
                if (length == 0) {
                    // don't attempt to read from the buffer, since certain implementation may throw an error here.
                    charsRead = 0;
                } else {
                    charsRead = reader.read(tmpBuffer);
                }

                if (charsRead != length) {
                    throw new SourceAccessException("Expected to read " + length + " chars from the given source " +
                            sourceName + ", but read only " + charsRead);
                }

                // OK, close reader and remove reference to it.
                reader.close();
                reader = null;
            } catch (IOException e) {
                throw new SourceAccessException(e);
            }

            // update state
            buffer = tmpBuffer;
            lastOverflowSize = overflowSize;
        }

        // expand buffer to meet overflow size bounds
        if (overflowSize > lastOverflowSize) {
            final char[] tmpBuffer = new char[length + overflowSize];
            System.arraycopy(this.buffer, 0, tmpBuffer, 0, length);
            this.buffer = tmpBuffer;
            this.lastOverflowSize = overflowSize;
        }

        return buffer;
    }