String (@NotNull String text, @NotNull Int2ObjectMap<String> offsetToProperty, @NotNull Project project) { List<Object> properties = new ArrayList<>(FileTemplateManager.getInstance(project).getDefaultProperties().keySet()); properties.add(FileTemplate.ATTRIBUTE_PACKAGE_NAME); String regex = escapeRegexChars(text); // first group is a whole file header int groupNumber = 1; for (Object property : properties) { String name = property.toString(); String escaped = escapeRegexChars("${" + name + "}"); boolean first = true; for (int i = regex.indexOf(escaped); i != -1 && i < regex.length(); i = regex.indexOf(escaped, i + 1)) { String replacement = first ? "([^\\n]*)" : "\\" + groupNumber; int delta = escaped.length() - replacement.length(); for (int off : offsetToProperty.keySet().toIntArray()) { if (off > i) { String prop = offsetToProperty.remove(off); offsetToProperty.put(off - delta, prop); } } offsetToProperty.put(i, name); regex = regex.substring(0, i) + replacement + regex.substring(i + escaped.length()); if (first) { groupNumber++; first = false; } } } return regex; }