public static @Nullable XmlNSDescriptor getDefaultNSDescriptor(final @NotNull XmlDocument document,
                                                                 final @Nullable String namespace,
                                                                 final boolean strict) {
    final XmlFile containingFile = XmlUtil.getContainingFile(document);
    if (containingFile == null) return null;
    final XmlProlog prolog = document.getProlog();
    final XmlDoctype doctype = prolog != null ? prolog.getDoctype() : null;
    boolean dtdUriFromDocTypeIsNamespace = false;

    if (XmlUtil.HTML_URI.equals(namespace)) {
      XmlNSDescriptor nsDescriptor = doctype != null ? getNsDescriptorFormDocType(document, doctype, containingFile, true) : null;
      if (doctype != null) {
        LOG.debug(
          "Descriptor from doctype " + doctype + " is " + (nsDescriptor != null ? nsDescriptor.getClass().getCanonicalName() : "NULL"));
      }

      if (nsDescriptor == null) {
        String htmlns = ExternalResourceManagerEx.getInstanceEx().getDefaultHtmlDoctype(document.getProject());
        if (htmlns.isEmpty()) {
          htmlns = Html5SchemaProvider.getHtml5SchemaLocation();
        }
        nsDescriptor = getDefaultNSDescriptor(document, htmlns, false);
      }
      if (nsDescriptor != null) {
        final XmlFile descriptorFile = nsDescriptor.getDescriptorFile();
        if (descriptorFile != null) {
          return getCachedHtmlNsDescriptor(descriptorFile);
        }
      }
      return new HtmlNSDescriptorImpl(nsDescriptor);
    }
    else if (XmlUtil.XHTML_URI.equals(namespace)) {
      String xhtmlNamespace = XmlUtil.getDefaultXhtmlNamespace(document.getProject());
      if (xhtmlNamespace == null || xhtmlNamespace.isEmpty()) {
        xhtmlNamespace = Html5SchemaProvider.getXhtml5SchemaLocation();
      }
      return getDefaultNSDescriptor(document, xhtmlNamespace, false);
    }
    else if (namespace != null && !namespace.equals(XmlUtil.EMPTY_URI)) {
      if (doctype == null || !namespace.equals(XmlUtil.getDtdUri(doctype))) {
        boolean documentIsSchemaThatDefinesNs = namespace.equals(XmlUtil.getTargetSchemaNsFromTag(document.getRootTag()));

        final XmlFile xmlFile = documentIsSchemaThatDefinesNs
                                ? containingFile
                                : XmlUtil.findNamespace(containingFile, namespace);
        if (xmlFile != null) {
          final XmlDocument nsDocument = AstLoadingFilter.forceAllowTreeLoading(xmlFile, () -> xmlFile.getDocument());
          if (nsDocument != null) {
            return (XmlNSDescriptor)nsDocument.getMetaData();
          }
        }
      }
      else {
        dtdUriFromDocTypeIsNamespace = true;
      }
    }

    if (strict && !dtdUriFromDocTypeIsNamespace) return null;

    if (doctype != null) {
      XmlNSDescriptor descr = getNsDescriptorFormDocType(document, doctype, containingFile, false);

      if (descr != null) {
        return XmlExtension.getExtension(containingFile).getDescriptorFromDoctype(containingFile, descr);
      }
    }

    if (strict) return null;
    if (XmlUtil.EMPTY_URI.equals(namespace)) {
      final XmlFile xmlFile = XmlUtil.findNamespace(containingFile, namespace);
      if (xmlFile != null) {
        return (XmlNSDescriptor)xmlFile.getDocument().getMetaData();
      }
    }
    try {
      final PsiFile fileFromText = PsiFileFactory.getInstance(document.getProject())
        .createFileFromText(containingFile.getName() + ".dtd", DTDLanguage.INSTANCE, XmlUtil.generateDocumentDTD(document, false), false,
                            false);
      if (fileFromText instanceof XmlFile) {
        fileFromText.putUserData(AUTO_GENERATED, Boolean.TRUE);
        return (XmlNSDescriptor)((XmlFile)fileFromText).getDocument().getMetaData();
      }
    }
    catch (ProcessCanceledException ex) {
      throw ex;
    }
    catch (RuntimeException ignored) {
    } // e.g. dtd isn't mapped to xml type

    return null;
  }
public static @Nullable XmlNSDescriptor getDefaultNSDescriptor(final @NotNull XmlDocument document,
                                                                 final @Nullable String namespace,
                                                                 final boolean strict)