function visitAndProcessFiles(rootPath, processor) {
            var rootEntry = FileSystem.getDirectoryForPath(rootPath),
                files = [];

            function visitor(file) {
                if (!file.isDirectory) {
                    // Skip binary files, since we don't care about them for these purposes and we can't read them
                    // to get their contents.
                    if (!LanguageManager.getLanguageForPath(file.fullPath).isBinary()) {
                        files.push(file);
                    }
                }
                return true;
            }
            return promisify(rootEntry, "visit", visitor).then(function () {
                return Async.doInParallel(files, function (file) {
                    return promisify(file, "read").then(function (contents) {
                        return processor(contents, file.fullPath);
                    });
                });
            });
        }
Helper function that calls the given asynchronous processor once on each file in the given subtree
and returns a promise that's resolved when all files are processed.
@param {string} rootPath The root of the subtree to search.
@param {function(string, string): $.Promise} processor The function that processes each file. Args are:
     contents: the contents of the file
     fullPath: the full path to the file on disk
@return {$.Promise} A promise that is resolved when all files are processed, or rejected if there was
     an error reading one of the files or one of the process steps was rejected.