public static void processFiles(File source, File dest) throws Exception {
    write(
        "Mutating "
            + FileSystemManager.getAbsolutePath(source)
            + " to "
            + FileSystemManager.getAbsolutePath(dest));
    if (!FileSystemManager.exists(source)) {
      write("   ERROR : " + FileSystemManager.getAbsolutePath(source) + " does not exist.");
      return;
    }

    FileTool.getInstance().createDir(FileSystemManager.getParentFile(dest));
    long length = FileSystemManager.length(source);
    byte[] buff = new byte[1024];
    double proba = 4.0 / length * buff.length;

    InputStream in = null;
    OutputStream out = null;
    boolean eq = true;
    try {
      in = FileSystemManager.getFileInputStream(source);
      out = FileSystemManager.getFileOutputStream(dest);

      int l;
      long position = 0;
      while ((l = in.read(buff)) != -1) {
        out.write(mutate(buff, l, proba, position++));
      }
    } finally {
      in.close();
      out.close();
    }
    if (eq) {
      write("   Mutation completed.");
    }
  }
  public static void main(String[] args) {
    try {
      if (args.length < 2) {
        log(
            "Usage : filediff <source file or directory> <destination file or directory> [output file]");
        return;
      }

      String outFile = System.getProperty("user.home") + "/mutation.out";
      if (args.length >= 3) {
        outFile = args[2];
      }
      int index = 0;
      File out = new File(outFile + index);
      while (FileSystemManager.exists(out)) {
        index++;
        out = new File(outFile + index);
      }
      ostream = FileSystemManager.getFileOutputStream(out);

      File source = new File(args[0]);
      File dest = new File(args[1]);
      GregorianCalendar cal = new GregorianCalendar();
      log(
          ""
              + cal.get(Calendar.DAY_OF_MONTH)
              + " "
              + cal.get(Calendar.HOUR_OF_DAY)
              + ":"
              + cal.get(Calendar.MINUTE)
              + ":"
              + cal.get(Calendar.SECOND)
              + ":"
              + cal.get(Calendar.MILLISECOND));
      log("Source : " + FileSystemManager.getAbsolutePath(source));
      log("Destination : " + FileSystemManager.getAbsolutePath(dest));
      log("Output file : " + FileSystemManager.getAbsolutePath(out));

      FileSystemIterator iter = new FileSystemIterator(source, false, true, true, true);
      while (iter.hasNext()) {
        File f1 = (File) iter.next();
        if (FileSystemManager.isFile(f1)) {
          String relativePath = FileSystemManager.getAbsolutePath(f1).substring(args[0].length());
          File f2 = new File(args[1], relativePath);
          processFiles(f1, f2);
        }
      }
      GregorianCalendar cal2 = new GregorianCalendar();
      log(
          ""
              + cal2.get(Calendar.DAY_OF_MONTH)
              + " "
              + cal2.get(Calendar.HOUR_OF_DAY)
              + ":"
              + cal2.get(Calendar.MINUTE)
              + ":"
              + cal2.get(Calendar.SECOND)
              + ":"
              + cal2.get(Calendar.MILLISECOND));
      log("Mutation completed.");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (ostream != null) {
        try {
          ostream.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }