public StreamEncryptionInfo(RecordInputStream rs, List<Record> outputRecs) {
      Record rec;
      rs.nextRecord();
      int recSize = 4 + rs.remaining();
      rec = RecordFactory.createSingleRecord(rs);
      outputRecs.add(rec);
      FilePassRecord fpr = null;
      if (rec instanceof BOFRecord) {
        _hasBOFRecord = true;

        // Fetch the next record, and see if it indicates whether
        //  the document is encrypted or not
        if (rs.hasNextRecord()) {
          rs.nextRecord();
          rec = RecordFactory.createSingleRecord(rs);
          recSize += rec.getRecordSize();
          outputRecs.add(rec);

          // Encrypted is normally BOF then FILEPASS
          // May sometimes be BOF, WRITEPROTECT, FILEPASS
          if (rec instanceof WriteProtectRecord && rs.hasNextRecord()) {
            rs.nextRecord();
            rec = RecordFactory.createSingleRecord(rs);
            recSize += rec.getRecordSize();
            outputRecs.add(rec);
          }

          // If it's a FILEPASS, track it specifically but
          //  don't include it in the main stream
          if (rec instanceof FilePassRecord) {
            fpr = (FilePassRecord) rec;
            outputRecs.remove(outputRecs.size() - 1);
            // TODO - add fpr not added to outputRecs
            rec = outputRecs.get(0);
          } else {
            // workbook not encrypted (typical case)
            if (rec instanceof EOFRecord) {
              // A workbook stream is never empty, so crash instead
              // of trying to keep track of nesting level
              throw new IllegalStateException("Nothing between BOF and EOF");
            }
          }
        }
      } else {
        // Invalid in a normal workbook stream.
        // However, some test cases work on sub-sections of
        // the workbook stream that do not begin with BOF
        _hasBOFRecord = false;
      }
      _initialRecordsSize = recSize;
      _filePassRec = fpr;
      _lastRecord = rec;
    }
  /**
   * @return the next available record, or <code>null</code> if this pass didn't return a record
   *     that's suitable for returning (eg was a continue record).
   */
  private Record readNextRecord() {

    Record record = RecordFactory.createSingleRecord(_recStream);
    _lastRecordWasEOFLevelZero = false;

    if (record instanceof BOFRecord) {
      _bofDepth++;
      return record;
    }

    if (record instanceof EOFRecord) {
      _bofDepth--;
      if (_bofDepth < 1) {
        _lastRecordWasEOFLevelZero = true;
      }

      return record;
    }

    if (record instanceof DBCellRecord) {
      // Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
      return null;
    }

    if (record instanceof RKRecord) {
      return RecordFactory.convertToNumberRecord((RKRecord) record);
    }

    if (record instanceof MulRKRecord) {
      Record[] records = RecordFactory.convertRKRecords((MulRKRecord) record);

      _unreadRecordBuffer = records;
      _unreadRecordIndex = 1;
      return records[0];
    }

    if (record.getSid() == DrawingGroupRecord.sid && _lastRecord instanceof DrawingGroupRecord) {
      DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) _lastRecord;
      lastDGRecord.join((AbstractEscherHolderRecord) record);
      return null;
    }
    if (record.getSid() == ContinueRecord.sid) {
      ContinueRecord contRec = (ContinueRecord) record;

      if (_lastRecord instanceof ObjRecord || _lastRecord instanceof TextObjectRecord) {
        // Drawing records have a very strange continue behaviour.
        // There can actually be OBJ records mixed between the continues.
        _lastDrawingRecord.processContinueRecord(contRec.getData());
        // we must remember the position of the continue record.
        // in the serialization procedure the original structure of records must be preserved
        if (_shouldIncludeContinueRecords) {
          return record;
        }
        return null;
      }
      if (_lastRecord instanceof DrawingGroupRecord) {
        ((DrawingGroupRecord) _lastRecord).processContinueRecord(contRec.getData());
        return null;
      }
      if (_lastRecord instanceof DrawingRecord) {
        //				((DrawingRecord) _lastRecord).appendContinueRecord(contRec.getData());
        return contRec;
      }
      if (_lastRecord instanceof UnknownRecord) {
        // Gracefully handle records that we don't know about,
        // that happen to be continued
        return record;
      }
      if (_lastRecord instanceof EOFRecord) {
        // This is really odd, but excel still sometimes
        //  outputs a file like this all the same
        return record;
      }
      throw new RecordFormatException(
          "Unhandled Continue Record followining " + _lastRecord.getClass());
    }
    _lastRecord = record;
    if (record instanceof DrawingRecord) {
      _lastDrawingRecord = (DrawingRecord) record;
    }
    return record;
  }