void (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")); }); } }