bool mergeAndDeduplicate(const TUReplacements &TUs,
                         FileToReplacementsMap &GroupedReplacements,
                         clang::SourceManager &SM) {

  // Group all replacements by target file.
  std::set<StringRef> Warned;
  for (const auto &TU : TUs) {
    for (const tooling::Replacement &R : TU.Replacements) {
      // Use the file manager to deduplicate paths. FileEntries are
      // automatically canonicalized.
      const FileEntry *Entry = SM.getFileManager().getFile(R.getFilePath());
      if (!Entry && Warned.insert(R.getFilePath()).second) {
        errs() << "Described file '" << R.getFilePath()
               << "' doesn't exist. Ignoring...\n";
        continue;
      }
      GroupedReplacements[Entry].push_back(R);
    }
  }

  // Ask clang to deduplicate and report conflicts.
  return !deduplicateAndDetectConflicts(GroupedReplacements, SM);
}