code: function _doReplaceInDocument(doc, matchInfo, replaceText, isRegexp) {
          // Double-check that the open document's timestamp matches the one we recorded. This
          // should normally never go out of sync, because if it did we wouldn't start the
          // replace in the first place (due to the fact that we immediately close the search
          // results panel whenever we detect a filesystem change that affects the results),
          // but we want to double-check in case we don't happen to get the change in time.
          // This will *not* handle cases where the document has been edited in memory since
          // the matchInfo was generated.
          if (doc.diskTimestamp.getTime() !== matchInfo.timestamp.getTime()) {
              return new $.Deferred().reject(exports.ERROR_FILE_CHANGED).promise();
          }
  
          // Do the replacements in reverse document order so the offsets continue to be correct.
          doc.batchOperation(function () {
              matchInfo.matches.reverse().forEach(function (match) {
                  if (match.isChecked) {
                      doc.replaceRange(isRegexp ? parseDollars(replaceText, match.result) : replaceText, match.start, match.end);
                  }
              });
          });
  
          return new $.Deferred().resolve().promise();
      }
docs: Does a set of replacements in a single document in memory.
  @param {!Document} doc The document to do the replacements in.
  @param {Object} matchInfo The match info for this file, as returned by `_addSearchMatches()`. Might be mutated.
  @param {string} replaceText The text to replace each result with.
  @param {boolean=} isRegexp Whether the original query was a regexp.
  @return {$.Promise} A promise that's resolved when the replacement is finished or rejected with an error if there were one or more errors.