private void saveConfiguration(
      BundleInfo[] configuration, File outputFile, URI installArea, boolean backup)
      throws IOException {
    if (backup && outputFile.exists()) {
      File backupFile = Utils.getSimpleDataFormattedFile(outputFile);
      if (!outputFile.renameTo(backupFile)) {
        throw new IOException("Fail to rename from (" + outputFile + ") to (" + backupFile + ")");
      }
    }

    org.eclipse.equinox.internal.simpleconfigurator.utils.BundleInfo[] simpleInfos =
        convertBundleInfos(configuration, installArea);

    // if empty remove the configuration file
    if (simpleInfos == null || simpleInfos.length == 0) {
      if (outputFile.exists()) {
        outputFile.delete();
      }
      File parentDir = outputFile.getParentFile();
      if (parentDir.exists()) {
        parentDir.delete();
      }
      return;
    }
    SimpleConfiguratorManipulatorUtils.writeConfiguration(simpleInfos, outputFile);
    if (CONFIG_LIST.equals(outputFile.getName())
        && installArea != null
        && isSharedInstallSetup(URIUtil.toFile(installArea), outputFile))
      rememberSharedBundlesInfoTimestamp(installArea, outputFile.getParentFile());
  }
 /**
  * Return the ConfiguratorConfigFile which is determined by the parameters set in Manipulator.
  *
  * @param manipulator
  * @return File
  */
 private static File getConfigFile(Manipulator manipulator) throws IllegalStateException {
   File fwConfigLoc = manipulator.getLauncherData().getFwConfigLocation();
   File baseDir = null;
   if (fwConfigLoc == null) {
     baseDir = manipulator.getLauncherData().getHome();
     if (baseDir == null) {
       if (manipulator.getLauncherData().getLauncher() != null) {
         baseDir = manipulator.getLauncherData().getLauncher().getParentFile();
       } else {
         throw new IllegalStateException(
             "All of fwConfigFile, home, launcher are not set."); //$NON-NLS-1$
       }
     }
   } else {
     if (fwConfigLoc.exists())
       if (fwConfigLoc.isDirectory()) baseDir = fwConfigLoc;
       else baseDir = fwConfigLoc.getParentFile();
     else {
       // TODO We need to decide whether launcher data configLocation is the location of a file or
       // a directory
       if (fwConfigLoc.getName().endsWith(".ini")) // $NON-NLS-1$
       baseDir = fwConfigLoc.getParentFile();
       else baseDir = fwConfigLoc;
     }
   }
   File configuratorFolder =
       new File(baseDir, SimpleConfiguratorManipulatorImpl.CONFIGURATOR_FOLDER);
   File targetFile = new File(configuratorFolder, SimpleConfiguratorManipulatorImpl.CONFIG_LIST);
   if (!Utils.createParentDir(targetFile)) return null;
   return targetFile;
 }
  private boolean hasBaseChanged(URI installArea, File outputFolder) {
    String rememberedTimestamp;
    try {
      rememberedTimestamp =
          (String)
              loadProperties(
                      new File(
                          outputFolder, SimpleConfiguratorImpl.BASE_TIMESTAMP_FILE_BUNDLESINFO))
                  .get(SimpleConfiguratorImpl.KEY_BUNDLESINFO_TIMESTAMP);
    } catch (IOException e) {
      return false;
    }
    if (rememberedTimestamp == null) return false;

    File sharedBundlesInfo = new File(URIUtil.append(installArea, SHARED_BUNDLES_INFO));
    if (!sharedBundlesInfo.exists()) return true;
    return !String.valueOf(sharedBundlesInfo.lastModified()).equals(rememberedTimestamp);
  }
  private void rememberSharedBundlesInfoTimestamp(URI installArea, File outputFolder) {
    if (installArea == null) return;

    File sharedBundlesInfo = new File(URIUtil.append(installArea, SHARED_BUNDLES_INFO));
    if (!sharedBundlesInfo.exists()) return;

    Properties timestampToPersist = new Properties();
    timestampToPersist.put(
        SimpleConfiguratorImpl.KEY_BUNDLESINFO_TIMESTAMP,
        Long.toString(sharedBundlesInfo.lastModified()));
    OutputStream os = null;
    try {
      try {
        File outputFile =
            new File(outputFolder, SimpleConfiguratorImpl.BASE_TIMESTAMP_FILE_BUNDLESINFO);
        os = new BufferedOutputStream(new FileOutputStream(outputFile));
        timestampToPersist.store(os, "Written by " + this.getClass()); // $NON-NLS-1$
      } finally {
        if (os != null) os.close();
      }
    } catch (IOException e) {
      return;
    }
  }