private boolean forEachRecord(@NotNull RecordReader reader,
                                long untilOffset) throws IOException {
    int pageSize = storage.pageSize();
    for (long recordOffsetInFile = HeaderLayout.HEADER_SIZE; recordOffsetInFile < untilOffset; ) {

      MMappedFileStorage.Page page = storage.pageByOffset(recordOffsetInFile);
      int recordOffsetInPage = storage.toOffsetInPage(recordOffsetInFile);
      ByteBuffer pageBuffer = page.rawPageBuffer();

      if (pageSize - recordOffsetInPage < RecordLayout.RECORD_HEADER_SIZE) {
        throw new IOException(
          getClass().getSimpleName() + " corrupted: recordOffsetInPage(=" + recordOffsetInPage + ") less than " +
          "RECORD_HEADER(=" + RecordLayout.RECORD_HEADER_SIZE + "b) left until " +
          "pageEnd(" + pageSize + ") -- all records must be 32b-aligned"
        );
      }

      int recordHeader = RecordLayout.readHeader(pageBuffer, recordOffsetInPage);
      if (recordHeader == 0) {
        //the record wasn't even started to be written
        // -> can't read the following records since we don't know there they are
        return true;
      }

      int recordLength = RecordLayout.extractRecordLength(recordHeader);

      if (RecordLayout.isDataHeader(recordHeader)) {
        if (RecordLayout.isRecordCommitted(recordHeader)) {
          int payloadLength = RecordLayout.extractPayloadLength(recordHeader);
          long recordId = recordOffsetToId(recordOffsetInFile);

          if (!RecordLayout.isFitIntoPage(pageBuffer, recordOffsetInPage, payloadLength)) {
            throw new IOException("record[" + recordId + "][@" + recordOffsetInFile + "].payloadLength(=" + payloadLength + "): " +
                                  " is incorrect: page[0.." + pageBuffer.limit() + "]" +
                                  moreDiagnosticInfo(recordOffsetInFile));
          }
          ByteBuffer recordDataSlice = pageBuffer.slice(recordOffsetInPage + RecordLayout.DATA_OFFSET, payloadLength)
            //.asReadOnlyBuffer()
            .order(pageBuffer.order());

          boolean shouldContinue = reader.read(recordId, recordDataSlice);
          if (!shouldContinue) {
            return false;
          }
        }//else: record not yet commited, we can't _read_ it -- but maybe _next_ record(s) are committed?
      }
      else if (RecordLayout.isPaddingHeader(recordHeader)) {
        //TODO RC: enable the check below after VFS version bump (currently it causes all the aologs to become
        //         corrupted, since all them previously missed 'committed' bit in padding records
        //if (!RecordLayout.isRecordCommitted(recordHeader)) {
        //  throw new IOException("padding.header("+recordHeader+") is not committed -- bug?")
        //}

        //just skip it
      }
      else {
        //if header != 0 => it must be either padding, or (uncommitted?) data record:
        throw new IOException("header(=" + recordHeader + "](@offset=" + recordOffsetInFile + "): not a padding, nor a data record" +
                              moreDiagnosticInfo(recordOffsetInFile));
      }


      recordOffsetInFile = nextRecordOffset(recordOffsetInFile, recordLength);
    }

    return true;
  }
private boolean forEachRecord(@NotNull RecordReader reader,
                                long untilOffset)