public static void saveProject(Project project,
                                 @NotNull Path zipFile,
                                 Module moduleToSave,
                                 String description,
                                 boolean replaceParameters,
                                 ProgressIndicator indicator,
                                 boolean shouldEscape) {
    Map<String, String> parameters = computeParameters(project, replaceParameters);
    indicator.setText(LangBundle.message("progress.text.saving.project"));
    StoreUtil.saveSettings(project, true);

    indicator.setText(LangBundle.message("progress.text.processing.project.files"));
    VirtualFile dir = getDirectoryToSave(project, moduleToSave);
    List<LocalArchivedTemplate.RootDescription> roots = collectStructure(project, moduleToSave);
    LocalArchivedTemplate.RootDescription basePathRoot = findOrAddBaseRoot(roots, dir);
    try {
      NioFiles.createDirectories(zipFile.getParent());
      try (Compressor stream = new Compressor.Zip(zipFile)) {
        writeFile(LocalArchivedTemplate.DESCRIPTION_PATH, description, project, basePathRoot.myRelativePath, stream, true);

        if (replaceParameters) {
          String text = getInputFieldsText(parameters);
          writeFile(LocalArchivedTemplate.TEMPLATE_DESCRIPTOR, text, project, basePathRoot.myRelativePath, stream, false);
        }

        String metaDescription = getTemplateMetaText(shouldEscape, roots);
        writeFile(LocalArchivedTemplate.META_TEMPLATE_DESCRIPTOR_PATH, metaDescription, project, basePathRoot.myRelativePath, stream, true);

        FileIndex index = moduleToSave == null
                          ? ProjectRootManager.getInstance(project).getFileIndex()
                          : ModuleRootManager.getInstance(moduleToSave).getFileIndex();
        MyContentIterator iterator = new MyContentIterator(indicator, stream, project, parameters, shouldEscape);
        for (LocalArchivedTemplate.RootDescription root : roots) {
          String prefix = LocalArchivedTemplate.ROOT_FILE_NAME + root.myIndex;
          VirtualFile rootFile = root.myFile;
          iterator.setRootAndPrefix(rootFile, prefix);
          index.iterateContentUnderDirectory(rootFile, iterator);
        }
      }
    }
    catch (ProcessCanceledException ignored) { }
    catch (Exception e) {
      LOG.error(e);
      EdtInvocationManager.invokeLaterIfNeeded(() -> {
        Messages.showErrorDialog(project,
                                 LangBundle.message("dialog.message.can.t.save.project.as.template"),
                                 LangBundle.message("dialog.message.internal.error"));
      });
    }
  }
public static void saveProject(Project project,
                                 @NotNull Path zipFile,
                                 Module moduleToSave,
                                 String description,
                                 boolean replaceParameters,
                                 ProgressIndicator indicator,
                                 boolean shouldEscape)