public static void write(@Nullable Project project,
                           @Nullable Path basePath,
                           @NotNull Collection<? extends FilePatch> patches,
                           @NotNull Writer writer,
                           @NotNull String lineSeparator,
                           @Nullable CommitContext commitContext,
                           @Nullable List<? extends PatchEP> patchEpExtensions) throws IOException {
    boolean forceUnixSeparators = shouldForceUnixLineSeparator(project);
    String headerLineSeparator = forceUnixSeparators ? LineSeparator.LF.getSeparatorString()
                                                     : lineSeparator;

    // write the patch files without content modifications strictly after the files with content modifications,
    // because GitPatchReader is not ready for mixed style patches
    List<FilePatch> noContentPatches = new ArrayList<>();
    for (FilePatch filePatch : patches) {
      if (!(filePatch instanceof TextFilePatch patch)) continue;
      if (patch.hasNoModifiedContent()) {
        noContentPatches.add(patch);
        continue;
      }
      String path = ObjectUtils.chooseNotNull(patch.getAfterName(), patch.getBeforeName());
      String pathRelatedToProjectDir = getPathRelatedToProjectDir(project, basePath, path);
      Map<String, CharSequence> additionalMap = new HashMap<>();
      if (project != null) {
        for (PatchEP extension : (patchEpExtensions == null ? PatchEP.EP_NAME.getExtensionList() : patchEpExtensions)) {
          CharSequence charSequence = extension.provideContent(project, pathRelatedToProjectDir, commitContext);
          if (!StringUtil.isEmpty(charSequence)) {
            additionalMap.put(extension.getName(), charSequence);
          }
        }
      }

      String fileContentLineSeparator = forceUnixSeparators ? LineSeparator.LF.getSeparatorString()
                                                            : StringUtil.notNullize(patch.getLineSeparator(), headerLineSeparator);

      writeFileHeading(writer, basePath, patch, headerLineSeparator, additionalMap);
      for (PatchHunk hunk : patch.getHunks()) {
        writeHunkStart(writer, hunk.getStartLineBefore(), hunk.getEndLineBefore(), hunk.getStartLineAfter(), hunk.getEndLineAfter(),
                       headerLineSeparator);
        for (PatchLine line : hunk.getLines()) {
          char prefixChar = switch (line.getType()) {
            case ADD -> '+';
            case REMOVE -> '-';
            case CONTEXT -> ' ';
          };
          String text = line.getText();
          text = StringUtil.trimEnd(text, "\n");
          writeLine(writer, text, prefixChar);
          if (line.isSuppressNewLine()) {
            // do not use fileContentLineSeparator here, as this line has no own separator
            writer.write(headerLineSeparator + NO_NEWLINE_SIGNATURE + headerLineSeparator);
          }
          else {
            writer.write(fileContentLineSeparator);
          }
        }
      }
    }
    for (FilePatch patch : noContentPatches) {
      GitPatchWriter.writeGitHeader(writer, basePath, patch, headerLineSeparator);
    }
  }
public static void write(@Nullable Project project,
                           @Nullable Path basePath,
                           @NotNull Collection<? extends FilePatch> patches,
                           @NotNull Writer writer,
                           @NotNull String lineSeparator,
                           @Nullable CommitContext commitContext,
                           @Nullable List<? extends PatchEP> patchEpExtensions)