/**
   * Run OfflineEditsViewer
   *
   * @param inFilename input edits filename
   * @param outFilename oputput edits filename
   */
  private int runOev(String inFilename, String outFilename, String processor, boolean recovery)
      throws IOException {

    LOG.info("Running oev [" + inFilename + "] [" + outFilename + "]");

    OfflineEditsViewer oev = new OfflineEditsViewer();
    Flags flags = new Flags();
    flags.setPrintToScreen();
    if (recovery) {
      flags.setRecoveryMode();
    }
    return oev.go(inFilename, outFilename, processor, flags, null);
  }
  /**
   * Checks that the edits file has all opCodes
   *
   * @param filename edits file
   * @return true is edits (filename) has all opCodes
   */
  private boolean hasAllOpCodes(String inFilename) throws IOException {
    String outFilename = inFilename + ".stats";
    FileOutputStream fout = new FileOutputStream(outFilename);
    StatisticsEditsVisitor visitor = new StatisticsEditsVisitor(fout);
    OfflineEditsViewer oev = new OfflineEditsViewer();
    if (oev.go(inFilename, outFilename, "stats", new Flags(), visitor) != 0) return false;
    LOG.info("Statistics for " + inFilename + "\n" + visitor.getStatisticsString());

    boolean hasAllOpCodes = true;
    for (FSEditLogOpCodes opCode : FSEditLogOpCodes.values()) {
      // don't need to test obsolete opCodes
      if (obsoleteOpCodes.containsKey(opCode)) {
        continue;
      }
      if (opCode == FSEditLogOpCodes.OP_INVALID) continue;
      Long count = visitor.getStatistics().get(opCode);
      if ((count == null) || (count == 0)) {
        hasAllOpCodes = false;
        LOG.info("Opcode " + opCode + " not tested in " + inFilename);
      }
    }
    return hasAllOpCodes;
  }