@Nullable
  public XmlAttribute getAttribute(String qname) {
    if (qname == null) return null;
    final XmlAttribute[] attributes = getAttributes();

    final boolean caseSensitive = isCaseSensitive();

    for (final XmlAttribute attribute : attributes) {
      final LeafElement attrNameElement =
          (LeafElement) XmlChildRole.ATTRIBUTE_NAME_FINDER.findChild(attribute.getNode());
      if (attrNameElement != null
          && (caseSensitive && Comparing.equal(attrNameElement.getChars(), qname)
              || !caseSensitive && Comparing.equal(attrNameElement.getChars(), qname, false))) {
        return attribute;
      }
    }
    return null;
  }
  public XmlAttribute setAttribute(String qname, String value) throws IncorrectOperationException {
    final XmlAttribute attribute = getAttribute(qname);

    if (attribute != null) {
      if (value == null) {
        deleteChildInternal(attribute.getNode());
        return null;
      }
      attribute.setValue(value);
      return attribute;
    } else if (value == null) {
      return null;
    } else {
      PsiElement xmlAttribute =
          add(XmlElementFactory.getInstance(getProject()).createXmlAttribute(qname, value));
      while (!(xmlAttribute instanceof XmlAttribute)) xmlAttribute = xmlAttribute.getNextSibling();
      return (XmlAttribute) xmlAttribute;
    }
  }
  @Nullable
  private BidirectionalMap<String, String> computeNamespaceMap(PsiElement parent) {
    BidirectionalMap<String, String> map = null;
    if (hasNamespaceDeclarations()) {
      map = new BidirectionalMap<String, String>();
      final XmlAttribute[] attributes = getAttributes();

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

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

    if (parent instanceof XmlDocument) {
      final XmlExtension extension = XmlExtension.getExtensionByElement(parent);
      if (extension != null) {
        final String[][] defaultNamespace =
            extension.getNamespacesFromDocument((XmlDocument) parent, map != null);
        if (defaultNamespace != null) {
          if (map == null) {
            map = new BidirectionalMap<String, String>();
          }
          for (final String[] prefix2ns : defaultNamespace) {
            map.put(prefix2ns[0], getRealNs(prefix2ns[1]));
          }
        }
      }
    }
    return map;
  }
  @NotNull
  private Map<String, CachedValue<XmlNSDescriptor>> computeNsDescriptorMap() {
    Map<String, CachedValue<XmlNSDescriptor>> map = null;
    // XSD aware attributes processing

    final String noNamespaceDeclaration =
        getAttributeValue("noNamespaceSchemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI);
    final String schemaLocationDeclaration =
        getAttributeValue("schemaLocation", XmlUtil.XML_SCHEMA_INSTANCE_URI);

    if (noNamespaceDeclaration != null) {
      map = initializeSchema(XmlUtil.EMPTY_URI, null, noNamespaceDeclaration, map);
    }
    if (schemaLocationDeclaration != null) {
      final StringTokenizer tokenizer = new StringTokenizer(schemaLocationDeclaration);
      while (tokenizer.hasMoreTokens()) {
        final String uri = tokenizer.nextToken();
        if (tokenizer.hasMoreTokens()) {
          map = initializeSchema(uri, null, tokenizer.nextToken(), map);
        }
      }
    }
    // namespace attributes processing (XSD declaration via ExternalResourceManager)

    if (hasNamespaceDeclarations()) {
      for (final XmlAttribute attribute : getAttributes()) {
        if (attribute.isNamespaceDeclaration()) {
          String ns = attribute.getValue();
          if (ns == null) ns = XmlUtil.EMPTY_URI;
          ns = getRealNs(ns);

          if (map == null || !map.containsKey(ns)) {
            map = initializeSchema(ns, getNSVersion(ns, this), getNsLocation(ns), map);
          }
        }
      }
    }
    return map == null ? Collections.<String, CachedValue<XmlNSDescriptor>>emptyMap() : map;
  }
 @NotNull
 public Map<String, String> getLocalNamespaceDeclarations() {
   Map<String, String> namespaces = new THashMap<String, String>();
   for (final XmlAttribute attribute : getAttributes()) {
     if (!attribute.isNamespaceDeclaration() || attribute.getValue() == null) continue;
     // xmlns -> "", xmlns:a -> a
     final String localName = attribute.getLocalName();
     namespaces.put(localName.equals(attribute.getName()) ? "" : localName, attribute.getValue());
   }
   return namespaces;
 }