class SelectiveRecordReaderEventIterator implements EventIterator {

    @Override
    public Optional<ProvenanceEventRecord> nextEvent() throws IOException {
        if (closed) {
            throw new IOException("EventIterator is already closed");
        }

        final long start = System.nanoTime();
        try {
            while (idIterator.hasNext()) {
                // Determine the next event ID to fetch
                final long eventId = idIterator.next();

                // Determine which file the event should be in.
                final File fileForEvent = getFileForEventId(eventId);
                if (fileForEvent == null) {
                    continue;
                }

                // If we determined which file the event should be in, and that's not the file that
                // we are currently reading from, rotate the reader to the appropriate one.
                if (!fileForEvent.equals(currentFile)) {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (final Exception e) {
                            logger.warn("Failed to close {}; some resources may not be cleaned up appropriately", reader);
                        }
                    }

                    reader = readerFactory.newRecordReader(fileForEvent, Collections.emptyList(), maxAttributeChars);
                    this.currentFile = fileForEvent;
                }

                final Optional<ProvenanceEventRecord> eventOption = reader.skipToEvent(eventId);
                if (eventOption.isPresent() && eventOption.get().getEventId() == eventId) {
                    reader.nextRecord();    // consume the event from the stream.
                    return eventOption;
                }

                continue;
            }

            return Optional.empty();
        } finally {
            final long ms = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
            logger.trace("Took {} ms to read next event", ms);
        }
    }

    public  SelectiveRecordReaderEventIterator(final List<File> filesToRead, final RecordReaderFactory readerFactory, final List<Long> eventIds, final int maxAttributeChars);

}