private static @Nullable BidirectionalMap<String, String> computeNamespaceMap(@NotNull XmlTag tag) {
    BidirectionalMap<String, String> map = null;
    boolean hasNamespaceDeclarations = tag.hasNamespaceDeclarations();
    if (hasNamespaceDeclarations) {
      map = new BidirectionalMap<>();
      final XmlAttribute[] attributes = tag.getAttributes();

      for (final XmlAttribute attribute : attributes) {
        if (attribute.isNamespaceDeclaration()) {
          final String name = attribute.getName();
          int splitIndex = name.indexOf(':');
          final String value = tag.getRealNs(attribute.getValue());

          if (value != null) {
            if (splitIndex < 0) {
              map.put("", value);
            }
            else {
              map.put(XmlUtil.findLocalNameByQualifiedName(name), value);
            }
          }
        }
      }
    }

    PsiElement parent = (tag instanceof HtmlTag)
                        ? PsiTreeUtil.getParentOfType(tag, XmlTag.class, XmlDocument.class)
                        : tag.getParent();
    if (parent instanceof XmlDocument) {
      final XmlExtension extension = XmlExtension.getExtensionByElement(parent);
      if (extension != null) {
        final String[][] namespacesFromDocument = extension.getNamespacesFromDocument((XmlDocument)parent, hasNamespaceDeclarations);
        if (namespacesFromDocument != null) {
          if (map == null) {
            map = new BidirectionalMap<>();
          }
          for (final String[] prefix2ns : namespacesFromDocument) {
            if (map.containsKey(prefix2ns[0])) continue;
            map.put(prefix2ns[0], tag.getRealNs(prefix2ns[1]));
          }
        }
      }
    }
    return map;
  }
private static @Nullable BidirectionalMap<String, String> computeNamespaceMap(@NotNull XmlTag tag)