class BitKeeperHistoryParser implements Executor.StreamHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(BitKeeperHistoryParser.class);

    /**
     * Parses dates.
     */
    private final SimpleDateFormat dateFormat;
    /**
     * Store entries processed from executor output.
     */
    private final List<HistoryEntry> entries = new ArrayList<>();
    /**
     * Store renamed files processed from executor output.
     */
    private final Set<String> renamedFiles = new TreeSet<>();

    /**
     * Constructor to construct the thing to be constructed.
     *
     * @param datePattern a simple date format string
     */
    BitKeeperHistoryParser(String datePattern) {
        dateFormat = new SimpleDateFormat(datePattern);
    }

    /**
     * Returns the history that has been created.
     *
     * @return history a history object
     */
    History getHistory() {
        return new History(entries, new ArrayList<>(renamedFiles));
    }

    /**
     * Process the output of a `bk log` command.
     *
     * Each input line should be in the following format:
     * either
     *   D FILE\tREVISION\tDATE\tUSER(\tRENAMED_FROM)?
     * or
     *   C COMMIT_MESSAGE_LINE
     *
     * BitKeeper always outputs the file name relative to its root directory, which is nice for us since that's what
     * History expects.
     *
     * @param input the executor input stream
     * @throws IOException if the stream reader throws an IOException
     */
    @Override
    public void processStream(InputStream input) throws IOException {<FILL_FUNCTION_BODY>}
}

        HistoryEntry entry = null;

        final BufferedReader in = new BufferedReader(new InputStreamReader(input));
        for (String line = in.readLine(); line != null; line = in.readLine()) {
            if (line.startsWith("D ")) {
                entry = null;
                try {
                    final String[] fields = line.substring(2).split("\t");
                    final HistoryEntry newEntry = new HistoryEntry();
                    if (fields[0].equals("ChangeSet")) {
                        continue;
                    }
                    newEntry.addFile(fields[0].intern());
                    newEntry.setRevision(fields[1]);
                    newEntry.setDate(dateFormat.parse(fields[2]));
                    newEntry.setAuthor(fields[3]);
                    newEntry.setActive(true);
                    entry = newEntry;
                    entries.add(entry);
                    if (fields.length == 5) {
                        renamedFiles.add(fields[4]);
                    }
                } catch (final Exception e) {
                    LOGGER.log(Level.SEVERE, "Error: malformed BitKeeper log output {0}", line);
                }
            } else if (line.startsWith("C ") && (entry != null)) {
                final String messageLine = line.substring(2);
                entry.appendMessage(messageLine);
            }
        }

    
<no_super_class>