class RCSHistoryParser {

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

    private static File readCVSRoot(File root, File cvsDir, String name) throws IOException {
        String cvsroot = readFirstLine(root);

        if (cvsroot == null) {
            return null;
        }
        if (cvsroot.charAt(0) != '/') {
            return null;
        }

        File repository = new File(cvsDir, "Repository");
        String repo = readFirstLine(repository);
        String dir = cvsroot + File.separatorChar + repo;
        String filename = name + ",v";
        File rcsFile = new File(dir, filename);
        if (!rcsFile.exists()) {
            File atticFile = new File(dir + File.separatorChar + "Attic", filename);
            if (atticFile.exists()) {
                rcsFile = atticFile;
            }
        }
        return rcsFile;
    }

    History parse(File file, Repository repos) throws HistoryException {
        try {
            return parseFile(file);
        } catch (IOException ioe) {
            throw new HistoryException(ioe);
        }
    }

    private History parseFile(File file) throws IOException {<FILL_FUNCTION_BODY>}

    private void traverse(Node n, List<HistoryEntry> history) {
        if (n == null) {
            return;
        }
        traverse(n.getChild(), history);
        TreeMap<?, ?> brt = n.getBranches();
        if (brt != null) {
            for (Object o : brt.values()) {
                Node b = (Node) o;
                traverse(b, history);
            }
        }
        if (!n.isGhost()) {
            HistoryEntry entry = new HistoryEntry();
            entry.setRevision(n.getVersion().toString());
            entry.setDate(n.getDate());
            entry.setAuthor(n.getAuthor());
            entry.setMessage(n.getLog());
            entry.setActive(true);
            history.add(entry);
        }
    }

    protected static File getRCSFile(File file) {
        return getRCSFile(file.getParent(), file.getName());
    }

    protected static File getRCSFile(String parent, String name) {
        File rcsDir = new File(parent, "RCS");
        File rcsFile = new File(rcsDir, name + ",v");
        if (rcsFile.exists()) {
            return rcsFile;
        }
        // not RCS, try CVS instead
        return getCVSFile(parent, name);
    }

    protected static File getCVSFile(String parent, String name) {
        try {
            File CVSdir = new File(parent, "CVS");
            if (CVSdir.isDirectory() && CVSdir.canRead()) {
                File root = new File(CVSdir, "Root");
                if (root.canRead()) {
                    return readCVSRoot(root, CVSdir, name);
                }
            }
        } catch (Exception e) {
            LOGGER.log(Level.WARNING, e, () ->
                    "Failed to retrieve CVS file of parent: " + parent + ", name: " + name);
        }
        return null;
    }

    /**
     * Read the first line of a file.
     * @param file the file from which to read
     * @return the first line of the file, or {@code null} if the file is empty
     * @throws IOException if an I/O error occurs while reading the file
     */
    private static String readFirstLine(File file) throws IOException {
        try (BufferedReader in = new BufferedReader(new FileReader(file))) {
            return in.readLine();
        }
    }
}

        File rcsfile = getRCSFile(file);
        if (rcsfile == null) {
            return null;
        }

        try {
            Archive archive = new Archive(rcsfile.getPath());
            Version ver = archive.getRevisionVersion();
            Node n = archive.findNode(ver);
            n = n.root();

            ArrayList<HistoryEntry> entries = new ArrayList<>();
            traverse(n, entries);

            History history = new History();
            history.setHistoryEntries(entries);
            return history;
        } catch (ParseException pe) {
            throw RCSRepository.wrapInIOException(
                    "Could not parse file " + file.getPath(), pe);
        }
    
<no_super_class>