lib/plugin.js
function onNextTransform (transform, next) {
      // check if we should handle this filePath
      function shouldProcess (filePath, done) {
        done(!!multimatch(filePath, transform.pattern, transform.opts).length)
      }

      // transform the path
      function process (filePath, complete) {
        var filename = path.basename(filePath),
            pathParts = path.dirname(filePath).split(path.sep)

        // we'll get an empty arrary if we overslice
        pathParts = pathParts.slice(transform.by)
        pathParts.push(filename)

        var newPath = pathParts.join(path.sep),
            fileData = files[filePath]

        // don't need the old fileData anymore,
        // since we are re-adding with the new path
        delete files[filePath]
        files[newPath] = fileData

        complete()
      }

      // we do this for each option as the last may have modified the collection
      async.filter(Object.keys(files), shouldProcess, function (results) {
        async.each(results, process, next)
      })
    }
function onNextTransform (transform, next) {
      // check if we should handle this filePath
      function shouldProcess (filePath, done) {
        done(!!multimatch(filePath, transform.pattern, transform.opts).length)
      }

      // transform the path
      function process (filePath, complete) {
        var filename = path.basename(filePath),
            pathParts = path.dirname(filePath).split(path.sep)

        // we'll get an empty arrary if we overslice
        pathParts = pathParts.slice(transform.by)
        pathParts.push(filename)

        var newPath = pathParts.join(path.sep),
            fileData = files[filePath]

        // don't need the old fileData anymore,
        // since we are re-adding with the new path
        delete files[filePath]
        files[newPath] = fileData

        complete()
      }

      // we do this for each option as the last may have modified the collection
      async.filter(Object.keys(files), shouldProcess, function (results) {
        async.each(results, process, next)
      })
    }
function onNextTransform ( transform , next ) { // check if we should handle this filePath
 function shouldProcess ( filePath , done ) { done ( ! ! multimatch ( filePath , transform . pattern , transform . opts ) . length ) } // transform the path
 function process ( filePath , complete ) { var filename = path . basename ( filePath ) , pathParts = path . dirname ( filePath ) . split ( path . sep ) // we'll get an empty arrary if we overslice
 pathParts = pathParts . slice ( transform . by ) pathParts . push ( filename ) var newPath = pathParts . join ( path . sep ) , fileData = files [ filePath ] // don't need the old fileData anymore,
 // since we are re-adding with the new path
 delete files [ filePath ] files [ newPath ] = fileData complete ( ) } // we do this for each option as the last may have modified the collection
 async . filter ( Object . keys ( files ) , shouldProcess , function ( results ) { async . each ( results , process , next ) } ) }
will be called once per transform
will be called once per transform