/**
  * Synchronize the current set of configurations for the project with the Autotools saved
  * configuration data. This is required when configuration management occurs outside of the
  * Autotools Configure Settings page in the Property menu.
  *
  * @param project to synchronize configurations for
  */
 public synchronized void syncConfigurations(IProject project) {
   setSyncing(true);
   clearTmpConfigurations(project);
   ICProjectDescription pd = CoreModel.getDefault().getProjectDescription(project);
   ICConfigurationDescription[] cfgs = pd.getConfigurations();
   Map<String, IAConfiguration> newCfgList = new HashMap<>();
   for (int i = 0; i < cfgs.length; ++i) {
     cfgs[i].getConfigurationData();
     IAConfiguration acfg = getTmpConfiguration(project, cfgs[i]);
     newCfgList.put(cfgs[i].getId(), acfg);
   }
   setSyncing(false);
   clearTmpConfigurations(project);
   replaceProjectConfigurations(project, newCfgList);
 }
  // Perform apply of configuration changes.  This rewrites out the current known list of
  // configurations
  // with any changes currently that have been made to them.  If a configuration has been renamed,
  // but this
  // has not yet been confirmed by the end-user, then only the changes to the configuration are
  // made.  The
  // name currently remains the same in the output file.
  public synchronized void applyConfigs(String projectName, ICConfigurationDescription[] cfgds) {
    try {
      IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
      IResource res = root.findMember(projectName, false);
      if (res == null || res.getType() != IResource.PROJECT) {
        AutotoolsPlugin.logErrorMessage(
            ConfigureMessages.getFormattedString(CFG_CANT_SAVE, new String[] {projectName}));
        return;
      }
      IProject project = (IProject) res;
      IPath output = project.getLocation().append(CFG_FILE_NAME);
      File f = output.toFile();
      if (!f.exists()) f.createNewFile();
      if (f.exists()) {
        try (PrintWriter p = new PrintWriter(new BufferedWriter(new FileWriter(f)))) {
          Map<String, IAConfiguration> cfgs = getSavedConfigs(project);
          if (cfgs == null) return;
          p.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); // $NON-NLS-1$
          p.println("<configurations>"); // $NON-NLS-1$
          Option[] optionList = AutotoolsConfiguration.getOptionList();
          HashSet<String> savedIds = new HashSet<>();
          setSyncing(true);
          for (int x = 0; x < cfgds.length; ++x) {
            ICConfigurationDescription cfgd = cfgds[x];
            @SuppressWarnings("unused")
            CConfigurationData data = cfgd.getConfigurationData();
            String id = cfgd.getId();
            savedIds.add(id);
            IAConfiguration cfg = getTmpConfiguration(project, cfgd);
            cfgs.put(
                id,
                cfg); // add to list in case we have a new configuration not yet added to Project
                      // Description
            p.println("<configuration id=\"" + id + "\">"); // $NON-NLS-1$ //$NON-NLS-2$
            for (int j = 0; j < optionList.length; ++j) {
              Option option = optionList[j];
              IConfigureOption opt = cfg.getOption(option.getName());
              if (!opt.isCategory())
                p.println(
                    "<option id=\""
                        + option.getName()
                        + "\" value=\""
                        + opt.getValue()
                        + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ // $NON-NLS-3$
            }
            p.println("</configuration>"); // $NON-NLS-1$
            syncNameField(cfgd);
          }
          setSyncing(false);

          // Put all the remaining configurations already saved back into the file.
          // These represent deleted configurations, but confirmation has not occurred.
          for (Entry<String, IAConfiguration> i : cfgs.entrySet()) {
            String id = i.getKey();
            // A remaining id won't appear in our savedIds list.
            if (!savedIds.contains(id)) {
              IAConfiguration cfg = i.getValue();
              p.println("<configuration id=\"" + id + "\">"); // $NON-NLS-1$ //$NON-NLS-2$
              for (int j = 0; j < optionList.length; ++j) {
                Option option = optionList[j];
                IConfigureOption opt = cfg.getOption(option.getName());
                if (!opt.isCategory())
                  p.println(
                      "<option id=\""
                          + option.getName()
                          + "\" value=\""
                          + opt.getValue()
                          + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ // $NON-NLS-3$
              }
              p.println("</configuration>"); // $NON-NLS-1$
            }
          }
          p.println("</configurations>");
        }
      }
    } catch (IOException e) {
      AutotoolsPlugin.log(e);
    }
  }
 private void saveConfigs(IProject project, ICConfigurationDescription[] cfgds) {
   try {
     String projectName = project.getName();
     IPath output = project.getLocation().append(CFG_FILE_NAME);
     File f = output.toFile();
     if (!f.exists()) f.createNewFile();
     if (f.exists()) {
       try (PrintWriter p = new PrintWriter(new BufferedWriter(new FileWriter(f)))) {
         Map<String, IAConfiguration> cfgs = configs.get(projectName);
         p.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); // $NON-NLS-1$
         p.println("<configurations>"); // $NON-NLS-1$
         Option[] optionList = AutotoolsConfiguration.getOptionList();
         // Before saving, force any cloning to occur via the option
         // value handler.
         setSyncing(true);
         for (int i = 0; i < cfgds.length; ++i) {
           @SuppressWarnings("unused")
           CConfigurationData data = cfgds[i].getConfigurationData();
         }
         setSyncing(false);
         for (int i = 0; i < cfgds.length; ++i) {
           ICConfigurationDescription cfgd = cfgds[i];
           String id = cfgd.getId();
           IAConfiguration cfg = cfgs.get(id);
           if (cfg == null) {
             cfg = createDefaultConfiguration(id);
           }
           p.println("<configuration id=\"" + cfg.getId() + "\">"); // $NON-NLS-1$ //$NON-NLS-2$
           for (int j = 0; j < optionList.length; ++j) {
             Option option = optionList[j];
             IConfigureOption opt = cfg.getOption(option.getName());
             if (opt.isFlag()) {
               p.println(
                   "<flag id=\""
                       + option.getName()
                       + "\" value=\"" //$NON-NLS-1$ //$NON-NLS-2$
                       + xmlEscape(option.getDefaultValue())
                       + "\">"); //$NON-NLS-1$
               FlagConfigureOption fco = (FlagConfigureOption) opt;
               List<String> children = fco.getChildren();
               for (int k = 0; k < children.size(); ++k) {
                 String childName = children.get(k);
                 IConfigureOption childopt = cfg.getOption(childName);
                 p.println(
                     "<flagvalue id=\""
                         + childopt.getName()
                         + "\" value=\"" //$NON-NLS-1$ //$NON-NLS-2$
                         + xmlEscape(childopt.getValue())
                         + "\"/>"); // $NON-NLS-3$
               }
               p.println("</flag>"); // $NON-NLS-1$
             } else if (!opt.isCategory() && !opt.isFlagValue())
               p.println(
                   "<option id=\""
                       + option.getName()
                       + "\" value=\""
                       + xmlEscape(opt.getValue()) // $NON-NLS-1$ //$NON-NLS-2$
                       + "\"/>"); // $NON-NLS-3$
           }
           p.println("</configuration>"); // $NON-NLS-1$
           // Sync name field as this configuration is now
           // officially saved
           syncNameField(cfgd);
         }
         p.println("</configurations>");
       }
     }
   } catch (IOException e) {
     AutotoolsPlugin.log(e);
   }
 }