code: function updatePaths(pathMap, options, log) {
      if (!pathMap || typeof pathMap !== "object" || Array.isArray(pathMap)) {
          throw new Error("An object mapping from target paths to source paths is required.");
      }
  
      log = log || function(message) { };
  
      var updated = false;
  
      // Iterate in sorted order to ensure directories are created before files under them.
      Object.keys(pathMap).sort().forEach(function (targetPath) {
          var sourcePath = pathMap[targetPath];
          updated = updatePathInternal(sourcePath, targetPath, options, log) || updated;
      });
  
      return updated;
  }
docs: Updates files and directories based on a mapping from target paths to source paths. Targets
  with null sources in the map are deleted.
  
  @param {Object} pathMap A dictionary mapping from target paths to source paths.
  @param {Object} [options] Optional additional parameters for the update.
  @param {string} [options.rootDir] Optional root directory (such as a project) to which target
  and source path parameters are relative; may be omitted if the paths are absolute. The
  rootDir is always omitted from any logged paths, to make the logs easier to read.
  @param {boolean} [options.all] If true, all files are copied regardless of last-modified times.
  Otherwise, a file is copied if the source's last-modified time is greather than or
  equal to the target's last-modified time, or if the file sizes are different.
  @param {loggingCallback} [log] Optional logging callback that takes a string message
  describing any file operations that are performed.
  @return {boolean} true if any changes were made, or false if the force flag is not set
  and everything was up to date