docs: @Override
      public void writeFile(String arg0, Map result) {
  
          long estTime = 0;
  
          try {
              if (getObjectOr(result, "experiments", new ArrayList()).isEmpty()
                      && getObjectOr(result, "soils", new ArrayList()).isEmpty()
                      && getObjectOr(result, "weathers", new ArrayList()).isEmpty()) {
  
                  // Calculate estimated time consume
                  HashMap wth = getObjectOr(result, "weather", new HashMap());
                  estTime += getObjectOr(wth, "dailyWeather", new ArrayList()).size();
  
                  // Write files
                  recordSWData(result, new DssatSoilOutput());
                  recordSWData(result, new DssatWeatherOutput());
                  writeWthFiles(arg0);
                  writeSoilFiles(arg0);
                  String exname = getValueOr(result, "exname", "N/A");
                  writeSingleExp(arg0, result, new DssatXFileOutput(), exname + "_X");
                  writeSingleExp(arg0, result, new DssatAFileOutput(), exname + "_A");
                  writeSingleExp(arg0, result, new DssatTFileOutput(), exname + "_T");
                  writeSingleExp(arg0, result, new DssatCulFileOutput(), exname + "_Cul");
                  writeSingleExp(arg0, result, new DssatBatchFileOutput(DssatVersion.DSSAT45), "DSSBatch.v45");
                  writeSingleExp(arg0, result, new DssatBatchFileOutput(DssatVersion.DSSAT46), "DSSBatch.v46");
                  writeSingleExp(arg0, result, new DssatRunFileOutput(DssatVersion.DSSAT45), "Run45.bat");
                  writeSingleExp(arg0, result, new DssatRunFileOutput(DssatVersion.DSSAT46), "Run46.bat");
  
                  // compress all output files into one zip file
                  outputFile = new File(revisePath(arg0) + exname + ".ZIP");
  
                  //createZip();
              } else {
                  // Calculate estimated time consume
                  for (HashMap wth : (ArrayList<HashMap>) getObjectOr(result, "weathers", new ArrayList<HashMap>())) {
                      estTime += getObjectOr(wth, "dailyWeather", new ArrayList()).size();
                  }
                  writeMultipleExp(arg0, result);
              }
  
              if (estTime > 0) {
                  estTime *= 10;
              } else {
                  estTime = 10000;
              }
  
              executor.shutdown();
              long timer = System.currentTimeMillis();
              HashSet<String> keys = new HashSet(futFiles.keySet());
              int counter = 0;
              while (!executor.isTerminated()) {
                  if (System.currentTimeMillis() - timer > estTime) {
                      counter++;
                      timer = System.currentTimeMillis();
                      if (keys.isEmpty()) {
                          LOG.info("The executor should be terminated");
                          executor.shutdownNow();
                      } else if (counter > 3) {
                          LOG.info("The executor is going to be force terminated");
                          executor.shutdownNow();
                      }
                      String[] arr = keys.toArray(new String[0]);
                      for (String key : arr) {
                          Future futFile = futFiles.get(key);
                          if (futFile.isCancelled() || futFile.isDone()) {
                              keys.remove(key);
                          } else {
                              LOG.info("DSSAT translation for {} is still under processing...", key);
                          }
                      }
                  }
              }
              executor = null;
              LOG.debug("Consume {} s", (System.currentTimeMillis() - timer) / 1000.0);
  
              // Get output result files into output array
              for (String key : futFiles.keySet()) {
                  try {
                      File f = futFiles.get(key).get();
                      if (f != null) {
                          files.put(f.getPath(), f);
                      }
                  } catch (InterruptedException ex) {
                      LOG.error(getStackTrace(ex));
                  } catch (ExecutionException ex) {
                      if (!ex.getMessage().contains("NoOutputFileException")) {
                          LOG.error(getStackTrace(ex));
                      }
                  }
              }
  
          } catch (FileNotFoundException e) {
              LOG.error(getStackTrace(e));
          } catch (IOException e) {
              LOG.error(getStackTrace(e));
          }
      }