public void startElement(String uri, String localName, String qName, Attributes atts)
            throws SAXException {
          Set<String> mapped = new HashSet<String>();
          mappedPrefixes.push(mapped);

          AttributesImpl newAtts = new AttributesImpl();
          // parse namespace declaration attributes
          if (atts != null) {
            for (int i = 0; i < atts.getLength(); i++) {
              String attQname = atts.getQName(i);
              boolean addAtt = true;
              if (isNamespaceDeclaration(attQname)) {
                String newPrefix = "";
                String newUri = atts.getValue(i);
                if (attQname.length() > NAMESPACE_DECLARATION_PREFIX.length()) {
                  newPrefix = attQname.substring(NAMESPACE_DECLARATION_PREFIX.length() + 1);
                }

                // xmlns prefix cannot be declared
                if (NAMESPACE_DECLARATION_PREFIX.equals(newPrefix))
                  throwException(
                      NAMESPACE_DECLARATION_PREFIX + " namespace prefix cannot be declared");

                // xml cannot be bound to a different uri
                if (XML_PREFIX.equals(newPrefix)) {
                  if (!XML_URI.equals(newUri))
                    throwException(
                        XML_PREFIX
                            + " namespace prefix cannot be bound to an URI different from "
                            + XML_URI);
                }
                // no prefix except for xml can be bound to xml
                // namespace
                else if (XML_URI.equals(newUri))
                  throwException(
                      "only " + XML_PREFIX + " namespace prefix can be bound to " + XML_URI);

                // check that new prefix is an ncname
                if (newPrefix.length() > 0 && !XMLChar.isValidNCName(newPrefix))
                  throwException("namespace prefix " + newPrefix + " is not an NCName");

                if (mapped.contains(newPrefix))
                  throwException(
                      "namespace prefix " + newPrefix + " declared twice in the same element");
                Mapping mapping = new Mapping(newUri, prefixMappings.get(newPrefix));
                prefixMappings.put(newPrefix, mapping);
                mapped.add(newPrefix);
                contentHandler.startPrefixMapping(newPrefix, newUri);
                addAtt = namespacePrefixes;
              }
              if (addAtt) newAtts.addAttribute("", "", attQname, atts.getType(i), atts.getValue(i));
            }
          }

          // set uris on attributes
          for (int i = 0; i < newAtts.getLength(); i++) {
            String attQname = newAtts.getQName(i);
            ExpandedName splitName = parseQName(attQname);
            newAtts.setLocalName(i, splitName.localName);
            newAtts.setURI(i, splitName.uri);
          }

          ExpandedName splitName = parseQName(qName);
          localName = splitName.localName;
          uri = splitName.uri;

          contentHandler.startElement(uri, localName, qName, newAtts);
        }