code: function readFile(path, options, callback) {
          var encoding = options.encoding || "utf8";
  
          // callback to be executed when the call to stat completes
          //  or immediately if a stat object was passed as an argument
          function doReadFile(stat) {
              if (stat.size > (FileUtils.MAX_FILE_SIZE)) {
                  callback(FileSystemError.EXCEEDS_MAX_FILE_SIZE);
              } else {
                  appshell.fs.readFile(path, encoding, function (_err, _data, encoding, preserveBOM) {
                      if (_err) {
                          callback(_mapError(_err));
                      } else {
                          callback(null, _data, encoding, preserveBOM, stat);
                      }
                  });
              }
          }
  
          if (options.stat) {
              doReadFile(options.stat);
          } else {
              exports.stat(path, function (_err, _stat) {
                  if (_err) {
                      callback(_err);
                  } else {
                      doReadFile(_stat);
                  }
              });
          }
      }
docs: Read the contents of the file at the given path, calling back
  asynchronously with either a FileSystemError string, or with the data and
  the FileSystemStats object associated with the read file. The options
  parameter can be used to specify an encoding (default "utf8"), and also
  a cached stats object that the implementation is free to use in order
  to avoid an additional stat call.
  
  Note: if either the read or the stat call fails then neither the read data
  nor stat will be passed back, and the call should be considered to have failed.
  If both calls fail, the error from the read call is passed back.
  
  @param {string} path
  @param {{encoding: string=, stat: FileSystemStats=}} options
  @param {function(?string, string=, FileSystemStats=)} callback