public static @NotNull String processAndSaveAllSchemas(@NotNull XmlFile file, @NotNull final Map<String, String> scannedToFileName,
                                                         final @NotNull SchemaReferenceProcessor schemaReferenceProcessor) {
    final String fileName = file.getName();

    String previous = scannedToFileName.get(fileName);

    if (previous != null) return previous;

    scannedToFileName.put(fileName, fileName);

    final StringBuilder result = new StringBuilder();

    file.acceptChildren(new XmlRecursiveElementVisitor() {
      @Override
      public void visitElement(@NotNull PsiElement psiElement) {
        super.visitElement(psiElement);
        if (psiElement instanceof LeafPsiElement) {
          final String text = psiElement.getText();
          result.append(text);
        }
      }

      @Override
      public void visitXmlAttribute(@NotNull XmlAttribute xmlAttribute) {
        boolean replaced = false;

        if (xmlAttribute.isNamespaceDeclaration()) {
          replaced = true;
          final String value = xmlAttribute.getValue();
          result.append(xmlAttribute.getText()).append(" ");

          if (!scannedToFileName.containsKey(value)) {
            final XmlNSDescriptor nsDescriptor = xmlAttribute.getParent().getNSDescriptor(value, true);

            if (nsDescriptor != null) {
              processAndSaveAllSchemas(Objects.requireNonNull(nsDescriptor.getDescriptorFile()), scannedToFileName, schemaReferenceProcessor);
            }
          }
        }
        else if ("schemaLocation".equals(xmlAttribute.getName())) {
          PsiReference[] references = Objects.requireNonNull(xmlAttribute.getValueElement()).getReferences();
          PsiReference reference = ArrayUtil.getLastElement(references);
          if (reference != null) {
            PsiElement psiElement = reference.resolve();

            if (psiElement instanceof XmlFile) {
              final String s = processAndSaveAllSchemas(((XmlFile)psiElement), scannedToFileName, schemaReferenceProcessor);
              result.append(xmlAttribute.getName()).append("='").append(s).append('\'');
              replaced = true;
            }
          }
        }
        if (!replaced) result.append(xmlAttribute.getText());
      }
    });

    final VirtualFile virtualFile = file.getVirtualFile();
    final String content = result.toString();

    byte[] bytes;
    if (virtualFile != null) {
      bytes = content.getBytes(virtualFile.getCharset());
    }
    else {
      try {
        final String charsetName = XmlUtil.extractXmlEncodingFromProlog(content.getBytes(StandardCharsets.UTF_8));
        bytes = charsetName != null ? content.getBytes(charsetName) : content.getBytes(StandardCharsets.UTF_8);
      }
      catch (UnsupportedEncodingException e) {
        bytes = content.getBytes(StandardCharsets.UTF_8);
      }
    }

    schemaReferenceProcessor.processSchema(fileName, bytes);
    return fileName;
  }
public static @NotNull String processAndSaveAllSchemas(@NotNull XmlFile file, @NotNull final Map<String, String> scannedToFileName,
                                                         final @NotNull SchemaReferenceProcessor schemaReferenceProcessor)