/** Binds namespaces. */
  protected void bindNamespaces(QName element, XMLAttributes attrs) {

    // split element qname
    splitQName(element);

    // declare namespace prefixes
    int attrCount = attrs != null ? attrs.getLength() : 0;
    for (int i = attrCount - 1; i >= 0; i--) {
      attrs.getName(i, fQName);
      String aname = fQName.rawname;
      String ANAME = aname.toUpperCase();
      if (ANAME.startsWith("XMLNS:") || ANAME.equals("XMLNS")) {
        int anamelen = aname.length();

        // get parts
        String aprefix = anamelen > 5 ? aname.substring(0, 5) : null;
        String alocal = anamelen > 5 ? aname.substring(6) : aname;
        String avalue = attrs.getValue(i);

        // re-case parts and set them back into attributes
        if (anamelen > 5) {
          aprefix = modifyName(aprefix, NAMES_LOWERCASE);
          alocal = modifyName(alocal, fNamesElems);
          aname = aprefix + ':' + alocal;
        } else {
          alocal = modifyName(alocal, NAMES_LOWERCASE);
          aname = alocal;
        }
        fQName.setValues(aprefix, alocal, aname, null);
        attrs.setName(i, fQName);

        // declare prefix
        String prefix = alocal != aname ? alocal : "";
        String uri = avalue.length() > 0 ? avalue : null;
        if (fOverrideNamespaces
            && prefix.equals(element.prefix)
            && HTMLElements.getElement(element.localpart, null) != null) {
          uri = fNamespacesURI;
        }
        fNamespaceContext.declarePrefix(prefix, uri);
      }
    }

    // bind element
    String prefix = element.prefix != null ? element.prefix : "";
    element.uri = fNamespaceContext.getURI(prefix);
    // REVISIT: The prefix of a qualified element name that is
    // bound to a namespace is passed (as recent as
    // Xerces 2.4.0) as "" for start elements and null
    // for end elements. Why? One of them is a bug,
    // clearly. -Ac
    if (element.uri != null && element.prefix == null) {
      element.prefix = "";
    }

    // do we need to insert namespace bindings?
    if (fInsertNamespaces
        && attrs != null
        && HTMLElements.getElement(element.localpart, null) != null) {
      if (element.prefix == null || fNamespaceContext.getURI(element.prefix) == null) {
        String xmlns = "xmlns" + ((element.prefix != null) ? ":" + element.prefix : "");
        fQName.setValues(null, xmlns, xmlns, null);
        attrs.addAttribute(fQName, "CDATA", fNamespacesURI);
        bindNamespaces(element, attrs);
        return;
      }
    }

    // bind attributes
    attrCount = attrs != null ? attrs.getLength() : 0;
    for (int i = 0; i < attrCount; i++) {
      attrs.getName(i, fQName);
      splitQName(fQName);
      prefix =
          !fQName.rawname.equals("xmlns") ? (fQName.prefix != null ? fQName.prefix : "") : "xmlns";
      // PATCH: Joseph Walton
      if (!prefix.equals("")) {
        fQName.uri = prefix.equals("xml") ? XML_URI : fNamespaceContext.getURI(prefix);
      }
      // NOTE: You would think the xmlns namespace would be handled
      // by NamespaceSupport but it's not. -Ac
      if (prefix.equals("xmlns") && fQName.uri == null) {
        fQName.uri = XMLNS_URI;
      }
      attrs.setName(i, fQName);
    }
  } // bindNamespaces(QName,XMLAttributes)