docs: function installPluginsFromConfigXML(args) {
      events.emit('verbose', 'Checking config.xml for saved plugins that haven\'t been added to the project');
  
      //Install plugins that are listed on config.xml
      var projectRoot = cordova_util.cdProjectRoot();
      var configPath = cordova_util.projectConfig(projectRoot);
      var cfg = new ConfigParser(configPath);
      var plugins_dir = path.join(projectRoot, 'plugins');
  
      // Get all configured plugins
      var plugins = cfg.getPluginIdList();
      if (0 === plugins.length) {
          return Q('No plugins found in config.xml that haven\'t been added to the project');
      }
  
  
      // Intermediate variable to store current installing plugin name
      // to be able to create informative warning on plugin failure
      var pluginName;
  
      // CB-9560 : Run `plugin add` serially, one plugin after another
      // We need to wait for the plugin and its dependencies to be installed
      // before installing the next root plugin otherwise we can have common
      // plugin dependencies installed twice which throws a nasty error.
      return promiseutil.Q_chainmap_graceful(plugins, function(featureId) {
          var pluginPath = path.join(plugins_dir, featureId);
          if (fs.existsSync(pluginPath)) {
              // Plugin already exists
              return Q();
          }
          events.emit('log', 'Discovered plugin "' + featureId + '" in config.xml. Adding it to the project');
          var pluginEntry = cfg.getPlugin(featureId);
  
          // Install from given URL if defined or using a plugin id. If spec isn't a valid version or version range,
          // assume it is the location to install from.
          var pluginSpec = pluginEntry.spec;
          pluginName = pluginEntry.name;
  
          // CB-10761 If plugin spec is not specified, use plugin name
          var installFrom = pluginSpec || pluginName;
          if (pluginSpec && semver.validRange(pluginSpec, true))
              installFrom = pluginName + '@' + pluginSpec;
  
          // Add feature preferences as CLI variables if have any
          var options = {
              cli_variables: pluginEntry.variables,
              searchpath: args.searchpath,
              fetch: args.fetch || false,
              save: args.save || false
          };
          var plugin = require('./plugin');
          return plugin('add', installFrom, options);
      }, function (error) {
          // CB-10921 emit a warning in case of error
          var msg = 'Failed to restore plugin \"' + pluginName + '\" from config.xml. ' +
              'You might need to try adding it again. Error: ' + error;
          events.emit('warn', msg);
      });
  }