@NotNull
  private static XmlFileHeader calcXmlFileHeader(final PsiFile file) {

    // if (file.getFileType() == XmlFileType.INSTANCE) {
    //  VirtualFile virtualFile = file.getVirtualFile();
    //  if (virtualFile instanceof VirtualFileWithId) {
    //    ObjectStubTree tree = StubTreeLoader.getInstance().readFromVFile(file.getProject(),
    // virtualFile);
    //    if (tree != null) {
    //      return ((FileStub)tree.getRoot()).getHeader();
    //    }
    //  }
    // }
    if (file instanceof XmlFile && file.getNode().isParsed()) {
      final XmlDocument document = ((XmlFile) file).getDocument();
      if (document != null) {
        String publicId = null;
        String systemId = null;
        final XmlProlog prolog = document.getProlog();
        if (prolog != null) {
          final XmlDoctype doctype = prolog.getDoctype();
          if (doctype != null) {
            publicId = doctype.getPublicId();
            systemId = doctype.getSystemId();
            if (systemId == null) {
              systemId = doctype.getDtdUri();
            }
          }
        }

        final XmlTag tag = document.getRootTag();
        if (tag != null) {
          String localName = tag.getLocalName();
          if (StringUtil.isNotEmpty(localName)) {
            if (tag.getPrevSibling() instanceof PsiErrorElement) {
              return XmlFileHeader.EMPTY;
            }

            String psiNs = tag.getNamespace();
            return new XmlFileHeader(
                localName,
                psiNs == XmlUtil.EMPTY_URI || Comparing.equal(psiNs, systemId) ? null : psiNs,
                publicId,
                systemId);
          }
        }
      }
      return XmlFileHeader.EMPTY;
    }

    if (!file.isValid()) return XmlFileHeader.EMPTY;
    return NanoXmlUtil.parseHeader(file);
  }
  @Nullable
  private XmlNSDescriptor getNsDescriptorFormDocType(
      final XmlDoctype doctype, final XmlFile containingFile, final boolean forHtml) {
    XmlNSDescriptor descriptor = getNSDescriptorFromMetaData(doctype.getMarkupDecl(), true);

    final String filePath = getFilePathForLogging(containingFile);

    final String dtdUri = XmlUtil.getDtdUri(doctype);
    LOG.debug(
        "DTD url for doctype " + doctype.getText() + " in file " + filePath + " is " + dtdUri);

    if (dtdUri != null && !dtdUri.isEmpty()) {
      XmlFile xmlFile = XmlUtil.findNamespace(containingFile, dtdUri);
      if (xmlFile == null) {
        // try to auto-detect it
        xmlFile = XmlNamespaceIndex.guessDtd(dtdUri, containingFile);
      }
      final String schemaFilePath = getFilePathForLogging(xmlFile);

      LOG.debug("Schema file for " + filePath + " is " + schemaFilePath);

      XmlNSDescriptor descriptorFromDtd =
          getNSDescriptorFromMetaData(xmlFile == null ? null : xmlFile.getDocument(), forHtml);

      LOG.debug(
          "Descriptor from meta data for schema file "
              + schemaFilePath
              + " is "
              + (descriptorFromDtd != null
                  ? descriptorFromDtd.getClass().getCanonicalName()
                  : "NULL"));

      if (descriptor != null && descriptorFromDtd != null) {
        descriptor =
            new XmlNSDescriptorSequence(new XmlNSDescriptor[] {descriptor, descriptorFromDtd});
      } else if (descriptorFromDtd != null) {
        descriptor = descriptorFromDtd;
      }
    }
    return descriptor;
  }
  private static XmlFileHeader computeHeaderByPsi(XmlFile file) {
    final XmlDocument document = file.getDocument();
    if (document == null) {
      return XmlFileHeader.EMPTY;
    }

    String publicId = null;
    String systemId = null;
    final XmlProlog prolog = document.getProlog();
    if (prolog != null) {
      final XmlDoctype doctype = prolog.getDoctype();
      if (doctype != null) {
        publicId = doctype.getPublicId();
        systemId = doctype.getSystemId();
        if (systemId == null) {
          systemId = doctype.getDtdUri();
        }
      }
    }

    final XmlTag tag = document.getRootTag();
    if (tag == null) {
      return XmlFileHeader.EMPTY;
    }

    String localName = tag.getLocalName();
    if (StringUtil.isNotEmpty(localName)) {
      if (tag.getPrevSibling() instanceof PsiErrorElement) {
        return XmlFileHeader.EMPTY;
      }

      String psiNs = tag.getNamespace();
      return new XmlFileHeader(
          localName,
          psiNs == XmlUtil.EMPTY_URI || Comparing.equal(psiNs, systemId) ? null : psiNs,
          publicId,
          systemId);
    }
    return XmlFileHeader.EMPTY;
  }