diff -pruN 1.4+r1.3.1-3/.github/dependabot.yml 1.4+r20250916-1/.github/dependabot.yml
--- 1.4+r1.3.1-3/.github/dependabot.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.github/dependabot.yml	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,10 @@
+version: 2
+updates:
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "weekly"
+  - package-ecosystem: "maven"
+    directory: "/"
+    schedule:
+      interval: "weekly"
diff -pruN 1.4+r1.3.1-3/.github/workflows/build.yml 1.4+r20250916-1/.github/workflows/build.yml
--- 1.4+r1.3.1-3/.github/workflows/build.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.github/workflows/build.yml	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,33 @@
+name: Build
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        java: [24, 21, 17, 11.0.23]
+        os: [ubuntu-latest, macos-latest, windows-latest]
+    name: Java ${{ matrix.java }}
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          submodules: true
+      - name: Set up java
+        uses: actions/setup-java@v3
+        with:
+          distribution: zulu
+          java-version: ${{ matrix.java }}
+      - name: Cache Maven packages
+        uses: actions/cache@v3
+        with:
+          path: ~/.m2
+          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+          restore-keys: ${{ runner.os }}-m2
+      - name: Build with Maven
+        run: mvn -B verify
diff -pruN 1.4+r1.3.1-3/.gitignore 1.4+r20250916-1/.gitignore
--- 1.4+r1.3.1-3/.gitignore	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.gitignore	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,9 @@
+.classpath
+.project
+.settings/
+eclipse-classes
+classes
+dist
+target
+www
+tomcat
diff -pruN 1.4+r1.3.1-3/.gitmodules 1.4+r20250916-1/.gitmodules
--- 1.4+r1.3.1-3/.gitmodules	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.gitmodules	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,3 @@
+[submodule "test-src/test/resources/html5lib-tests"]
+	path = test-src/test/resources/html5lib-tests
+	url = https://github.com/html5lib/html5lib-tests.git
diff -pruN 1.4+r1.3.1-3/.hgtags 1.4+r20250916-1/.hgtags
--- 1.4+r1.3.1-3/.hgtags	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.hgtags	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,10 @@
+0228dede851df3ace19c5448324d8f81e9457617 HTML_PARSER_INITIAL_RELEASE
+03b5e65f87f3921fe80a55b7c4af470d746abd81 RELEASE_1_2_1
+35b82c2668e8ccd9d4782844240ea5f5c75b41de RELEASE_1_0_7
+3fb354951651d1a3c69dce343f5c46b591745838 RELEASE_1_2_0
+5aef354fc3a8beda2ecd83d3bf1e785ac91afe06 trunk
+6201ee18d44f8f4023046b2b4b7eec71bb9b62f3 ENTIRE_JAVA_SOURCE_IN_CVS_2007-05-28
+c9370fd05f6eacbc33f9bda8930c22357332d474 RELEASE_1_0_6
+cb9f6e22989608c078265775fdf87edc4b81dd62 RELEASE_1_3
+763a8ce07c715e6daa4b95c29f417cc5b819a189 RELEASE_1_3_1
+42d7aef6013846b63f0801adb7cbc4379812b6a3 RELEASE_1_4
diff -pruN 1.4+r1.3.1-3/.mailmap 1.4+r20250916-1/.mailmap
--- 1.4+r1.3.1-3/.mailmap	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/.mailmap	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,7 @@
+Henri Sivonen <hsivonen@hsivonen.fi> hsivonen <none@none>
+Henri Sivonen <hsivonen@hsivonen.fi> unknown <none@none>
+Henri Sivonen <hsivonen@hsivonen.fi> html5-readonly <none@none>
+Henri Sivonen <hsivonen@hsivonen.fi> convert-repo <none@none>
+Michael[tm] Smith <mike@w3.org> Michael(tm) Smith <mike@w3.org>
+Michael[tm] Smith <mike@w3.org> sideshowbarker <none@none>
+Sam Ruby <rubys@intertwingly.net> rubys <none@none>
diff -pruN 1.4+r1.3.1-3/LICENSE.txt 1.4+r20250916-1/LICENSE.txt
--- 1.4+r1.3.1-3/LICENSE.txt	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/LICENSE.txt	2025-09-16 08:29:41.000000000 +0000
@@ -4,7 +4,7 @@ For the copyright notices for individual
 
 /*
  * Copyright (c) 2005, 2006, 2007 Henri Sivonen
- * Copyright (c) 2007-2011 Mozilla Foundation
+ * Copyright (c) 2007-2012 Mozilla Foundation
  * Portions of comments Copyright 2004-2007 Apple Computer, Inc., Mozilla 
  * Foundation, and Opera Software ASA.
  *
diff -pruN 1.4+r1.3.1-3/debian/README.source 1.4+r20250916-1/debian/README.source
--- 1.4+r1.3.1-3/debian/README.source	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/README.source	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-Information about libhtml5parser-java
--------------------------------------
-
-This package was debianized using the mh_make command
-from the maven-debian-helper package.
-
-The build system uses Maven but prevents it from downloading
-anything from the Internet, making the build compliant with
-the Debian policy.
-
-The sources were cloned from
-
-hg clone https://hg.mozilla.org/projects/htmlparser/
-
-on 2016/01/01
-
-Run hg up RELEASE_1.3.1 to "checkout" release number 1.3.1.
-
-The hidden .hg directory, .hgtags and .cvsignore were removed.
diff -pruN 1.4+r1.3.1-3/debian/changelog 1.4+r20250916-1/debian/changelog
--- 1.4+r1.3.1-3/debian/changelog	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/changelog	2025-10-06 21:30:32.000000000 +0000
@@ -1,3 +1,20 @@
+libhtml5parser-java (1.4+r20250916-1) unstable; urgency=medium
+
+  [ Fab Stz ]
+  * New upstream version 1.4+r20250916 (Closes: #1107520)
+  * update d/copyright
+  * refresh patches
+  * remove d/p/netbeans.patch
+  * add myself to Uploaders
+  * Enable Salsa CI using default template
+
+  [ Markus Koschany ]
+  * Declare compliance with Debian Policy 4.7.2.
+  * Update debian/copyright. Update Source and link to github repository.
+  * Remmove debian/README.source.
+
+ -- Fab Stz <fabstz-it@yahoo.fr>  Mon, 06 Oct 2025 23:30:32 +0200
+
 libhtml5parser-java (1.4+r1.3.1-3) unstable; urgency=medium
 
   * Switch to debhelper-compat = 13.
diff -pruN 1.4+r1.3.1-3/debian/control 1.4+r20250916-1/debian/control
--- 1.4+r1.3.1-3/debian/control	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/control	2025-10-06 21:30:32.000000000 +0000
@@ -3,19 +3,20 @@ Section: java
 Priority: optional
 Maintainer: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org>
 Uploaders:
- Markus Koschany <apo@debian.org>
+ Markus Koschany <apo@debian.org>,
+ Fab Stz <fabstz-it@yahoo.fr>
 Build-Depends:
  debhelper-compat (= 13),
  default-jdk,
  default-jdk-doc,
- libxom-java,
- libxom-java-doc,
  libicu4j-java,
+ libmaven-antrun-plugin-java,
  libmaven-bundle-plugin-java,
  libmaven-javadoc-plugin-java,
- libmaven-antrun-plugin-java,
+ libxom-java,
+ libxom-java-doc,
  maven-debian-helper (>= 1.5)
-Standards-Version: 4.5.1
+Standards-Version: 4.7.2
 Vcs-Git: https://salsa.debian.org/java-team/libhtml5parser-java.git
 Vcs-Browser: https://salsa.debian.org/java-team/libhtml5parser-java
 Homepage: https://about.validator.nu/htmlparser/
diff -pruN 1.4+r1.3.1-3/debian/copyright 1.4+r20250916-1/debian/copyright
--- 1.4+r1.3.1-3/debian/copyright	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/copyright	2025-10-06 21:30:32.000000000 +0000
@@ -1,10 +1,14 @@
 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: validator.nu HTML Parser
-Source: https://hg.mozilla.org/projects/htmlparser/
+Source: https://github.com/validator/htmlparser/
+Comment:
+ The original tarball was downloaded from
+ https://about.validator.nu/htmlparser/.
+ Newer versions are downloaded from https://github.com/validator/htmlparser/
 
 Files: *
 Copyright: 2005, 2006, 2007 Henri Sivonen
-           2007-2015 Mozilla Foundation
+           2007-2023 Mozilla Foundation
            Portions of comments Copyright 2004-2007 Apple Computer, Inc., Mozilla
            Foundation, and Opera Software ASA.
            2000, 2006, 2008 Ian Hickson and various contributors
@@ -55,7 +59,8 @@ License: WHATWG-HTML-5-spec-License
  document.
 
 Files: debian/*
-Copyright: 2016-2021, Markus Koschany <apo@debian.org>
+Copyright: 2016-2025, Markus Koschany <apo@debian.org>
+           2025,      Fab Stz <fabstz-it@yahoo.fr>
 License: Expat
 
 License: GPL-2+
@@ -588,9 +593,3 @@ License: MPL-1.1
      the notices in the Source Code files of the Original Code. You should
      use the text of this Exhibit A rather than the text found in the
      Original Code Source Code for Your Modifications.]
-
-
-
-
-
-
diff -pruN 1.4+r1.3.1-3/debian/patches/netbeans.patch 1.4+r20250916-1/debian/patches/netbeans.patch
--- 1.4+r1.3.1-3/debian/patches/netbeans.patch	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/patches/netbeans.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,84 +0,0 @@
-From: Markus Koschany <apo@debian.org>
-Date: Sun, 3 Jan 2016 02:48:46 +0100
-Subject: netbeans
-
-This patch is Netbeans specific and must be applied in order to use the
-html.parser module. The original .diff is located in html.parser/external.
-
-Forwarded: not-needed
----
- src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java | 3 +--
- src/nu/validator/htmlparser/impl/Tokenizer.java               | 9 +++++++++
- src/nu/validator/htmlparser/impl/TreeBuilder.java             | 4 ++--
- 3 files changed, 12 insertions(+), 4 deletions(-)
-
-diff --git a/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java b/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
-index 2612c14..95bc174 100644
---- a/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
-+++ b/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
-@@ -336,8 +336,7 @@ public class ErrorReportingTokenizer extends Tokenizer {
-     @Override protected int transition(int from, int to, boolean reconsume,
-             int pos) throws SAXException {
-         if (transitionHandler != null) {
--            transitionHandler.transition(from, to, reconsume,
--                    transitionBaseOffset + pos);
-+            transitionHandler.transition(from, to, reconsume, currentBufferGlobalOffset + pos);
-         }
-         return to;
-     }
-diff --git a/src/nu/validator/htmlparser/impl/Tokenizer.java b/src/nu/validator/htmlparser/impl/Tokenizer.java
-index d21ac9d..f676aca 100755
---- a/src/nu/validator/htmlparser/impl/Tokenizer.java
-+++ b/src/nu/validator/htmlparser/impl/Tokenizer.java
-@@ -513,6 +513,9 @@ public class Tokenizer implements Locator {
- 
-     // [NOCPP[
- 
-+    //holds the offset of the current buffer relative to the beginning of the input source
-+    protected int currentBufferGlobalOffset;
-+
-     protected LocatorImpl ampersandLocation;
- 
-     public Tokenizer(TokenHandler tokenHandler, boolean newAttributesEachTime) {
-@@ -1357,6 +1360,11 @@ public class Tokenizer implements Locator {
-         } else {
-             buffer.setStart(pos + 1);
-         }
-+
-+        if(!buffer.hasMore()) {
-+            currentBufferGlobalOffset += buffer.getEnd();
-+        }
-+
-         return lastCR;
-     }
- 
-@@ -6790,6 +6798,7 @@ public class Tokenizer implements Locator {
-         }
-         // ]NOCPP]
-         resetToDataState();
-+        currentBufferGlobalOffset = 0;
-     }
- 
-     protected void errGarbageAfterLtSlash() throws SAXException {
-diff --git a/src/nu/validator/htmlparser/impl/TreeBuilder.java b/src/nu/validator/htmlparser/impl/TreeBuilder.java
-index 9bd40e1..2570728 100644
---- a/src/nu/validator/htmlparser/impl/TreeBuilder.java
-+++ b/src/nu/validator/htmlparser/impl/TreeBuilder.java
-@@ -1517,7 +1517,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
-         end();
-     }
- 
--    public final void startTag(ElementName elementName,
-+    public void startTag(ElementName elementName,
-             HtmlAttributes attributes, boolean selfClosing) throws SAXException {
-         flushCharacters();
- 
-@@ -3140,7 +3140,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
-         }
-     }
- 
--    public final void endTag(ElementName elementName) throws SAXException {
-+    public void endTag(ElementName elementName) throws SAXException {
-         flushCharacters();
-         needToDropLF = false;
-         int eltPos;
diff -pruN 1.4+r1.3.1-3/debian/patches/no-chardet.patch 1.4+r20250916-1/debian/patches/no-chardet.patch
--- 1.4+r1.3.1-3/debian/patches/no-chardet.patch	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/patches/no-chardet.patch	2025-10-06 21:30:32.000000000 +0000
@@ -103,10 +103,10 @@ index a757503..0000000
 -    }
 -}
 diff --git a/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java b/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java
-index 553c937..0ec65ff 100755
+index 4facce4..d79d53d 100755
 --- a/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java
 +++ b/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java
-@@ -35,7 +35,6 @@ import java.nio.charset.CodingErrorAction;
+@@ -36,7 +36,6 @@ import java.nio.charset.CodingErrorAction;
  import nu.validator.htmlparser.common.ByteReadable;
  import nu.validator.htmlparser.common.Heuristics;
  import nu.validator.htmlparser.common.XmlViolationPolicy;
@@ -114,14 +114,14 @@ index 553c937..0ec65ff 100755
  import nu.validator.htmlparser.extra.IcuDetectorSniffer;
  import nu.validator.htmlparser.impl.Tokenizer;
  
-@@ -127,10 +126,6 @@ public final class HtmlInputStreamReader extends Reader implements
-             position = 0;
-             encoding = (new MetaSniffer(errorHandler, this)).sniff(this);
-             if (encoding == null
+@@ -143,10 +142,6 @@ public final class HtmlInputStreamReader extends Reader implements
+                         + encoding.getCanonName()
+                         + "\u201D used. Documents must use UTF-8.");
+             }
+-            if (encoding == null
 -                    && (heuristics == Heuristics.CHARDET || heuristics == Heuristics.ALL)) {
 -                encoding = (new ChardetSniffer(byteArray, limit)).sniff();
 -            }
--            if (encoding == null
+             if (encoding == null
                      && (heuristics == Heuristics.ICU || heuristics == Heuristics.ALL)) {
                  position = 0;
-                 encoding = (new IcuDetectorSniffer(this)).sniff();
diff -pruN 1.4+r1.3.1-3/debian/patches/series 1.4+r20250916-1/debian/patches/series
--- 1.4+r1.3.1-3/debian/patches/series	2021-01-06 00:36:09.000000000 +0000
+++ 1.4+r20250916-1/debian/patches/series	2025-10-06 21:30:32.000000000 +0000
@@ -1,2 +1 @@
-netbeans.patch
 no-chardet.patch
diff -pruN 1.4+r1.3.1-3/debian/salsa-ci.yml 1.4+r20250916-1/debian/salsa-ci.yml
--- 1.4+r1.3.1-3/debian/salsa-ci.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/debian/salsa-ci.yml	2025-10-06 21:30:32.000000000 +0000
@@ -0,0 +1,14 @@
+# This is a template from
+# https://salsa.debian.org/salsa-ci-team/pipeline/-/raw/master/recipes/salsa-ci.yml
+#
+# If this pipeline is not running at after committing and pushing this file,
+# ensure that https://salsa.debian.org/%{project_path}/-/settings/ci_cd has in
+# field "CI/CD configuration file" filename "debian/salsa-ci.yml".
+#
+# Feel free disable and enable tests to find a good balance between extensive
+# coverage and having a consistently green pipeline where failures are rare
+# enough that they are always investigated and addressed. For documeenation
+# please read https://salsa.debian.org/salsa-ci-team/pipeline
+---
+include:
+  - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
diff -pruN 1.4+r1.3.1-3/gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java 1.4+r20250916-1/gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java
--- 1.4+r1.3.1-3/gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/gwt-src/nu/validator/htmlparser/gwt/BrowserTreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2008-2009 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -133,11 +133,11 @@ class BrowserTreeBuilder extends Coalesc
             HtmlAttributes attributes) throws SAXException {
         try {
             for (int i = 0; i < attributes.getLength(); i++) {
-                String localName = attributes.getLocalName(i);
-                String uri = attributes.getURI(i);
+                String localName = attributes.getLocalNameNoBoundsCheck(i);
+                String uri = attributes.getURINoBoundsCheck(i);
                 if (!hasAttributeNS(element, uri, localName)) {
                     setAttributeNS(element, uri, localName,
-                            attributes.getValue(i));
+                            attributes.getValueNoBoundsCheck(i));
                 }
             }
         } catch (JavaScriptException e) {
@@ -238,8 +238,9 @@ class BrowserTreeBuilder extends Coalesc
         try {
             JavaScriptObject rv = createElementNS(document, ns, name);
             for (int i = 0; i < attributes.getLength(); i++) {
-                setAttributeNS(rv, attributes.getURI(i),
-                        attributes.getLocalName(i), attributes.getValue(i));
+                setAttributeNS(rv, attributes.getURINoBoundsCheck(i),
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i));
             }
 
             if ("script" == name) {
@@ -251,8 +252,9 @@ class BrowserTreeBuilder extends Coalesc
                         "http://n.validator.nu/placeholder/", "script");
                 rv = placeholder;
                 for (int i = 0; i < attributes.getLength(); i++) {
-                    setAttributeNS(rv, attributes.getURI(i),
-                            attributes.getLocalName(i), attributes.getValue(i));
+                    setAttributeNS(rv, attributes.getURINoBoundsCheck(i),
+                            attributes.getLocalNameNoBoundsCheck(i),
+                            attributes.getValueNoBoundsCheck(i));
                 }
             }
 
@@ -269,8 +271,9 @@ class BrowserTreeBuilder extends Coalesc
             JavaScriptObject rv = createElementNS(document,
                     "http://www.w3.org/1999/xhtml", "html");
             for (int i = 0; i < attributes.getLength(); i++) {
-                setAttributeNS(rv, attributes.getURI(i),
-                        attributes.getLocalName(i), attributes.getValue(i));
+                setAttributeNS(rv, attributes.getURINoBoundsCheck(i),
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i));
             }
             appendChild(document, rv);
             return rv;
@@ -373,7 +376,7 @@ class BrowserTreeBuilder extends Coalesc
     }
 
     protected void documentMode(DocumentMode mode, String publicIdentifier,
-            String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+            String systemIdentifier)
             throws SAXException {
         // document.setUserData("nu.validator.document-mode", mode, null);
     }
diff -pruN 1.4+r1.3.1-3/pom.xml 1.4+r20250916-1/pom.xml
--- 1.4+r1.3.1-3/pom.xml	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/pom.xml	2025-09-16 08:29:41.000000000 +0000
@@ -1,13 +1,52 @@
+<!--
+ * Copyright (c) 2007-2012 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the 
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>nu.validator.htmlparser</groupId>
   <artifactId>htmlparser</artifactId>
-  <packaging>jar</packaging>
-  <version>1.3.1</version>
+  <version>1.4</version>
   <name>htmlparser</name>
   <url>http://about.validator.nu/htmlparser/</url>
-  <description>The Validator.nu HTML Parser is an implementation of the HTML5 parsing algorithm in Java for applications that do not run scripts. The parser is designed to work as a drop-in replacement for the XML parser in applications that already support XHTML 1.x content with an XML parser and use SAX, DOM or XOM to interface with the parser.</description>
+  <description>The Validator.nu HTML Parser is an implementation of the HTML5 parsing algorithm in Java for applications. The parser is designed to work as a drop-in replacement for the XML parser in applications that already support XHTML 1.x content with an XML parser and use SAX, DOM or XOM to interface with the parser.</description>
+  <!--
+    Usage notes for this POM:
+
+    To build without signing, run:
+    mvn clean source:jar javadoc:jar repository:bundle-create
+    (enter 0 <return> when prompted)
+
+    To build and sign, run:
+    mvn clean source:jar javadoc:jar package gpg:sign repository:bundle-create
+    (enter 0 <return> when prompted)
+
+    This POM file is used for creating the bundle for distribution via the
+    Maven Central Repository. It is not used as part of the normal development
+    process of the parser and the maintainer of the parser (Henri Sivonen) 
+    isn't experienced in POM tweaking. If you need this POM to do something
+    that it currently does not do or do something better, you need to write
+    the changes you need yourself and contribute a patch via
+    http://bugzilla.validator.nu/
+  -->
   <developers>
     <developer>
       <id>hsivonen</id>
@@ -29,64 +68,74 @@
     </license>
   </licenses>
   <scm>
-    <connection>scm:svn:http://svn.versiondude.net/whattf/htmlparser/</connection>
+    <connection>scm:hg:http://hg.mozilla.org/projects/htmlparser/</connection>
+    <url>http://hg.mozilla.org/projects/htmlparser/</url>
   </scm>
   <build>
-    <sourceDirectory>${basedir}/src</sourceDirectory>
+    <sourceDirectory>${project.build.directory}/src</sourceDirectory>
     <testSourceDirectory>${basedir}/test-src</testSourceDirectory>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
-          <source>1.5</source>
-          <target>1.5</target>
+          <source>1.8</source>
+          <target>1.8</target>
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>1.7</version>
+        <executions>
+          <execution>
+            <id>intitialize-sources</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <delete dir="${project.build.sourceDirectory}"/>
+                <mkdir dir="${project.build.sourceDirectory}"/>
+                <copy todir="${project.build.sourceDirectory}">
+                  <fileset dir="${basedir}/src"/>
+                </copy>
+              </target>
+            </configuration>
+          </execution>
+          <execution>
+            <id>tokenizer-hotspot-workaround</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <property name="translator.sources" value="${basedir}/translator-src"/>
+                <property name="translator.classes" value="${project.build.directory}/translator-classes"/>
+                <mkdir dir="${translator.classes}"/>
+                <javac srcdir="${translator.sources}" includes="nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java" destdir="${translator.classes}" includeantruntime="false"/>
+                <java classname="nu.validator.htmlparser.generator.ApplyHotSpotWorkaround">
+                  <classpath>
+                    <pathelement location="${translator.classes}"/>
+                  </classpath>
+                  <arg value="${project.build.sourceDirectory}/nu/validator/htmlparser/impl/Tokenizer.java"/>
+                  <arg value="${project.build.sourceDirectory}/nu/validator/htmlparser/impl/HotSpotWorkaround.txt"/>
+                </java>
+              </target>
+            </configuration>
+          </execution>
+        </executions>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>rpm-maven-plugin</artifactId>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <release>1</release>
-          <copyright>The MIT License</copyright>
-          <group>Development/Java</group>
-          <workarea>/var/tmp/${project.build.finalName}</workarea>
-          <defineStatements>
-            <defineStatement>_javadir ${rpm.java.dir}</defineStatement>
-            <defineStatement>_javadocdir ${rpm.javadoc.dir}</defineStatement>
-          </defineStatements>
-          <mappings>
-            <mapping>
-              <directory>${rpm.java.dir}</directory>
-              <filemode>644</filemode>
-              <username>root</username>
-              <groupname>root</groupname>
-              <sources>
-                <source>
-                  <location>${project.build.directory}/${project.build.finalName}.jar</location>
-                </source>
-              </sources>
-            </mapping>
-            <mapping>
-              <directory>${rpm.javadoc.dir}/${project.build.finalName}</directory>
-              <filemode>644</filemode>
-              <username>root</username>
-              <groupname>root</groupname>
-              <sources>
-                <source>
-                  <location>${project.build.directory}/apidocs</location>
-                </source>
-              </sources>
-            </mapping>
-          </mappings>
-          <install>%__ln_s ${project.build.finalName}.jar %{buildroot}%{_javadir}/${project.name}.jar</install>
+          <test>Html5libTest</test>
+          <testFailureIgnore>true</testFailureIgnore> <!-- FIXME: Remove this testFailureIgnore after we have all tests passing -->
+          <additionalClasspathElements>
+            <additionalClasspathElement>${project.build.testSourceDirectory}/test/resources</additionalClasspathElement>
+          </additionalClasspathElements>
         </configuration>
       </plugin>
     </plugins>
@@ -95,7 +144,7 @@
     <dependency>
       <groupId>com.ibm.icu</groupId>
       <artifactId>icu4j</artifactId>
-      <version>4.0.1</version>
+      <version>71.1</version>
       <scope>compile</scope>
       <optional>true</optional>
     </dependency>
@@ -120,8 +169,4 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
-  <properties>
-    <rpm.java.dir>/usr/share/java</rpm.java.dir>
-    <rpm.javadoc.dir>/usr/share/javadoc</rpm.javadoc.dir>
-  </properties>
 </project>
diff -pruN 1.4+r1.3.1-3/ruby-gcj/DomUtils.java 1.4+r20250916-1/ruby-gcj/DomUtils.java
--- 1.4+r1.3.1-3/ruby-gcj/DomUtils.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/DomUtils.java	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-import java.util.HashSet;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.Element;
-
-public class DomUtils {
-
-  private static HashSet<Document> pinned_list = new HashSet<Document>();
-
-  public static synchronized void pin(Document d) {
-    pinned_list.add(d);
-  }
-
-  public static synchronized void unpin(Document d) {
-    pinned_list.remove(d);
-  }
-
-  // return all the text content contained by a single element 
-  public static void getElementContent(Element e, StringBuffer b) {
-    for (Node n = e.getFirstChild(); n!=null; n=n.getNextSibling()) {
-      if (n.getNodeType() == n.TEXT_NODE) {
-        b.append(n.getNodeValue());
-      } else if (n.getNodeType() == n.ELEMENT_NODE) {
-        getElementContent((Element) e, b);
-      }
-    }
-  }
-
-  // replace all child nodes of a given element with a single text element
-  public static void setElementContent(Element e, String s) {
-    while (e.hasChildNodes()) {
-      e.removeChild(e.getFirstChild());
-    }
-    e.appendChild(e.getOwnerDocument().createTextNode(s));
-  }
-}
diff -pruN 1.4+r1.3.1-3/ruby-gcj/README 1.4+r20250916-1/ruby-gcj/README
--- 1.4+r1.3.1-3/ruby-gcj/README	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/README	1970-01-01 00:00:00.000000000 +0000
@@ -1,65 +0,0 @@
-Disclaimer:
-
-  This code is experimental.
-
-  When some people say experimental, they mean "it may not do what it is
-  intended to do; in fact, it might even wipe out your hard drive".  I mean
-  that too.  But I mean something more than that.
-
-  In this case, experimental means that I don't even know what it is intended
-  to do.  I just have a vague vision, and I am trying out various things in
-  the hopes that one of them will work out.
-
-Vision:
-
-  My vague vision is that I would like to see HTML 5 be a success.  For me to
-  consider it to be a success, it needs to be a standard, be interoperable,
-  and be ubiquitous.
-
-  I believe that the Validator.nu parser can be used to bootstrap that
-  process.  It is written in Java.  Has been compiled into JavaScript.  Has
-  been translated into C++ based on the Mozilla libraries with the intent of
-  being included in Firefox.  It very closely tracks to the standard.
-
-  For the moment, the effort is on extending that to another language (Ruby)
-  on a single environment (i.e., Linux).  Once that is complete, intent is to
-  evaluate the results, decide what needs to be changed, and what needs to be
-  done to support other languages and environments.
-
-  The bar I'm setting for myself isn't just another SWIG generated low level
-  interface to a DOM, but rather a best of breed interface; which for Ruby
-  seems to be the one pioneered by Hpricot and adopted by Nokogiri.  Success
-  will mean passing all of the tests from one of those two parsers as well as
-  all of the HTML5 tests.
-
-Build instructions:
-
-  You'll need icu4j and chardet jars.  If you checked out and ran dldeps you
-  are already all set:
-
-    svn co http://svn.versiondude.net/whattf/build/trunk/ build
-    python build/build.py checkout dldeps
-
-  Fedora 11:
-
-    yum install ruby-devel rubygem-rake java-1.5.0-gcj-devel gcc-c++ 
-
-  Ubuntu 9.04:
-
-    apt-get install ruby ruby1.8-dev rake gcj g++
-
-    Also at this time, you need to install a jdk (e.g. sun-java6-jdk), simply
-    because the javac that comes with gcj doesn't support -sourcepath, and
-    I haven't spent the time to find a replacement.
-
-    Finally, make sure that libjaxp1.3-java is *not* installed.
-
-      http://gcc.gnu.org/ml/java/2009-06/msg00055.html
-
-  If this is done, you should be all set.
- 
-    cd htmlparser/ruby-gcj
-    rake test
-
-  If things are successful, the last lines of the output will list the
-  font attributes and values found in the test/google.html file.
diff -pruN 1.4+r1.3.1-3/ruby-gcj/Rakefile 1.4+r20250916-1/ruby-gcj/Rakefile
--- 1.4+r1.3.1-3/ruby-gcj/Rakefile	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/Rakefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,77 +0,0 @@
-deps    = ENV['deps'] || '../../dependencies'
-icu4j   = "#{deps}/icu4j-4_0.jar"
-chardet = "#{deps}/mozilla/intl/chardet/java/dist/lib/chardet.jar"
-libgcj  = Dir['/usr/share/java/libgcj*.jar'].grep(/gcj[-\d.]*jar$/).sort.last
-
-task :default => %w(headers libs Makefile validator.so)
-
-# headers
-
-hdb = 'nu/validator/htmlparser/dom/HtmlDocumentBuilder'
-task :headers => %W(headers/DomUtils.h headers/#{hdb}.h)
-
-file 'headers/DomUtils.h' => 'DomUtils.java' do |t|
-  mkdir_p %w(classes headers), :verbose => false
-  sh "javac -d classes #{t.prerequisites.first}"
-  sh "gcjh -force -o #{t.name} -cp #{libgcj}:classes DomUtils"
-end
-
-file "headers/#{hdb}.h" => "../src/#{hdb}.java" do |t|
-  mkdir_p %w(classes headers), :verbose => false
-  sh "javac -cp #{icu4j}:#{chardet} -d classes -sourcepath ../src " +
-    t.prerequisites.first
-  sh "gcjh -force -cp classes -o #{t.name} -cp #{libgcj}:classes " + 
-    hdb.gsub('/','.')
-end
-
-# libs
-
-task :libs => %w(htmlparser chardet icu).map {|name| "lib/libnu-#{name}.so"}
-
-htmlparser = Dir['../src/**/*.java'].reject {|name| name.include? '/xom/'}
-file 'lib/libnu-htmlparser.so' => htmlparser + ['DomUtils.java'] do |t|
-  mkdir_p 'lib', :verbose => false
-  sh "gcj -shared --classpath=#{icu4j}:#{chardet} -fPIC " +
-    "-o #{t.name} #{t.prerequisites.join(' ')}"
-end
-
-file 'lib/libnu-chardet.so' => chardet do |t|
-  mkdir_p 'lib', :verbose => false
-  sh "gcj -shared -fPIC -o #{t.name} #{t.prerequisites.join(' ')}"
-end
-
-file 'lib/libnu-icu.so' => icu4j do |t|
-  mkdir_p 'lib', :verbose => false
-  sh "gcj -shared -fPIC -o #{t.name} #{t.prerequisites.join(' ')}"
-end
-
-# module
-
-file 'Makefile' do
-  sh "ruby extconf.rb --with-gcj=#{libgcj}"
-end
-
-file 'validator.so' => %w(Makefile validator.cpp headers/DomUtils.h) do
-  system 'make'
-end
-
-file 'nu/validator.so' do
-  mkdir_p 'nu', :verbose => false
-  system 'ln -s -t nu ../validator.so'
-end
-
-# tasks
-
-task :test => [:default, 'nu/validator.so'] do
-  ENV['LD_LIBRARY_PATH']='lib'
-  sh 'ruby test/fonts.rb test/google.html'
-end
-
-task :clean do
-  rm_rf %W(classes lib nu mkmf.log headers/DomUtils.h headers/#{hdb}.h) + 
-    Dir['*.o'] + Dir['*.so']
-end
-
-task :clobber => :clean do
-  rm_rf %w(headers Makefile)
-end
diff -pruN 1.4+r1.3.1-3/ruby-gcj/extconf.rb 1.4+r20250916-1/ruby-gcj/extconf.rb
--- 1.4+r1.3.1-3/ruby-gcj/extconf.rb	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/extconf.rb	1970-01-01 00:00:00.000000000 +0000
@@ -1,45 +0,0 @@
-require 'mkmf'
-
-# system dependencies
-gcj  = with_config('gcj', '/usr/share/java/libgcj.jar')
-
-# headers for JAXP
-CONFIG['CC'] = 'g++'
-with_cppflags('-xc++') do
-
-  unless find_header('org/w3c/dom/Document.h', 'headers')
-  
-    `jar tf #{gcj}`.split.each do |file|
-      next unless file =~ /\.class$/
-      next unless file =~ /^(javax|org)\/(w3c|xml)/
-      next if file.include? '$'
-    
-      dest = 'headers/' + file.sub(/\.class$/,'.h')
-      name = file.sub(/\.class$/,'').gsub('/','.')
-    
-      next if File.exist? dest
-    
-      cmd = "gcjh -cp #{gcj} -o #{dest} #{name}"
-      puts cmd
-      break unless system cmd
-      system "ruby -pi -e '$_.sub!(/namespace namespace$/," +
-        "\"namespace namespace$\")' #{dest}"
-      system "ruby -pi -e '$_.sub!(/::namespace::/," +
-        "\"::namespace$::\")' #{dest}"
-    end
-
-    exit unless find_header('org/w3c/dom/Document.h', 'headers')
-  end
-
-  find_header 'nu/validator/htmlparser/dom/HtmlDocumentBuilder.h', 'headers'
-end
-
-# Java libraries
-Config::CONFIG['CC'] = 'g++ -shared'
-dir_config('nu-htmlparser', nil, 'lib')
-have_library 'nu-htmlparser'
-have_library 'nu-icu'
-have_library 'nu-chardet'
-
-# Ruby library
-create_makefile 'nu/validator'
diff -pruN 1.4+r1.3.1-3/ruby-gcj/test/domencoding.rb 1.4+r20250916-1/ruby-gcj/test/domencoding.rb
--- 1.4+r1.3.1-3/ruby-gcj/test/domencoding.rb	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/test/domencoding.rb	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-require 'nu/validator'
-
-ARGV.each do |arg|
-  puts Nu::Validator::parse(open(arg)).root.name
-end
diff -pruN 1.4+r1.3.1-3/ruby-gcj/test/fonts.rb 1.4+r20250916-1/ruby-gcj/test/fonts.rb
--- 1.4+r1.3.1-3/ruby-gcj/test/fonts.rb	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/test/fonts.rb	1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-require 'nu/validator'
-require 'open-uri'
-
-ARGV.each do |arg|
-  doc = Nu::Validator::parse(open(arg))
-  doc.xpath("//*[local-name()='font']").each do |font|
-    font.attributes.each do |name, attr|
-      puts "#{name} => #{attr.value}"
-    end
-  end
-end
diff -pruN 1.4+r1.3.1-3/ruby-gcj/test/google.html 1.4+r20250916-1/ruby-gcj/test/google.html
--- 1.4+r1.3.1-3/ruby-gcj/test/google.html	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/test/google.html	1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>window.google={kEI:"vLhASujeGpTU9QT2iOnWAQ",kEXPI:"17259",kCSIE:"17259",kHL:"en"};
-window.google.sn="webhp";window.google.timers={load:{t:{start:(new Date).getTime()}}};try{window.google.pt=window.gtbExternal&&window.gtbExternal.pageT()||window.external&&window.external.pageT}catch(b){}
-window.google.jsrt_kill=1;
-var _gjwl=location;function _gjuc(){var e=_gjwl.href.indexOf("#");if(e>=0){var a=_gjwl.href.substring(e);if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var f=a.substring(d,b);if(f.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(f=="cad=h")return 0;c=b}_gjwl.href="/search?"+a+"&cad=h";return 1}}}return 0}function _gjp(){!(window._gjwl.hash&&
-window._gjuc())&&setTimeout(_gjp,500)};
-window._gjp && _gjp();</script><style>td{line-height:.8em;}.gac_c{line-height:normal;}form{margin-bottom:20px;}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:0px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#guser{padding-bottom:7px !important;text-align:right}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb3{color:#00c !important}.gb3{text-decoration:none}</style><script>google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo4.png'" topmargin=3 marginheight=3><textarea id=csi style=display:none></textarea><iframe name=wgjf style="display:none"></iframe><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.com/imghp?hl=en&tab=wi" class=gb1>Images</a> <a href="http://video.google.com/?hl=en&tab=wv" class=gb1>Video</a> <a href="http://maps.google.com/maps?hl=en&tab=wl" class=gb1>Maps</a> <a href="http://news.google.com/nwshp?hl=en&tab=wn" class=gb1>News</a> <a href="http://www.google.com/prdhp?hl=en&tab=wf" class=gb1>Shopping</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.com/intl/en/options/" class=gb3><u>more</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNFA18XPfgb7dKnXfKz7x7g1GDH1tg">iGoogle</a> | <a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/">Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ALL/images/logo.gif" width=276 id=logo onload="window.lol&&lol()"><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""><br><input name=btnG type=submit value="Google Search"><input name=btnI type=submit value="I'm Feeling Lucky"></td><td nowrap width=25% align=left><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><font size=-1><a href="/aclk?sa=L&ai=CqVchLbNASrv7IZa68gS13KTwAc3__IMB29PoogzB2ZzZExABIMFUUK_O0JX______wFgyQaqBAlP0BcDOBRYhqw&num=1&sig=AGiWqty21CD7ixNXZILwCnH7c_3n9v2-tg&q=http://www.allforgood.org#source=hpp">Find an opportunity to volunteer</a> in your community today.</font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a></font><p><font size=-2>&copy;2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center><div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];if(google.y)google.y.first=[];google.dstr=[];google.rein=[];window.setTimeout(function(){var a=document.createElement("script");a.src="/extern_js/f/CgJlbhICdXMgACswCjggQAgsKzAOOAUsKzAYOAQsKzAlOMmIASwrMCY4BCwrMCc4ACw/1t0T7hspHT4.js";(document.getElementById("xjsd")||document.body).appendChild(a)},0);
-;google.y.first.push(function(){google.ac.i(document.f,document.f.q,'','')});google.xjs&&google.j&&google.j.xi&&google.j.xi()</script></div><script>(function(){
-function a(){google.timers.load.t.ol=(new Date).getTime();google.report&&google.report(google.timers.load,{ei:google.kEI,e:google.kCSIE})}if(window.addEventListener)window.addEventListener("load",a,false);else if(window.attachEvent)window.attachEvent("onload",a);google.timers.load.t.prt=(new Date).getTime();
-})();
-</script>
\ No newline at end of file
diff -pruN 1.4+r1.3.1-3/ruby-gcj/test/greek.xml 1.4+r20250916-1/ruby-gcj/test/greek.xml
--- 1.4+r1.3.1-3/ruby-gcj/test/greek.xml	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/test/greek.xml	1970-01-01 00:00:00.000000000 +0000
@@ -1,2 +0,0 @@
-<?xml version='1.0' encoding='iso-8859-7'?>
-<root/>
diff -pruN 1.4+r1.3.1-3/ruby-gcj/validator.cpp 1.4+r20250916-1/ruby-gcj/validator.cpp
--- 1.4+r1.3.1-3/ruby-gcj/validator.cpp	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/ruby-gcj/validator.cpp	1970-01-01 00:00:00.000000000 +0000
@@ -1,210 +0,0 @@
-#include <gcj/cni.h>
-
-#include <java/io/ByteArrayInputStream.h>
-#include <java/lang/System.h>
-#include <java/lang/Throwable.h>
-#include <java/util/ArrayList.h>
-#include <javax/xml/xpath/XPath.h>
-#include <javax/xml/xpath/XPathFactory.h>
-#include <javax/xml/xpath/XPathExpression.h>
-#include <javax/xml/xpath/XPathConstants.h>
-#include <javax/xml/parsers/DocumentBuilderFactory.h>
-#include <javax/xml/parsers/DocumentBuilder.h>
-#include <org/w3c/dom/Attr.h>
-#include <org/w3c/dom/Document.h>
-#include <org/w3c/dom/Element.h>
-#include <org/w3c/dom/NodeList.h>
-#include <org/w3c/dom/NamedNodeMap.h>
-#include <org/xml/sax/InputSource.h>
-
-#include "nu/validator/htmlparser/dom/HtmlDocumentBuilder.h"
-
-#include "DomUtils.h"
-
-#include "ruby.h"
-
-using namespace java::io;
-using namespace java::lang;
-using namespace java::util;
-using namespace javax::xml::parsers;
-using namespace javax::xml::xpath;
-using namespace nu::validator::htmlparser::dom;
-using namespace org::w3c::dom;
-using namespace org::xml::sax;
-
-static VALUE jaxp_Document;
-static VALUE jaxp_Attr;
-static VALUE jaxp_Element;
-static ID ID_read;
-static ID ID_doc;
-static ID ID_element;
-
-// convert a Java string into a Ruby string
-static VALUE j2r(String *string) {
-  if (string == NULL) return Qnil;
-  jint len = JvGetStringUTFLength(string);
-  char buf[len];
-  JvGetStringUTFRegion(string, 0, len, buf);
-  return rb_str_new(buf, len);
-}
-
-// convert a Ruby string into a Java string
-static String *r2j(VALUE string) {
-  return JvNewStringUTF(RSTRING(string)->ptr);
-}
-
-// release the Java Document associated with this Ruby Document
-static void vnu_document_free(Document *doc) {
-  DomUtils::unpin(doc);
-}
-
-// Nu::Validator::parse( string|file )
-static VALUE vnu_parse(VALUE self, VALUE input) {
-  HtmlDocumentBuilder *parser = new HtmlDocumentBuilder();
-  
-  // read file-like objects into memory.  TODO: buffer such objects
-  if (rb_respond_to(input, ID_read))
-    input = rb_funcall(input, ID_read, 0);
-
-  // convert input in to a ByteArrayInputStream
-  jbyteArray bytes = JvNewByteArray(RSTRING(input)->len);
-  memcpy(elements(bytes), RSTRING(input)->ptr, RSTRING(input)->len);
-  InputSource *source = new InputSource(new ByteArrayInputStream(bytes));
-
-  // parse, pin, and wrap
-  Document *doc = parser->parse(source);
-  DomUtils::pin(doc);
-  return Data_Wrap_Struct(jaxp_Document, NULL, vnu_document_free, doc);
-}
-
-// Jaxp::parse( string|file )
-static VALUE jaxp_parse(VALUE self, VALUE input) {
-  DocumentBuilderFactory *factory = DocumentBuilderFactory::newInstance();
-  DocumentBuilder *parser = factory->newDocumentBuilder();
-   
-  // read file-like objects into memory.  TODO: buffer such objects
-  if (rb_respond_to(input, ID_read))
-    input = rb_funcall(input, ID_read, 0);
- 
-  try {
-    jbyteArray bytes = JvNewByteArray(RSTRING(input)->len);
-    memcpy(elements(bytes), RSTRING(input)->ptr, RSTRING(input)->len);
-    Document *doc = parser->parse(new ByteArrayInputStream(bytes));
-    DomUtils::pin(doc);
-    return Data_Wrap_Struct(jaxp_Document, NULL, vnu_document_free, doc);
-  } catch (java::lang::Throwable *ex) {
-    ex->printStackTrace();
-    return Qnil;
-  }
-}
-
-
-// Nu::Validator::Document#encoding
-static VALUE jaxp_document_encoding(VALUE rdoc) {
-  Document *jdoc;
-  Data_Get_Struct(rdoc, Document, jdoc);
-  return j2r(jdoc->getXmlEncoding());
-}
-
-// Nu::Validator::Document#root
-static VALUE jaxp_document_root(VALUE rdoc) {
-  Document *jdoc;
-  Data_Get_Struct(rdoc, Document, jdoc);
-
-  Element *jelement = jdoc->getDocumentElement();
-  if (jelement==NULL) return Qnil;
-
-  VALUE relement = Data_Wrap_Struct(jaxp_Element, NULL, NULL, jelement);
-  rb_ivar_set(relement, ID_doc, rdoc);
-  return relement;
-}
-
-// Nu::Validator::Document#xpath
-static VALUE jaxp_document_xpath(VALUE rdoc, VALUE path) {
-  Document *jdoc;
-  Data_Get_Struct(rdoc, Document, jdoc);
-
-  Element *jelement = jdoc->getDocumentElement();
-  if (jelement==NULL) return Qnil;
-
-  XPath *xpath = XPathFactory::newInstance()->newXPath();
-  XPathExpression *expr = xpath->compile(r2j(path));
-  NodeList *list = (NodeList*) expr->evaluate(jdoc, XPathConstants::NODESET);
-
-  VALUE result = rb_ary_new();
-  for (int i=0; i<list->getLength(); i++) {
-    VALUE relement = Data_Wrap_Struct(jaxp_Element, NULL, NULL, list->item(i));
-    rb_ivar_set(relement, ID_doc, rdoc);
-    rb_ary_push(result, relement);
-  }
-  return result;
-}
-
-// Nu::Validator::Element#name
-static VALUE jaxp_element_name(VALUE relement) {
-  Element *jelement;
-  Data_Get_Struct(relement, Element, jelement);
-  return j2r(jelement->getNodeName());
-}
-
-// Nu::Validator::Element#attributes
-static VALUE jaxp_element_attributes(VALUE relement) {
-  Element *jelement;
-  Data_Get_Struct(relement, Element, jelement);
-  VALUE result = rb_hash_new();
-  NamedNodeMap *map = jelement->getAttributes();
-  for (int i=0; i<map->getLength(); i++) {
-    Attr *jattr = (Attr *) map->item(i);
-    VALUE rattr = Data_Wrap_Struct(jaxp_Attr, NULL, NULL, jattr);
-    rb_ivar_set(rattr, ID_element, relement);
-    rb_hash_aset(result, j2r(jattr->getName()), rattr);
-  }
-  return result;
-}
-
-// Nu::Validator::Attribute#value
-static VALUE jaxp_attribute_value(VALUE rattribute) {
-  Attr *jattribute;
-  Data_Get_Struct(rattribute, Attr, jattribute);
-  return j2r(jattribute->getValue());
-}
-
-typedef VALUE (ruby_method)(...);
-
-// Nu::Validator module initialization
-extern "C" void Init_validator() {
-  JvCreateJavaVM(NULL);
-  JvAttachCurrentThread(NULL, NULL);
-  JvInitClass(&DomUtils::class$);
-  JvInitClass(&XPathFactory::class$);
-  JvInitClass(&XPathConstants::class$);
-
-  VALUE jaxp = rb_define_module("Jaxp");
-  rb_define_singleton_method(jaxp, "parse", (ruby_method*)&jaxp_parse, 1);
-
-  VALUE nu = rb_define_module("Nu");
-  VALUE validator = rb_define_module_under(nu, "Validator");
-  rb_define_singleton_method(validator, "parse", (ruby_method*)&vnu_parse, 1);
-
-  jaxp_Document = rb_define_class_under(jaxp, "Document", rb_cObject);
-  rb_define_method(jaxp_Document, "encoding", 
-    (ruby_method*)&jaxp_document_encoding, 0);
-  rb_define_method(jaxp_Document, "root", 
-    (ruby_method*)&jaxp_document_root, 0);
-  rb_define_method(jaxp_Document, "xpath", 
-    (ruby_method*)&jaxp_document_xpath, 1);
-
-  jaxp_Element = rb_define_class_under(jaxp, "Element", rb_cObject);
-  rb_define_method(jaxp_Element, "name", 
-    (ruby_method*)&jaxp_element_name, 0);
-  rb_define_method(jaxp_Element, "attributes", 
-    (ruby_method*)&jaxp_element_attributes, 0);
-
-  jaxp_Attr = rb_define_class_under(jaxp, "Attr", rb_cObject);
-  rb_define_method(jaxp_Attr, "value", 
-    (ruby_method*)&jaxp_attribute_value, 0);
-
-  ID_read = rb_intern("read");
-  ID_doc  = rb_intern("@doc");
-  ID_element = rb_intern("@element");
-}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/CppInlineLength.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/CppInlineLength.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/CppInlineLength.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/CppInlineLength.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the 
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.annotation;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * The array member marked with this annotation will be inline.
+ * 
+ * @version $Id$
+ * @author Emilio Cobos Álvarez <emilio@crisal.io>
+ */
+@Target(ElementType.FIELD)
+public @interface CppInlineLength {
+    int value();
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/Creator.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/Creator.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/Creator.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/Creator.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Applied to an integer type to generate the unsigned variant in C++.
+ */
+package nu.validator.htmlparser.annotation;
+
+public @interface Creator {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/HtmlCreator.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/HtmlCreator.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/HtmlCreator.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/HtmlCreator.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Applied to an integer type to generate the unsigned variant in C++.
+ */
+package nu.validator.htmlparser.annotation;
+
+public @interface HtmlCreator {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/StaticLocal.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/StaticLocal.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/StaticLocal.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/StaticLocal.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2023 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the 
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.annotation;
+
+/**
+ * The local name of an element or attribute. Must be comparable with
+ * <code>==</code> (interned <code>String</code> in Java).
+ * 
+ * @version $Id$
+ * @author Emilio Cobos Álvarez <emilio@crisal.io>
+ */
+public @interface StaticLocal {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/SvgCreator.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/SvgCreator.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/SvgCreator.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/SvgCreator.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Applied to an integer type to generate the unsigned variant in C++.
+ */
+package nu.validator.htmlparser.annotation;
+
+public @interface SvgCreator {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/Unsigned.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/Unsigned.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/Unsigned.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/Unsigned.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Applied to an integer type to generate the unsigned variant in C++.
+ */
+package nu.validator.htmlparser.annotation;
+
+public @interface Unsigned {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/WeakLocal.java 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/WeakLocal.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/annotation/WeakLocal.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/annotation/WeakLocal.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2023 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the 
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.annotation;
+
+/**
+ * The local name of an element or attribute. Must be comparable with
+ * <code>==</code> (interned <code>String</code> in Java).
+ * 
+ * @version $Id$
+ * @author Emilio Cobos Álvarez <emilio@crisal.io>
+ */
+public @interface WeakLocal {
+
+}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/DoctypeExpectation.java 1.4+r20250916-1/src/nu/validator/htmlparser/common/DoctypeExpectation.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/DoctypeExpectation.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/common/DoctypeExpectation.java	1970-01-01 00:00:00.000000000 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2007 Henri Sivonen
- *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- * DEALINGS IN THE SOFTWARE.
- */
-
-package nu.validator.htmlparser.common;
-
-/**
- * Used for indicating desired behavior with legacy doctypes.
- * 
- * @version $Id$
- * @author hsivonen
- */
-public enum DoctypeExpectation {
-    /**
-     * Be a pure HTML5 parser.
-     */
-    HTML,
-    
-    /**
-     * Require the HTML 4.01 Transitional public id. Turn on HTML4-specific
-     * additional errors regardless of doctype.
-     */
-    HTML401_TRANSITIONAL,
-    
-    /**
-     * Require the HTML 4.01 Transitional public id and a system id. Turn on
-     * HTML4-specific additional errors regardless of doctype.
-     */
-    HTML401_STRICT,
-    
-    /**
-     * Treat the doctype required by HTML 5, doctypes with the HTML 4.01 Strict 
-     * public id and doctypes with the HTML 4.01 Transitional public id and a 
-     * system id as non-errors. Turn on HTML4-specific additional errors if the 
-     * public id is the HTML 4.01 Strict or Transitional public id.
-     */
-    AUTO,
-    
-    /**
-     * Never enable HTML4-specific error checks. Never report any doctype 
-     * condition as an error. (Doctype tokens in wrong places will be 
-     * reported as errors, though.) The application may decide what to log 
-     * in response to calls to <code>DocumentModeHanler</code>. This mode 
-     * in meant for doing surveys on existing content.
-     */
-    NO_DOCTYPE_ERRORS
-}
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/DocumentModeHandler.java 1.4+r20250916-1/src/nu/validator/htmlparser/common/DocumentModeHandler.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/DocumentModeHandler.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/common/DocumentModeHandler.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -39,8 +40,7 @@ public interface DocumentModeHandler {
      * @param mode the document mode
      * @param publicIdentifier the public id of the doctype or <code>null</code> if unavailable
      * @param systemIdentifier the system id of the doctype or <code>null</code> if unavailable
-     * @param html4SpecificAdditionalErrorChecks <code>true</code> if HTML 4-specific checks were enabled, <code>false</code> otherwise
      * @throws SAXException if things go wrong
      */
-    public void documentMode(DocumentMode mode, String publicIdentifier, String systemIdentifier, boolean html4SpecificAdditionalErrorChecks) throws SAXException;
+    public void documentMode(DocumentMode mode, String publicIdentifier, String systemIdentifier) throws SAXException;
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/TokenHandler.java 1.4+r20250916-1/src/nu/validator/htmlparser/common/TokenHandler.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/common/TokenHandler.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/common/TokenHandler.java	2025-09-16 08:29:41.000000000 +0000
@@ -145,6 +145,17 @@ public interface TokenHandler {
     public void zeroOriginatingReplacementCharacter() throws SAXException;
     
     /**
+     * Emits:
+     *
+     *  * U+0000 if only tokenization is being performed
+     *  * U+FFFD if tree construction is being performed also
+     *
+     * @throws SAXException
+     *             if something went wrong
+     */
+    public void zeroOrReplacementCharacter() throws SAXException;
+
+    /**
      * The end-of-file token.
      * 
      * @throws SAXException
@@ -168,4 +179,16 @@ public interface TokenHandler {
      *             if something went wrong
      */
     public boolean cdataSectionAllowed() throws SAXException;
+
+    /**
+     * Notifies the token handler of the worst case amount of data to be
+     * reported via <code>characters()</code> and
+     * <code>zeroOriginatingReplacementCharacter()</code>.
+     *
+     * @param inputLength the maximum number of chars that can be reported
+     * via <code>characters()</code> and
+     * <code>zeroOriginatingReplacementCharacter()</code> before a new call to
+     * this method.
+     */
+    public void ensureBufferSpace(int inputLength) throws SAXException;
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/dom/DOMTreeBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/dom/DOMTreeBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/dom/DOMTreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/dom/DOMTreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2008-2010 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -74,11 +74,11 @@ class DOMTreeBuilder extends CoalescingT
             HtmlAttributes attributes) throws SAXException {
         try {
             for (int i = 0; i < attributes.getLength(); i++) {
-                String localName = attributes.getLocalName(i);
-                String uri = attributes.getURI(i);
+                String localName = attributes.getLocalNameNoBoundsCheck(i);
+                String uri = attributes.getURINoBoundsCheck(i);
                 if (!element.hasAttributeNS(uri, localName)) {
                     element.setAttributeNS(uri, localName,
-                            attributes.getValue(i));
+                            attributes.getValueNoBoundsCheck(i));
                 }
             }
         } catch (DOMException e) {
@@ -151,19 +151,18 @@ class DOMTreeBuilder extends CoalescingT
 
     /**
      * 
-     * @see nu.validator.htmlparser.impl.TreeBuilder#createElement(java.lang.String,
-     *      java.lang.String, nu.validator.htmlparser.impl.HtmlAttributes)
+     * @see nu.validator.htmlparser.impl.TreeBuilder#createElement(String, String, nu.validator.htmlparser.impl.HtmlAttributes, Object)
      */
     @Override protected Element createElement(String ns, String name,
-            HtmlAttributes attributes) throws SAXException {
+            HtmlAttributes attributes, Element intendedParent) throws SAXException {
         try {
             Element rv = document.createElementNS(ns, name);
             for (int i = 0; i < attributes.getLength(); i++) {
-                rv.setAttributeNS(attributes.getURI(i),
-                        attributes.getLocalName(i), attributes.getValue(i));
-                if (attributes.getType(i) == "ID") {
-                    rv.setIdAttributeNS(null,
-                            attributes.getLocalName(i), true);
+                rv.setAttributeNS(attributes.getURINoBoundsCheck(i),
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i));
+                if (attributes.getTypeNoBoundsCheck(i) == "ID") {
+                    rv.setIdAttributeNS(null, attributes.getLocalName(i), true);
                 }
             }
             return rv;
@@ -183,8 +182,9 @@ class DOMTreeBuilder extends CoalescingT
             Element rv = document.createElementNS(
                     "http://www.w3.org/1999/xhtml", "html");
             for (int i = 0; i < attributes.getLength(); i++) {
-                rv.setAttributeNS(attributes.getURI(i),
-                        attributes.getLocalName(i), attributes.getValue(i));
+                rv.setAttributeNS(attributes.getURINoBoundsCheck(i),
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i));
             }
             document.appendChild(rv);
             return rv;
@@ -227,9 +227,9 @@ class DOMTreeBuilder extends CoalescingT
      *      java.lang.String, org.xml.sax.Attributes, java.lang.Object)
      */
     @Override protected Element createElement(String ns, String name,
-            HtmlAttributes attributes, Element form) throws SAXException {
+            HtmlAttributes attributes, Element form, Element intendedParent) throws SAXException {
         try {
-            Element rv = createElement(ns, name, attributes);
+            Element rv = createElement(ns, name, attributes, intendedParent);
             rv.setUserData("nu.validator.form-pointer", form, null);
             return rv;
         } catch (DOMException e) {
@@ -251,7 +251,7 @@ class DOMTreeBuilder extends CoalescingT
      *      java.lang.String, java.lang.String, boolean)
      */
     protected void documentMode(DocumentMode mode, String publicIdentifier,
-            String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+            String systemIdentifier)
             throws SAXException {
         document.setUserData("nu.validator.document-mode", mode, null);
     }
@@ -282,6 +282,26 @@ class DOMTreeBuilder extends CoalescingT
         return rv;
     }
 
+    @Override
+    protected Element createAndInsertFosterParentedElement(String ns, String name,
+            HtmlAttributes attributes, Element table, Element stackParent) throws SAXException {
+        try {
+            Node parent = table.getParentNode();
+            Element child = createElement(ns, name, attributes, parent != null ? (Element) parent : stackParent);
+
+            if (parent != null) { // always an element if not null
+                parent.insertBefore(child, table);
+            } else {
+                stackParent.appendChild(child);
+            }
+
+            return child;
+        } catch (DOMException e) {
+            fatal(e);
+            throw new RuntimeException("Unreachable");
+        }
+    }
+
     @Override protected void insertFosterParentedCharacters(String text,
             Element table, Element stackParent) throws SAXException {
         try {
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/dom/HtmlDocumentBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/dom/HtmlDocumentBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/dom/HtmlDocumentBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/dom/HtmlDocumentBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2007-2008 Mozilla Foundation
+ * Copyright (c) 2007-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -34,7 +34,6 @@ import javax.xml.parsers.DocumentBuilder
 import javax.xml.parsers.ParserConfigurationException;
 
 import nu.validator.htmlparser.common.CharacterHandler;
-import nu.validator.htmlparser.common.DoctypeExpectation;
 import nu.validator.htmlparser.common.DocumentModeHandler;
 import nu.validator.htmlparser.common.Heuristics;
 import nu.validator.htmlparser.common.TokenHandler;
@@ -122,8 +121,6 @@ public class HtmlDocumentBuilder extends
     
     private DocumentModeHandler documentModeHandler = null;
 
-    private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML;
-
     private boolean checkingNormalization = false;
 
     private boolean scriptingEnabled = false;
@@ -140,8 +137,6 @@ public class HtmlDocumentBuilder extends
 
     private XmlViolationPolicy streamabilityViolationPolicy = XmlViolationPolicy.ALLOW;
     
-    private boolean html4ModeCompatibleWithXhtml1Schemata = false;
-
     private boolean mappingLangToXmlLang = false;
 
     private XmlViolationPolicy xmlnsPolicy = XmlViolationPolicy.FATAL;
@@ -223,14 +218,12 @@ public class HtmlDocumentBuilder extends
             this.driver.setCommentPolicy(commentPolicy);
             this.driver.setContentNonXmlCharPolicy(contentNonXmlCharPolicy);
             this.driver.setContentSpacePolicy(contentSpacePolicy);
-            this.driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
             this.driver.setMappingLangToXmlLang(mappingLangToXmlLang);
             this.driver.setXmlnsPolicy(xmlnsPolicy);
             this.driver.setHeuristics(heuristics);
             for (CharacterHandler characterHandler : characterHandlers) {
                 this.driver.addCharacterHandler(characterHandler);
             }
-            this.treeBuilder.setDoctypeExpectation(doctypeExpectation);
             this.treeBuilder.setDocumentModeHandler(documentModeHandler);
             this.treeBuilder.setScriptingEnabled(scriptingEnabled);
             this.treeBuilder.setReportingDoctype(reportingDoctype);
@@ -321,10 +314,11 @@ public class HtmlDocumentBuilder extends
     }
 
     /**
-     * Parses a document fragment from a SAX <code>InputSource</code>.
+     * Parses a document fragment from a SAX <code>InputSource</code> with 
+     * an HTML element as the fragment context.
      * @param is the source
-     * @param context the context element name
-     * @return the doc
+     * @param context the context element name (HTML namespace assumed)
+     * @return the document fragment
      * @throws SAXException if stuff goes wrong
      * @throws IOException if IO goes wrong
      */
@@ -336,6 +330,23 @@ public class HtmlDocumentBuilder extends
     }
 
     /**
+     * Parses a document fragment from a SAX <code>InputSource</code>.
+     * @param is the source
+     * @param contextLocal the local name of the context element
+     * @param contextNamespace the namespace of the context element
+     * @return the document fragment
+     * @throws SAXException if stuff goes wrong
+     * @throws IOException if IO goes wrong
+     */
+    public DocumentFragment parseFragment(InputSource is, String contextLocal,
+            String contextNamespace) throws IOException, SAXException {
+        treeBuilder.setFragmentContext(contextLocal.intern(),
+                contextNamespace.intern(), null, false);
+        tokenize(is);
+        return treeBuilder.getDocumentFragment();
+    }
+
+    /**
      * Sets the entity resolver for URI-only inputs.
      * @param resolver the resolver
      * @see javax.xml.parsers.DocumentBuilder#setEntityResolver(org.xml.sax.EntityResolver)
@@ -351,7 +362,9 @@ public class HtmlDocumentBuilder extends
      */
     @Override public void setErrorHandler(ErrorHandler errorHandler) {
         treeBuilder.setErrorHandler(errorHandler);
-        driver.setErrorHandler(errorHandler);
+        if (driver != null) {
+            driver.setErrorHandler(errorHandler);
+        }
     }
 
     public void setTransitionHander(TransitionHandler handler) {
@@ -438,29 +451,6 @@ public class HtmlDocumentBuilder extends
     }
 
     /**
-     * Returns the doctype expectation.
-     * 
-     * @return the doctypeExpectation
-     */
-    public DoctypeExpectation getDoctypeExpectation() {
-        return doctypeExpectation;
-    }
-
-    /**
-     * Sets the doctype expectation.
-     * 
-     * @param doctypeExpectation
-     *            the doctypeExpectation to set
-     * @see nu.validator.htmlparser.impl.TreeBuilder#setDoctypeExpectation(nu.validator.htmlparser.common.DoctypeExpectation)
-     */
-    public void setDoctypeExpectation(DoctypeExpectation doctypeExpectation) {
-        this.doctypeExpectation = doctypeExpectation;
-        if (treeBuilder != null) {
-            treeBuilder.setDoctypeExpectation(doctypeExpectation);
-        }
-    }
-
-    /**
      * Returns the document mode handler.
      * 
      * @return the documentModeHandler
@@ -502,19 +492,6 @@ public class HtmlDocumentBuilder extends
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * @param html4ModeCompatibleWithXhtml1Schemata
-     */
-    public void setHtml4ModeCompatibleWithXhtml1Schemata(
-            boolean html4ModeCompatibleWithXhtml1Schemata) {
-        this.html4ModeCompatibleWithXhtml1Schemata = html4ModeCompatibleWithXhtml1Schemata;
-        if (driver != null) {
-            driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
-        }
-    }
-
-    /**
      * Returns the <code>Locator</code> during parse.
      * @return the <code>Locator</code>
      */
@@ -523,16 +500,6 @@ public class HtmlDocumentBuilder extends
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * 
-     * @return the html4ModeCompatibleWithXhtml1Schemata
-     */
-    public boolean isHtml4ModeCompatibleWithXhtml1Schemata() {
-        return html4ModeCompatibleWithXhtml1Schemata;
-    }
-
-    /**
      * Whether <code>lang</code> is mapped to <code>xml:lang</code>.
      * @param mappingLangToXmlLang
      * @see nu.validator.htmlparser.impl.Tokenizer#setMappingLangToXmlLang(boolean)
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/AttributeName.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/AttributeName.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/AttributeName.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/AttributeName.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,35 +1,42 @@
 /*
- * Copyright (c) 2008-2011 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
 
+import nu.validator.htmlparser.annotation.CppInlineLength;
+import nu.validator.htmlparser.annotation.Inline;
 import nu.validator.htmlparser.annotation.Local;
+import nu.validator.htmlparser.annotation.StaticLocal;
+import nu.validator.htmlparser.annotation.WeakLocal;
 import nu.validator.htmlparser.annotation.NoLength;
 import nu.validator.htmlparser.annotation.NsUri;
 import nu.validator.htmlparser.annotation.Prefix;
 import nu.validator.htmlparser.annotation.QName;
-import nu.validator.htmlparser.annotation.Virtual;
+import nu.validator.htmlparser.annotation.Unsigned;
 import nu.validator.htmlparser.common.Interner;
 
 public final class AttributeName
@@ -51,7 +58,7 @@ public final class AttributeName
     public static final int BOOLEAN = (1 << 6);
 
     // ]NOCPP]
-    
+
     /**
      * An array representing no namespace regardless of namespace mode (HTML,
      * SVG, MathML, lang-mapping HTML) used.
@@ -167,98 +174,32 @@ public final class AttributeName
 
     // ]NOCPP]
 
-    /**
-     * An initialization helper for having a one name in the SVG mode and
-     * another name in the other modes.
-     * 
-     * @param name
-     *            the name for the non-SVG modes
-     * @param camel
-     *            the name for the SVG mode
-     * @return the initialized name array
-     */
-    private static @NoLength @Local String[] SVG_DIFFERENT(@Local String name,
-            @Local String camel) {
-        @NoLength @Local String[] arr = new String[4];
-        arr[0] = name;
-        arr[1] = name;
-        arr[2] = camel;
-        // [NOCPP[
-        arr[3] = name;
-        // ]NOCPP]
-        return arr;
-    }
-
-    /**
-     * An initialization helper for having a one name in the MathML mode and
-     * another name in the other modes.
-     * 
-     * @param name
-     *            the name for the non-MathML modes
-     * @param camel
-     *            the name for the MathML mode
-     * @return the initialized name array
-     */
-    private static @NoLength @Local String[] MATH_DIFFERENT(@Local String name,
-            @Local String camel) {
-        @NoLength @Local String[] arr = new String[4];
-        arr[0] = name;
-        arr[1] = camel;
-        arr[2] = name;
-        // [NOCPP[
-        arr[3] = name;
-        // ]NOCPP]
-        return arr;
-    }
-
-    /**
-     * An initialization helper for having a different local name in the HTML
-     * mode and the SVG and MathML modes.
-     * 
-     * @param name
-     *            the name for the HTML mode
-     * @param suffix
-     *            the name for the SVG and MathML modes
-     * @return the initialized name array
-     */
-    private static @NoLength @Local String[] COLONIFIED_LOCAL(
-            @Local String name, @Local String suffix) {
-        @NoLength @Local String[] arr = new String[4];
-        arr[0] = name;
-        arr[1] = suffix;
-        arr[2] = suffix;
-        // [NOCPP[
-        arr[3] = name;
-        // ]NOCPP]
-        return arr;
-    }
+    @Inline static int levelOrderBinarySearch(int[] data, int key) {
+        int n = data.length;
+        int i = 0;
+
+        while (i < n) {
+            int val = data[i];
+            if (val < key) {
+                i = 2 * i + 2;
+            } else if (val > key) {
+                i = 2 * i + 1;
+            } else {
+                return i;
+            }
+        }
 
-    /**
-     * An initialization helper for having the same local name in all modes.
-     * 
-     * @param name
-     *            the name
-     * @return the initialized name array
-     */
-    static @NoLength @Local String[] SAME_LOCAL(@Local String name) {
-        @NoLength @Local String[] arr = new String[4];
-        arr[0] = name;
-        arr[1] = name;
-        arr[2] = name;
-        // [NOCPP[
-        arr[3] = name;
-        // ]NOCPP]
-        return arr;
+        return -1;
     }
 
     /**
      * Returns an attribute name by buffer.
-     * 
+     *
      * <p>
      * C++ ownership: The return value is either released by the caller if the
      * attribute is a duplicate or the ownership is transferred to
      * HtmlAttributes and released upon clearing or destroying that object.
-     * 
+     *
      * @param buf
      *            the buffer
      * @param offset
@@ -269,61 +210,62 @@ public final class AttributeName
      *            whether to check ncnameness
      * @return an <code>AttributeName</code> corresponding to the argument data
      */
-    static AttributeName nameByBuffer(@NoLength char[] buf, int offset,
-            int length
-            // [NOCPP[
-            , boolean checkNcName
-            // ]NOCPP]
-            , Interner interner) {
+    @Inline static AttributeName nameByBuffer(@NoLength char[] buf,
+            int length, Interner interner) {
         // XXX deal with offset
-        int hash = AttributeName.bufToHash(buf, length);
-        int index = Arrays.binarySearch(AttributeName.ATTRIBUTE_HASHES, hash);
+        @Unsigned int hash = AttributeName.bufToHash(buf, length);
+        int[] hashes;
+        hashes = AttributeName.ATTRIBUTE_HASHES;
+        int index = levelOrderBinarySearch(hashes, hash);
         if (index < 0) {
-            return AttributeName.createAttributeName(
-                    Portability.newLocalNameFromBuffer(buf, offset, length,
-                            interner)
-                    // [NOCPP[
-                    , checkNcName
-            // ]NOCPP]
-            );
-        } else {
-            AttributeName attributeName = AttributeName.ATTRIBUTE_NAMES[index];
-            @Local String name = attributeName.getLocal(AttributeName.HTML);
-            if (!Portability.localEqualsBuffer(name, buf, offset, length)) {
-                return AttributeName.createAttributeName(
-                        Portability.newLocalNameFromBuffer(buf, offset, length,
-                                interner)
-                        // [NOCPP[
-                        , checkNcName
-                // ]NOCPP]
-                );
-            }
-            return attributeName;
+            return null;
         }
+        AttributeName attributeName = AttributeName.ATTRIBUTE_NAMES[index];
+        @Local String name = attributeName.getLocal(0);
+        if (!Portability.localEqualsBuffer(name, buf, length)) {
+            return null;
+        }
+        return attributeName;
     }
 
     /**
-     * This method has to return a unique integer for each well-known
+     * This method has to return a unique positive integer for each well-known
      * lower-cased attribute name.
-     * 
+     *
      * @param buf
      * @param len
      * @return
      */
-    private static int bufToHash(@NoLength char[] buf, int len) {
-        int hash2 = 0;
-        int hash = len;
-        hash <<= 5;
-        hash += buf[0] - 0x60;
-        int j = len;
-        for (int i = 0; i < 4 && j > 0; i++) {
-            j--;
-            hash <<= 5;
-            hash += buf[j] - 0x60;
-            hash2 <<= 6;
-            hash2 += buf[i] - 0x5F;
+    @Inline private static @Unsigned int bufToHash(@NoLength char[] buf, int length) {
+        @Unsigned int len = length;
+        @Unsigned int first = buf[0];
+        first <<= 19;
+        @Unsigned int second = 1 << 23;
+        @Unsigned int third = 0;
+        @Unsigned int fourth = 0;
+        @Unsigned int fifth = 0;
+        @Unsigned int sixth = 0;
+        if (length >= 4) {
+            second = buf[length - 4];
+            second <<= 4;
+            third = buf[1];
+            third <<= 9;
+            fourth = buf[length - 2];
+            fourth <<= 14;
+            fifth = buf[3];
+            fifth <<= 24;
+            sixth = buf[length - 1];
+            sixth <<= 11;
+        } else if (length == 3) {
+            second = buf[1];
+            second <<= 4;
+            third = buf[2];
+            third <<= 9;
+        } else if (length == 2) {
+            second = buf[1];
+            second <<= 24;
         }
-        return hash ^ hash2;
+        return len + first + second + third + fourth + fifth + sixth;
     }
 
     /**
@@ -353,17 +295,22 @@ public final class AttributeName
     /**
      * The namespaces indexable by mode.
      */
-    private final @NsUri @NoLength String[] uri;
+    private final @CppInlineLength(3) @NsUri @NoLength String[] uri;
 
     /**
      * The local names indexable by mode.
+     *
+     * These are weak because they're either all static, or
+     * all the same, in wich case we just need to take one reference.
      */
-    private final @Local @NoLength String[] local;
+    private final @CppInlineLength(3) @WeakLocal @NoLength String[] local;
 
     /**
      * The prefixes indexably by mode.
      */
-    private final @Prefix @NoLength String[] prefix;
+    private final @CppInlineLength(3) @Prefix @NoLength String[] prefix;
+
+    // CPPONLY: private final boolean custom;
 
     // [NOCPP[
 
@@ -378,7 +325,7 @@ public final class AttributeName
 
     /**
      * The startup-time constructor.
-     * 
+     *
      * @param uri
      *            the namespace
      * @param local
@@ -390,91 +337,102 @@ public final class AttributeName
      * @param xmlns
      *            whether this is an xmlns attribute
      */
-    protected AttributeName(@NsUri @NoLength String[] uri,
-            @Local @NoLength String[] local, @Prefix @NoLength String[] prefix
+    private AttributeName(@NsUri @NoLength String[] uri,
+            @StaticLocal String html, @StaticLocal String mathml, @StaticLocal String svg,
+            // [NOCPP[
+            @StaticLocal String htmlLang,
+            // ]NOCPP]
+            @Prefix @NoLength String[] prefix
             // [NOCPP[
             , int flags
-    // ]NOCPP]        
+            // ]NOCPP]
     ) {
         this.uri = uri;
-        this.local = local;
         this.prefix = prefix;
         // [NOCPP[
-        this.qName = COMPUTE_QNAME(local, prefix);
+        this.local = new String[4];
         this.flags = flags;
         // ]NOCPP]
+        this.local[HTML] = html;
+        this.local[MATHML] = mathml;
+        this.local[SVG] = svg;
+        // [NOCPP[
+        this.local[HTML_LANG] = htmlLang;
+        this.qName = COMPUTE_QNAME(local, prefix);
+        // ]NOCPP]
+        // CPPONLY: this.custom = false;
     }
 
+    // CPPONLY: public AttributeName() {
+    // CPPONLY:     this.uri = ALL_NO_NS;
+    // CPPONLY:     this.local[0] = null;
+    // CPPONLY:     this.local[1] = null;
+    // CPPONLY:     this.local[2] = null;
+    // CPPONLY:     this.prefix = ALL_NO_PREFIX;
+    // CPPONLY:     this.custom = true;
+    // CPPONLY: }
+    // CPPONLY:
+    // CPPONLY: @Inline public boolean isInterned() {
+    // CPPONLY:     return !custom;
+    // CPPONLY: }
+    // CPPONLY:
+    // CPPONLY: @Inline public void setNameForNonInterned(@Local String name) {
+    // CPPONLY:     assert custom;
+    // CPPONLY:     Portability.addrefIfNonNull(name);
+    // CPPONLY:     Portability.releaseIfNonNull(local[0]);
+    // CPPONLY:     local[0] = name;
+    // CPPONLY:     local[1] = name;
+    // CPPONLY:     local[2] = name;
+    // CPPONLY: }
+
     /**
      * Creates an <code>AttributeName</code> for a local name.
-     * 
+     *
      * @param name
      *            the name
      * @param checkNcName
      *            whether to check ncnameness
      * @return an <code>AttributeName</code>
      */
-    private static AttributeName createAttributeName(@Local String name
     // [NOCPP[
-            , boolean checkNcName
-    // ]NOCPP]
-    ) {
-        // [NOCPP[
+    static AttributeName createAttributeName(@Local String name, boolean checkNcName) {
         int flags = NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG;
         if (name.startsWith("xmlns:")) {
             flags = IS_XMLNS;
         } else if (checkNcName && !NCName.isNCName(name)) {
             flags = 0;
         }
-        // ]NOCPP]
-        return new AttributeName(AttributeName.ALL_NO_NS,
-                AttributeName.SAME_LOCAL(name), ALL_NO_PREFIX, flags);
-    }
-
-    /**
-     * Deletes runtime-allocated instances in C++.
-     */
-    @Virtual void release() {
-        // No-op in Java.
-        // Implement as |delete this;| in subclass.
+        return new AttributeName(ALL_NO_NS,
+                name, name, name, name, ALL_NO_PREFIX, flags);
     }
+    // ]NOCPP]
 
     /**
      * The C++ destructor.
      */
     @SuppressWarnings("unused") private void destructor() {
-        Portability.deleteArray(local);
-    }
-
-    /**
-     * Clones the attribute using an interner. Returns <code>this</code> in Java
-     * and for non-dynamic instances in C++.
-     * 
-     * @param interner
-     *            an interner
-     * @return a clone
-     */
-    @Virtual public AttributeName cloneAttributeName(Interner interner) {
-        return this;
+        // CPPONLY: if (custom) {
+        // CPPONLY:     Portability.releaseIfNonNull(local[0]);
+        // CPPONLY: }
     }
 
     // [NOCPP[
     /**
      * Creator for use when the XML violation policy requires an attribute name
      * to be changed.
-     * 
+     *
      * @param name
      *            the name of the attribute to create
      */
     static AttributeName create(@Local String name) {
         return new AttributeName(AttributeName.ALL_NO_NS,
-                AttributeName.SAME_LOCAL(name), ALL_NO_PREFIX,
+                name, name, name, name, ALL_NO_PREFIX,
                 NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     }
 
     /**
      * Queries whether this name is an XML 1.0 4th ed. NCName.
-     * 
+     *
      * @param mode
      *            the SVG/MathML/HTML mode
      * @return <code>true</code> if this is an NCName in the given mode
@@ -485,17 +443,17 @@ public final class AttributeName
 
     /**
      * Queries whether this is an <code>xmlns</code> attribute.
-     * 
+     *
      * @return <code>true</code> if this is an <code>xmlns</code> attribute
      */
     public boolean isXmlns() {
         return (flags & IS_XMLNS) != 0;
     }
-        
+
     /**
      * Queries whether this attribute has a case-folded value in the HTML4 mode
      * of the parser.
-     * 
+     *
      * @return <code>true</code> if the value is case-folded
      */
     boolean isCaseFolded() {
@@ -545,7 +503,7 @@ public final class AttributeName
 //                builder.append(" | ");
 //            }
 //            builder.append("NCNAME_HTML");
-//        }            
+//        }
 //        if ((flags & NCNAME_FOREIGN) != 0) {
 //            if (builder.length() != 0) {
 //                builder.append(" | ");
@@ -618,25 +576,7 @@ public final class AttributeName
 //    }
 //
 //    private String formatLocal() {
-//        if (local[0] == local[1] && local[0] == local[3]
-//                && local[0] != local[2]) {
-//            return "SVG_DIFFERENT(\"" + local[0] + "\", \"" + local[2] + "\")";
-//        }
-//        if (local[0] == local[2] && local[0] == local[3]
-//                && local[0] != local[1]) {
-//            return "MATH_DIFFERENT(\"" + local[0] + "\", \"" + local[1] + "\")";
-//        }
-//        if (local[0] == local[3] && local[1] == local[2]
-//                && local[0] != local[1]) {
-//            return "COLONIFIED_LOCAL(\"" + local[0] + "\", \"" + local[1]
-//                    + "\")";
-//        }
-//        for (int i = 1; i < local.length; i++) {
-//            if (local[0] != local[i]) {
-//                throw new IllegalStateException();
-//            }
-//        }
-//        return "SAME_LOCAL(\"" + local[0] + "\")";
+//        return "\"" + local[0] + "\", \"" + local[1] + "\", \"" + local[2] + "\", \"" + local[3] + "\"";
 //    }
 //
 //    private String formatNs() {
@@ -681,20 +621,46 @@ public final class AttributeName
 //        return bufToHash(name.toCharArray(), name.length());
 //    }
 //
+//    private static void fillLevelOrderArray(List<AttributeName> sorted, int depth,
+//                                            int rootIdx, AttributeName[] levelOrder) {
+//        if (rootIdx >= levelOrder.length) {
+//            return;
+//        }
+//
+//        if (depth > 0) {
+//            fillLevelOrderArray(sorted, depth - 1, rootIdx * 2 + 1, levelOrder);
+//        }
+//
+//        if (!sorted.isEmpty()) {
+//            levelOrder[rootIdx] = sorted.remove(0);
+//        }
+//
+//        if (depth > 0) {
+//            fillLevelOrderArray(sorted, depth - 1, rootIdx * 2 + 2, levelOrder);
+//        }
+//    }
+//
 //    /**
-//     * Regenerate self
-//     * 
+//     * Regenerate self with: mvn compile exec:java -Dexec.mainClass="nu.validator.htmlparser.impl.AttributeName"
+//     *
 //     * @param args
 //     */
 //    public static void main(String[] args) {
 //        Arrays.sort(ATTRIBUTE_NAMES);
-//        for (int i = 1; i < ATTRIBUTE_NAMES.length; i++) {
-//            if (ATTRIBUTE_NAMES[i].hash() == ATTRIBUTE_NAMES[i - 1].hash()) {
-//                System.err.println("Hash collision: "
-//                        + ATTRIBUTE_NAMES[i].getLocal(HTML) + ", "
-//                        + ATTRIBUTE_NAMES[i - 1].getLocal(HTML));
+//        for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
+//            int hash = ATTRIBUTE_NAMES[i].hash();
+//            if (hash < 0) {
+//                System.err.println("Negative hash: " + ATTRIBUTE_NAMES[i].local[0]);
 //                return;
 //            }
+//            for (int j = i + 1; j < ATTRIBUTE_NAMES.length; j++) {
+//                if (hash == ATTRIBUTE_NAMES[j].hash()) {
+//                    System.err.println(
+//                            "Hash collision: " + ATTRIBUTE_NAMES[i].local[0] + ", "
+//                                    + ATTRIBUTE_NAMES[j].local[0]);
+//                    return;
+//                }
+//            }
 //        }
 //        for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
 //            AttributeName att = ATTRIBUTE_NAMES[i];
@@ -702,1767 +668,1554 @@ public final class AttributeName
 //                    + att.constName() + " = new AttributeName" + att.toString()
 //                    + ";");
 //        }
+//
+//        LinkedList<AttributeName> sortedNames = new LinkedList<AttributeName>();
+//        Collections.addAll(sortedNames, ATTRIBUTE_NAMES);
+//        AttributeName[] levelOrder = new AttributeName[ATTRIBUTE_NAMES.length];
+//        int bstDepth = (int) Math.ceil(Math.log(ATTRIBUTE_NAMES.length) / Math.log(2));
+//        fillLevelOrderArray(sortedNames, bstDepth, 0, levelOrder);
+//
 //        System.out.println("private final static @NoLength AttributeName[] ATTRIBUTE_NAMES = {");
-//        for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
-//            AttributeName att = ATTRIBUTE_NAMES[i];
+//        for (int i = 0; i < levelOrder.length; i++) {
+//            AttributeName att = levelOrder[i];
 //            System.out.println(att.constName() + ",");
 //        }
 //        System.out.println("};");
 //        System.out.println("private final static int[] ATTRIBUTE_HASHES = {");
-//        for (int i = 0; i < ATTRIBUTE_NAMES.length; i++) {
-//            AttributeName att = ATTRIBUTE_NAMES[i];
+//        for (int i = 0; i < levelOrder.length; i++) {
+//            AttributeName att = levelOrder[i];
 //            System.out.println(Integer.toString(att.hash()) + ",");
 //        }
 //        System.out.println("};");
 //    }
 
     // START GENERATED CODE
-    public static final AttributeName D = new AttributeName(ALL_NO_NS, SAME_LOCAL("d"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName K = new AttributeName(ALL_NO_NS, SAME_LOCAL("k"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName R = new AttributeName(ALL_NO_NS, SAME_LOCAL("r"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName X = new AttributeName(ALL_NO_NS, SAME_LOCAL("x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName Z = new AttributeName(ALL_NO_NS, SAME_LOCAL("z"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BY = new AttributeName(ALL_NO_NS, SAME_LOCAL("by"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CX = new AttributeName(ALL_NO_NS, SAME_LOCAL("cx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CY = new AttributeName(ALL_NO_NS, SAME_LOCAL("cy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DX = new AttributeName(ALL_NO_NS, SAME_LOCAL("dx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DY = new AttributeName(ALL_NO_NS, SAME_LOCAL("dy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName G2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("g2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName G1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("g1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FX = new AttributeName(ALL_NO_NS, SAME_LOCAL("fx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName K4 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k4"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName K2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName K3 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k3"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName K1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("k1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ID = new AttributeName(ALL_NO_NS, SAME_LOCAL("id"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName IN = new AttributeName(ALL_NO_NS, SAME_LOCAL("in"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName U2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("u2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName U1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("u1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RT = new AttributeName(ALL_NO_NS, SAME_LOCAL("rt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RX = new AttributeName(ALL_NO_NS, SAME_LOCAL("rx"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RY = new AttributeName(ALL_NO_NS, SAME_LOCAL("ry"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TO = new AttributeName(ALL_NO_NS, SAME_LOCAL("to"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName Y2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("y2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName Y1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("y1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName X1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("x1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName X2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("x2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ALT = new AttributeName(ALL_NO_NS, SAME_LOCAL("alt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DIR = new AttributeName(ALL_NO_NS, SAME_LOCAL("dir"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName DUR = new AttributeName(ALL_NO_NS, SAME_LOCAL("dur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName END = new AttributeName(ALL_NO_NS, SAME_LOCAL("end"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("for"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName IN2 = new AttributeName(ALL_NO_NS, SAME_LOCAL("in2"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("max"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("min"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("low"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REL = new AttributeName(ALL_NO_NS, SAME_LOCAL("rel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REV = new AttributeName(ALL_NO_NS, SAME_LOCAL("rev"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("src"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName AXIS = new AttributeName(ALL_NO_NS, SAME_LOCAL("axis"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ABBR = new AttributeName(ALL_NO_NS, SAME_LOCAL("abbr"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BBOX = new AttributeName(ALL_NO_NS, SAME_LOCAL("bbox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CITE = new AttributeName(ALL_NO_NS, SAME_LOCAL("cite"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("code"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BIAS = new AttributeName(ALL_NO_NS, SAME_LOCAL("bias"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("cols"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLIP = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CHAR = new AttributeName(ALL_NO_NS, SAME_LOCAL("char"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BASE = new AttributeName(ALL_NO_NS, SAME_LOCAL("base"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EDGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("edge"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DATA = new AttributeName(ALL_NO_NS, SAME_LOCAL("data"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FILL = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FROM = new AttributeName(ALL_NO_NS, SAME_LOCAL("from"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("form"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("face"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HIGH = new AttributeName(ALL_NO_NS, SAME_LOCAL("high"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("href"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OPEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("open"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ICON = new AttributeName(ALL_NO_NS, SAME_LOCAL("icon"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("name"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MASK = new AttributeName(ALL_NO_NS, SAME_LOCAL("mask"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("link"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LANG = new AttributeName(LANG_NS, SAME_LOCAL("lang"), LANG_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LIST = new AttributeName(ALL_NO_NS, SAME_LOCAL("list"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("type"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName WHEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("when"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName WRAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("wrap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEXT = new AttributeName(ALL_NO_NS, SAME_LOCAL("text"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATH = new AttributeName(ALL_NO_NS, SAME_LOCAL("path"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PING = new AttributeName(ALL_NO_NS, SAME_LOCAL("ping"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REFX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("refx", "refX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REFY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("refy", "refY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("size"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SEED = new AttributeName(ALL_NO_NS, SAME_LOCAL("seed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ROWS = new AttributeName(ALL_NO_NS, SAME_LOCAL("rows"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("span"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STEP = new AttributeName(ALL_NO_NS, SAME_LOCAL("step"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName ROLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("role"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("xref"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ASYNC = new AttributeName(ALL_NO_NS, SAME_LOCAL("async"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ALINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("alink"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("align"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName CLOSE = new AttributeName(ALL_NO_NS, SAME_LOCAL("close"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLASS = new AttributeName(ALL_NO_NS, SAME_LOCAL("class"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLEAR = new AttributeName(ALL_NO_NS, SAME_LOCAL("clear"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName BEGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("begin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DEPTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("depth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DEFER = new AttributeName(ALL_NO_NS, SAME_LOCAL("defer"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName FENCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fence"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FRAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("frame"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName ISMAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ismap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ONEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("onend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName INDEX = new AttributeName(ALL_NO_NS, SAME_LOCAL("index"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("order"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OTHER = new AttributeName(ALL_NO_NS, SAME_LOCAL("other"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncut"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NARGS = new AttributeName(ALL_NO_NS, SAME_LOCAL("nargs"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MEDIA = new AttributeName(ALL_NO_NS, SAME_LOCAL("media"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LABEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("label"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LOCAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("local"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName WIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("width"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TITLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("title"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VLINK = new AttributeName(ALL_NO_NS, SAME_LOCAL("vlink"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VALUE = new AttributeName(ALL_NO_NS, SAME_LOCAL("value"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SLOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("slope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SHAPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("shape"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName SCOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName SCALE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scale"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPEED = new AttributeName(ALL_NO_NS, SAME_LOCAL("speed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("style"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RULES = new AttributeName(ALL_NO_NS, SAME_LOCAL("rules"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName STEMH = new AttributeName(ALL_NO_NS, SAME_LOCAL("stemh"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STEMV = new AttributeName(ALL_NO_NS, SAME_LOCAL("stemv"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName START = new AttributeName(ALL_NO_NS, SAME_LOCAL("start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XMLNS = new AttributeName(XMLNS_NS, SAME_LOCAL("xmlns"), ALL_NO_PREFIX, IS_XMLNS);
-    public static final AttributeName ACCEPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accept"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ASCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("ascent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACTIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("active"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ALTIMG = new AttributeName(ALL_NO_NS, SAME_LOCAL("altimg"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("action"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("border"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CURSOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("cursor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COORDS = new AttributeName(ALL_NO_NS, SAME_LOCAL("coords"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FILTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("filter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FORMAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("format"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HIDDEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("hidden"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("hspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmove"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAG = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondrag"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ORIGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("origin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONZOOM = new AttributeName(ALL_NO_NS, SAME_LOCAL("onzoom"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONHELP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onhelp"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSTOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onstop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDROP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondrop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBLUR = new AttributeName(ALL_NO_NS, SAME_LOCAL("onblur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OBJECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("object"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OFFSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("offset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ORIENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("orient"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCOPY = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncopy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NOWRAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("nowrap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName NOHREF = new AttributeName(ALL_NO_NS, SAME_LOCAL("nohref"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName MACROS = new AttributeName(ALL_NO_NS, SAME_LOCAL("macros"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName METHOD = new AttributeName(ALL_NO_NS, SAME_LOCAL("method"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName LOWSRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("lowsrc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("lspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LQUOTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("lquote"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName USEMAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("usemap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName WIDTHS = new AttributeName(ALL_NO_NS, SAME_LOCAL("widths"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TARGET = new AttributeName(ALL_NO_NS, SAME_LOCAL("target"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VALUES = new AttributeName(ALL_NO_NS, SAME_LOCAL("values"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("valign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName VSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("vspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName POSTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("poster"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName POINTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("points"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PROMPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("prompt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCOPED = new AttributeName(ALL_NO_NS, SAME_LOCAL("scoped"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STRING = new AttributeName(ALL_NO_NS, SAME_LOCAL("string"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCHEME = new AttributeName(ALL_NO_NS, SAME_LOCAL("scheme"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RADIUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("radius"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RESULT = new AttributeName(ALL_NO_NS, SAME_LOCAL("result"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ROTATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rotate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RQUOTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("rquote"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ALTTEXT = new AttributeName(ALL_NO_NS, SAME_LOCAL("alttext"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARCHIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("archive"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName AZIMUTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("azimuth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLOSURE = new AttributeName(ALL_NO_NS, SAME_LOCAL("closure"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CHECKED = new AttributeName(ALL_NO_NS, SAME_LOCAL("checked"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName CLASSID = new AttributeName(ALL_NO_NS, SAME_LOCAL("classid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CHAROFF = new AttributeName(ALL_NO_NS, SAME_LOCAL("charoff"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BGCOLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("bgcolor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("colspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CHARSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("charset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COMPACT = new AttributeName(ALL_NO_NS, SAME_LOCAL("compact"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName CONTENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("content"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ENCTYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("enctype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName DATASRC = new AttributeName(ALL_NO_NS, SAME_LOCAL("datasrc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DATAFLD = new AttributeName(ALL_NO_NS, SAME_LOCAL("datafld"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DECLARE = new AttributeName(ALL_NO_NS, SAME_LOCAL("declare"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName DISPLAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("display"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DIVISOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("divisor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DEFAULT = new AttributeName(ALL_NO_NS, SAME_LOCAL("default"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName DESCENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("descent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KERNING = new AttributeName(ALL_NO_NS, SAME_LOCAL("kerning"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HANGING = new AttributeName(ALL_NO_NS, SAME_LOCAL("hanging"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HEADERS = new AttributeName(ALL_NO_NS, SAME_LOCAL("headers"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONPASTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onpaste"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCLICK = new AttributeName(ALL_NO_NS, SAME_LOCAL("onclick"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OPTIMUM = new AttributeName(ALL_NO_NS, SAME_LOCAL("optimum"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEGIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbegin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONKEYUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeyup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONERROR = new AttributeName(ALL_NO_NS, SAME_LOCAL("onerror"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONINPUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oninput"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONABORT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onabort"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONRESET = new AttributeName(ALL_NO_NS, SAME_LOCAL("onreset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NOSHADE = new AttributeName(ALL_NO_NS, SAME_LOCAL("noshade"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName MINSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("minsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MAXSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LOOPEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("loopend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LARGEOP = new AttributeName(ALL_NO_NS, SAME_LOCAL("largeop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNICODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TARGETX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("targetx", "targetX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TARGETY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("targety", "targetY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VIEWBOX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("viewbox", "viewBox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERSION = new AttributeName(ALL_NO_NS, SAME_LOCAL("version"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATTERN = new AttributeName(ALL_NO_NS, SAME_LOCAL("pattern"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PROFILE = new AttributeName(ALL_NO_NS, SAME_LOCAL("profile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RESTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("restart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ROWSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SANDBOX = new AttributeName(ALL_NO_NS, SAME_LOCAL("sandbox"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SUMMARY = new AttributeName(ALL_NO_NS, SAME_LOCAL("summary"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STANDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("standby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPLACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("replace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName AUTOPLAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("autoplay"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ADDITIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("additive"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CALCMODE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("calcmode", "calcMode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CODETYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("codetype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CODEBASE = new AttributeName(ALL_NO_NS, SAME_LOCAL("codebase"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CONTROLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("controls"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BEVELLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("bevelled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EXPONENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("exponent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EDGEMODE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("edgemode", "edgeMode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ENCODING = new AttributeName(ALL_NO_NS, SAME_LOCAL("encoding"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GLYPHREF = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("glyphref", "glyphRef"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DATETIME = new AttributeName(ALL_NO_NS, SAME_LOCAL("datetime"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DISABLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("disabled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName FONTSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KEYTIMES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keytimes", "keyTimes"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PANOSE_1 = new AttributeName(ALL_NO_NS, SAME_LOCAL("panose-1"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HREFLANG = new AttributeName(ALL_NO_NS, SAME_LOCAL("hreflang"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONRESIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onresize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBOUNCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbounce"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONUNLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onunload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFINISH = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfinish"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSCROLL = new AttributeName(ALL_NO_NS, SAME_LOCAL("onscroll"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OPERATOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("operator"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OVERFLOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("overflow"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSUBMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onsubmit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONREPEAT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrepeat"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSELECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onselect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NOTATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("notation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NORESIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("noresize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName MANIFEST = new AttributeName(ALL_NO_NS, SAME_LOCAL("manifest"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MATHSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MULTIPLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("multiple"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName LONGDESC = new AttributeName(ALL_NO_NS, SAME_LOCAL("longdesc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LANGUAGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("language"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEMPLATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("template"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TABINDEX = new AttributeName(ALL_NO_NS, SAME_LOCAL("tabindex"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName READONLY = new AttributeName(ALL_NO_NS, SAME_LOCAL("readonly"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName SELECTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("selected"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ROWLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SEAMLESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("seamless"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ROWALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STRETCHY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stretchy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REQUIRED = new AttributeName(ALL_NO_NS, SAME_LOCAL("required"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName XML_BASE = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:base", "base"), XML_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName XML_LANG = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:lang", "lang"), XML_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName X_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("x-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_OWNS = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-owns"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName AUTOFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("autofocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ARIA_SORT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-sort"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACCESSKEY = new AttributeName(ALL_NO_NS, SAME_LOCAL("accesskey"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_BUSY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-busy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_GRAB = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-grab"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName AMPLITUDE = new AttributeName(ALL_NO_NS, SAME_LOCAL("amplitude"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_LIVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-live"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLIP_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLIP_PATH = new AttributeName(ALL_NO_NS, SAME_LOCAL("clip-path"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EQUALROWS = new AttributeName(ALL_NO_NS, SAME_LOCAL("equalrows"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ELEVATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("elevation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DIRECTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("direction"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DRAGGABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("draggable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FILTERRES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("filterres", "filterRes"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FILL_RULE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill-rule"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONTSTYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontstyle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_SIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-size"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KEYPOINTS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keypoints", "keyPoints"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HIDEFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("hidefocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMESSAGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmessage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName INTERCEPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("intercept"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOVEEND = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmoveend"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONINVALID = new AttributeName(ALL_NO_NS, SAME_LOCAL("oninvalid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONKEYDOWN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeydown"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFOCUSIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocusin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName INPUTMODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("inputmode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONROWEXIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowexit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MATHCOLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathcolor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MASKUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("maskunits", "maskUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MAXLENGTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("maxlength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LINEBREAK = new AttributeName(ALL_NO_NS, SAME_LOCAL("linebreak"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LOOPSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("loopstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TRANSFORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("transform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName V_HANGING = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-hanging"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VALUETYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("valuetype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName POINTSATZ = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatz", "pointsAtZ"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName POINTSATX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsatx", "pointsAtX"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName POINTSATY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pointsaty", "pointsAtY"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PLAYCOUNT = new AttributeName(ALL_NO_NS, SAME_LOCAL("playcount"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SYMMETRIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("symmetric"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCROLLING = new AttributeName(ALL_NO_NS, SAME_LOCAL("scrolling"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName REPEATDUR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("repeatdur", "repeatDur"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SELECTION = new AttributeName(ALL_NO_NS, SAME_LOCAL("selection"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SEPARATOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("separator"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XML_SPACE = new AttributeName(XML_NS, COLONIFIED_LOCAL("xml:space", "space"), XML_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName AUTOSUBMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("autosubmit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
-    public static final AttributeName ALPHABETIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("alphabetic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACTIONTYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("actiontype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACCUMULATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("accumulate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_LEVEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-level"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLUMNSPAN = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnspan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CAP_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("cap-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("background"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GLYPH_NAME = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-name"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GROUPALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("groupalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONTFAMILY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontfamily"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONTWEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("fontweight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_STYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-style"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KEYSPLINES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("keysplines", "keySplines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HTTP_EQUIV = new AttributeName(ALL_NO_NS, SAME_LOCAL("http-equiv"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OCCURRENCE = new AttributeName(ALL_NO_NS, SAME_LOCAL("occurrence"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName IRRELEVANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("irrelevant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDBLCLICK = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondblclick"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGDROP = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragdrop"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONKEYPRESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onkeypress"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONROWENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGOVER = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragover"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFOCUSOUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfocusout"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEOUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseout"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName NUMOCTAVES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("numoctaves", "numOctaves"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKER_MID = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-mid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKER_END = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-end"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEXTLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("textlength", "textLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VISIBILITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("visibility"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VIEWTARGET = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("viewtarget", "viewTarget"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERT_ADV_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-adv-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATHLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("pathlength", "pathLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEAT_MAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-max"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RADIOGROUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("radiogroup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STOP_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("stop-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SEPARATORS = new AttributeName(ALL_NO_NS, SAME_LOCAL("separators"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEAT_MIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-min"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ROWSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ZOOMANDPAN = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("zoomandpan", "zoomAndPan"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XLINK_TYPE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:type", "type"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName XLINK_ROLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:role", "role"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName XLINK_HREF = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:href", "href"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName XLINK_SHOW = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:show", "show"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName ACCENTUNDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("accentunder"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_SECRET = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-secret"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_ATOMIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-atomic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_HIDDEN = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-hidden"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_FLOWTO = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-flowto"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARABIC_FORM = new AttributeName(ALL_NO_NS, SAME_LOCAL("arabic-form"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CELLPADDING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellpadding"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CELLSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("cellspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLUMNWIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnwidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLUMNALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLUMNLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CONTEXTMENU = new AttributeName(ALL_NO_NS, SAME_LOCAL("contextmenu"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BASEPROFILE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("baseprofile", "baseProfile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_FAMILY = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-family"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FRAMEBORDER = new AttributeName(ALL_NO_NS, SAME_LOCAL("frameborder"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FILTERUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("filterunits", "filterUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FLOOD_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("flood-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_WEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-weight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HORIZ_ADV_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-adv-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGLEAVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragleave"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEMOVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousemove"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ORIENTATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("orientation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEDOWN = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousedown"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEOVER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseover"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName IDEOGRAPHIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("ideographic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFORECUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforecut"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFORMINPUT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onforminput"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDRAGSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondragstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOVESTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmovestart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKERUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerunits", "markerUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MATHVARIANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathvariant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARGINWIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("marginwidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKERWIDTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerwidth", "markerWidth"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEXT_ANCHOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-anchor"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TABLEVALUES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("tablevalues", "tableValues"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCRIPTLEVEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptlevel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEATCOUNT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("repeatcount", "repeatCount"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STITCHTILES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("stitchtiles", "stitchTiles"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STARTOFFSET = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("startoffset", "startOffset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCROLLDELAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("scrolldelay"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XMLNS_XLINK = new AttributeName(XMLNS_NS, COLONIFIED_LOCAL("xmlns:xlink", "xlink"), XMLNS_PREFIX, IS_XMLNS);
-    public static final AttributeName XLINK_TITLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:title", "title"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName ARIA_INVALID = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-invalid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_PRESSED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-pressed"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_CHECKED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-checked"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName AUTOCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("autocomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName ARIA_SETSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-setsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_CHANNEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-channel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EQUALCOLUMNS = new AttributeName(ALL_NO_NS, SAME_LOCAL("equalcolumns"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DISPLAYSTYLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("displaystyle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DATAFORMATAS = new AttributeName(ALL_NO_NS, SAME_LOCAL("dataformatas"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
-    public static final AttributeName FILL_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("fill-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_VARIANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-variant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_STRETCH = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-stretch"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FRAMESPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("framespacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KERNELMATRIX = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("kernelmatrix", "kernelMatrix"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDEACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONROWSDELETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowsdelete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSELEAVE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseleave"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFORMCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onformchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCELLCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncellchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEWHEEL = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmousewheel"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONMOUSEENTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("onmouseenter"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONAFTERPRINT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onafterprint"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFORECOPY = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforecopy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARGINHEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("marginheight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKERHEIGHT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("markerheight", "markerHeight"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MARKER_START = new AttributeName(ALL_NO_NS, SAME_LOCAL("marker-start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MATHEMATICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathematical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LENGTHADJUST = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("lengthadjust", "lengthAdjust"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNSELECTABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unselectable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNICODE_BIDI = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode-bidi"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNITS_PER_EM = new AttributeName(ALL_NO_NS, SAME_LOCAL("units-per-em"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName WORD_SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("word-spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName WRITING_MODE = new AttributeName(ALL_NO_NS, SAME_LOCAL("writing-mode"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName V_ALPHABETIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-alphabetic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATTERNUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patternunits", "patternUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPREADMETHOD = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("spreadmethod", "spreadMethod"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SURFACESCALE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("surfacescale", "surfaceScale"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_WIDTH = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-width"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEAT_START = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-start"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STDDEVIATION = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("stddeviation", "stdDeviation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STOP_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stop-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_CONTROLS = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-controls"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_HASPOPUP = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-haspopup"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ACCENT_HEIGHT = new AttributeName(ALL_NO_NS, SAME_LOCAL("accent-height"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_VALUENOW = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuenow"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_RELEVANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-relevant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_POSINSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-posinset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_VALUEMAX = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuemax"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_READONLY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-readonly"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_SELECTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-selected"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_REQUIRED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-required"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_EXPANDED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-expanded"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_DISABLED = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-disabled"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ATTRIBUTETYPE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("attributetype", "attributeType"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ATTRIBUTENAME = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("attributename", "attributeName"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_DATATYPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-datatype"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_VALUEMIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-valuemin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BASEFREQUENCY = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("basefrequency", "baseFrequency"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLUMNSPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("columnspacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLOR_PROFILE = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-profile"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CLIPPATHUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("clippathunits", "clipPathUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DEFINITIONURL = new AttributeName(ALL_NO_NS, MATH_DIFFERENT("definitionurl", "definitionURL"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GRADIENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("gradientunits", "gradientUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FLOOD_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("flood-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONAFTERUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onafterupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONERRORUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onerrorupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREPASTE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforepaste"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONLOSECAPTURE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onlosecapture"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCONTEXTMENU = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncontextmenu"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONSELECTSTART = new AttributeName(ALL_NO_NS, SAME_LOCAL("onselectstart"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREPRINT = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeprint"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MOVABLELIMITS = new AttributeName(ALL_NO_NS, SAME_LOCAL("movablelimits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LINETHICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("linethickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNICODE_RANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("unicode-range"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName THINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("thinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERT_ORIGIN_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-origin-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERT_ORIGIN_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("vert-origin-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName V_IDEOGRAPHIC = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-ideographic"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PRESERVEALPHA = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("preservealpha", "preserveAlpha"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCRIPTMINSIZE = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptminsize"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPECIFICATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("specification"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XLINK_ACTUATE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:actuate", "actuate"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName XLINK_ARCROLE = new AttributeName(XLINK_NS, COLONIFIED_LOCAL("xlink:arcrole", "arcrole"), XLINK_PREFIX, NCNAME_FOREIGN);
-    public static final AttributeName ACCEPT_CHARSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("accept-charset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ALIGNMENTSCOPE = new AttributeName(ALL_NO_NS, SAME_LOCAL("alignmentscope"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_MULTILINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-multiline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName BASELINE_SHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("baseline-shift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HORIZ_ORIGIN_X = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-origin-x"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName HORIZ_ORIGIN_Y = new AttributeName(ALL_NO_NS, SAME_LOCAL("horiz-origin-y"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREUPDATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeupdate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONFILTERCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onfilterchange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONROWSINSERTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("onrowsinserted"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREUNLOAD = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeunload"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MATHBACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("mathbackground"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LETTER_SPACING = new AttributeName(ALL_NO_NS, SAME_LOCAL("letter-spacing"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LIGHTING_COLOR = new AttributeName(ALL_NO_NS, SAME_LOCAL("lighting-color"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName THICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("thickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEXT_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName V_MATHEMATICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-mathematical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName POINTER_EVENTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("pointer-events"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PRIMITIVEUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("primitiveunits", "primitiveUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SYSTEMLANGUAGE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("systemlanguage", "systemLanguage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_LINECAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-linecap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SUBSCRIPTSHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("subscriptshift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_OPACITY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-opacity"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_DROPEFFECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-dropeffect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_LABELLEDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-labelledby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_TEMPLATEID = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-templateid"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLOR_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CONTENTEDITABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("contenteditable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DIFFUSECONSTANT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("diffuseconstant", "diffuseConstant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDATAAVAILABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondataavailable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONCONTROLSELECT = new AttributeName(ALL_NO_NS, SAME_LOCAL("oncontrolselect"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName IMAGE_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("image-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MEDIUMMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("mediummathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName TEXT_DECORATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("text-decoration"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SHAPE_RENDERING = new AttributeName(ALL_NO_NS, SAME_LOCAL("shape-rendering"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_LINEJOIN = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-linejoin"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REPEAT_TEMPLATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("repeat-template"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_DESCRIBEDBY = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-describedby"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CONTENTSTYLETYPE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("contentstyletype", "contentStyleType"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName FONT_SIZE_ADJUST = new AttributeName(ALL_NO_NS, SAME_LOCAL("font-size-adjust"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName KERNELUNITLENGTH = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("kernelunitlength", "kernelUnitLength"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONPROPERTYCHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onpropertychange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDATASETCHANGED = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondatasetchanged"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName MASKCONTENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("maskcontentunits", "maskContentUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATTERNTRANSFORM = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patterntransform", "patternTransform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REQUIREDFEATURES = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("requiredfeatures", "requiredFeatures"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName RENDERING_INTENT = new AttributeName(ALL_NO_NS, SAME_LOCAL("rendering-intent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPECULAREXPONENT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("specularexponent", "specularExponent"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SPECULARCONSTANT = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("specularconstant", "specularConstant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SUPERSCRIPTSHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("superscriptshift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_DASHARRAY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-dasharray"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName XCHANNELSELECTOR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("xchannelselector", "xChannelSelector"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName YCHANNELSELECTOR = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("ychannelselector", "yChannelSelector"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_AUTOCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-autocomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName CONTENTSCRIPTTYPE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("contentscripttype", "contentScriptType"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ENABLE_BACKGROUND = new AttributeName(ALL_NO_NS, SAME_LOCAL("enable-background"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName DOMINANT_BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("dominant-baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GRADIENTTRANSFORM = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("gradienttransform", "gradientTransform"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFORDEACTIVATE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbefordeactivate"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONDATASETCOMPLETE = new AttributeName(ALL_NO_NS, SAME_LOCAL("ondatasetcomplete"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OVERLINE_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("overline-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONBEFOREEDITFOCUS = new AttributeName(ALL_NO_NS, SAME_LOCAL("onbeforeeditfocus"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName LIMITINGCONEANGLE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("limitingconeangle", "limitingConeAngle"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERYTHINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("verythinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_DASHOFFSET = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-dashoffset"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STROKE_MITERLIMIT = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-miterlimit"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ALIGNMENT_BASELINE = new AttributeName(ALL_NO_NS, SAME_LOCAL("alignment-baseline"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ONREADYSTATECHANGE = new AttributeName(ALL_NO_NS, SAME_LOCAL("onreadystatechange"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName OVERLINE_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("overline-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNDERLINE_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("underline-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERYTHICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("verythickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName REQUIREDEXTENSIONS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("requiredextensions", "requiredExtensions"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLOR_INTERPOLATION = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-interpolation"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName UNDERLINE_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("underline-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PRESERVEASPECTRATIO = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("preserveaspectratio", "preserveAspectRatio"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName PATTERNCONTENTUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("patterncontentunits", "patternContentUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_MULTISELECTABLE = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-multiselectable"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName SCRIPTSIZEMULTIPLIER = new AttributeName(ALL_NO_NS, SAME_LOCAL("scriptsizemultiplier"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName ARIA_ACTIVEDESCENDANT = new AttributeName(ALL_NO_NS, SAME_LOCAL("aria-activedescendant"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERYVERYTHINMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("veryverythinmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName VERYVERYTHICKMATHSPACE = new AttributeName(ALL_NO_NS, SAME_LOCAL("veryverythickmathspace"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STRIKETHROUGH_POSITION = new AttributeName(ALL_NO_NS, SAME_LOCAL("strikethrough-position"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName STRIKETHROUGH_THICKNESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("strikethrough-thickness"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName EXTERNALRESOURCESREQUIRED = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("externalresourcesrequired", "externalResourcesRequired"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GLYPH_ORIENTATION_VERTICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-orientation-vertical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName COLOR_INTERPOLATION_FILTERS = new AttributeName(ALL_NO_NS, SAME_LOCAL("color-interpolation-filters"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
-    public static final AttributeName GLYPH_ORIENTATION_HORIZONTAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("glyph-orientation-horizontal"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ALT = new AttributeName(ALL_NO_NS, "alt", "alt", "alt", "alt", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DIR = new AttributeName(ALL_NO_NS, "dir", "dir", "dir", "dir", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName DUR = new AttributeName(ALL_NO_NS, "dur", "dur", "dur", "dur", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName END = new AttributeName(ALL_NO_NS, "end", "end", "end", "end", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FOR = new AttributeName(ALL_NO_NS, "for", "for", "for", "for", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IN2 = new AttributeName(ALL_NO_NS, "in2", "in2", "in2", "in2", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LOW = new AttributeName(ALL_NO_NS, "low", "low", "low", "low", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MIN = new AttributeName(ALL_NO_NS, "min", "min", "min", "min", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MAX = new AttributeName(ALL_NO_NS, "max", "max", "max", "max", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REL = new AttributeName(ALL_NO_NS, "rel", "rel", "rel", "rel", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REV = new AttributeName(ALL_NO_NS, "rev", "rev", "rev", "rev", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SRC = new AttributeName(ALL_NO_NS, "src", "src", "src", "src", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName D = new AttributeName(ALL_NO_NS, "d", "d", "d", "d", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName R = new AttributeName(ALL_NO_NS, "r", "r", "r", "r", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName X = new AttributeName(ALL_NO_NS, "x", "x", "x", "x", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName Y = new AttributeName(ALL_NO_NS, "y", "y", "y", "y", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName Z = new AttributeName(ALL_NO_NS, "z", "z", "z", "z", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName K1 = new AttributeName(ALL_NO_NS, "k1", "k1", "k1", "k1", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName X1 = new AttributeName(ALL_NO_NS, "x1", "x1", "x1", "x1", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName Y1 = new AttributeName(ALL_NO_NS, "y1", "y1", "y1", "y1", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName K2 = new AttributeName(ALL_NO_NS, "k2", "k2", "k2", "k2", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName X2 = new AttributeName(ALL_NO_NS, "x2", "x2", "x2", "x2", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName Y2 = new AttributeName(ALL_NO_NS, "y2", "y2", "y2", "y2", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName K3 = new AttributeName(ALL_NO_NS, "k3", "k3", "k3", "k3", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName K4 = new AttributeName(ALL_NO_NS, "k4", "k4", "k4", "k4", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName XML_SPACE = new AttributeName(XML_NS, "xml:space", "space", "space", "xml:space", XML_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XML_LANG = new AttributeName(XML_NS, "xml:lang", "lang", "lang", "xml:lang", XML_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName ARIA_GRAB = new AttributeName(ALL_NO_NS, "aria-grab", "aria-grab", "aria-grab", "aria-grab", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_VALUEMAX = new AttributeName(ALL_NO_NS, "aria-valuemax", "aria-valuemax", "aria-valuemax", "aria-valuemax", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_LABELLEDBY = new AttributeName(ALL_NO_NS, "aria-labelledby", "aria-labelledby", "aria-labelledby", "aria-labelledby", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_DESCRIBEDBY = new AttributeName(ALL_NO_NS, "aria-describedby", "aria-describedby", "aria-describedby", "aria-describedby", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_DISABLED = new AttributeName(ALL_NO_NS, "aria-disabled", "aria-disabled", "aria-disabled", "aria-disabled", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_CHECKED = new AttributeName(ALL_NO_NS, "aria-checked", "aria-checked", "aria-checked", "aria-checked", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_SELECTED = new AttributeName(ALL_NO_NS, "aria-selected", "aria-selected", "aria-selected", "aria-selected", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_DROPEFFECT = new AttributeName(ALL_NO_NS, "aria-dropeffect", "aria-dropeffect", "aria-dropeffect", "aria-dropeffect", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_REQUIRED = new AttributeName(ALL_NO_NS, "aria-required", "aria-required", "aria-required", "aria-required", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_EXPANDED = new AttributeName(ALL_NO_NS, "aria-expanded", "aria-expanded", "aria-expanded", "aria-expanded", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_PRESSED = new AttributeName(ALL_NO_NS, "aria-pressed", "aria-pressed", "aria-pressed", "aria-pressed", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_LEVEL = new AttributeName(ALL_NO_NS, "aria-level", "aria-level", "aria-level", "aria-level", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_CHANNEL = new AttributeName(ALL_NO_NS, "aria-channel", "aria-channel", "aria-channel", "aria-channel", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_HIDDEN = new AttributeName(ALL_NO_NS, "aria-hidden", "aria-hidden", "aria-hidden", "aria-hidden", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_SECRET = new AttributeName(ALL_NO_NS, "aria-secret", "aria-secret", "aria-secret", "aria-secret", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_POSINSET = new AttributeName(ALL_NO_NS, "aria-posinset", "aria-posinset", "aria-posinset", "aria-posinset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_ATOMIC = new AttributeName(ALL_NO_NS, "aria-atomic", "aria-atomic", "aria-atomic", "aria-atomic", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_INVALID = new AttributeName(ALL_NO_NS, "aria-invalid", "aria-invalid", "aria-invalid", "aria-invalid", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_TEMPLATEID = new AttributeName(ALL_NO_NS, "aria-templateid", "aria-templateid", "aria-templateid", "aria-templateid", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_VALUEMIN = new AttributeName(ALL_NO_NS, "aria-valuemin", "aria-valuemin", "aria-valuemin", "aria-valuemin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_MULTISELECTABLE = new AttributeName(ALL_NO_NS, "aria-multiselectable", "aria-multiselectable", "aria-multiselectable", "aria-multiselectable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_CONTROLS = new AttributeName(ALL_NO_NS, "aria-controls", "aria-controls", "aria-controls", "aria-controls", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_MULTILINE = new AttributeName(ALL_NO_NS, "aria-multiline", "aria-multiline", "aria-multiline", "aria-multiline", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_READONLY = new AttributeName(ALL_NO_NS, "aria-readonly", "aria-readonly", "aria-readonly", "aria-readonly", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_OWNS = new AttributeName(ALL_NO_NS, "aria-owns", "aria-owns", "aria-owns", "aria-owns", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_ACTIVEDESCENDANT = new AttributeName(ALL_NO_NS, "aria-activedescendant", "aria-activedescendant", "aria-activedescendant", "aria-activedescendant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_RELEVANT = new AttributeName(ALL_NO_NS, "aria-relevant", "aria-relevant", "aria-relevant", "aria-relevant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_DATATYPE = new AttributeName(ALL_NO_NS, "aria-datatype", "aria-datatype", "aria-datatype", "aria-datatype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_VALUENOW = new AttributeName(ALL_NO_NS, "aria-valuenow", "aria-valuenow", "aria-valuenow", "aria-valuenow", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_SORT = new AttributeName(ALL_NO_NS, "aria-sort", "aria-sort", "aria-sort", "aria-sort", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_AUTOCOMPLETE = new AttributeName(ALL_NO_NS, "aria-autocomplete", "aria-autocomplete", "aria-autocomplete", "aria-autocomplete", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_FLOWTO = new AttributeName(ALL_NO_NS, "aria-flowto", "aria-flowto", "aria-flowto", "aria-flowto", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_BUSY = new AttributeName(ALL_NO_NS, "aria-busy", "aria-busy", "aria-busy", "aria-busy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_LIVE = new AttributeName(ALL_NO_NS, "aria-live", "aria-live", "aria-live", "aria-live", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_HASPOPUP = new AttributeName(ALL_NO_NS, "aria-haspopup", "aria-haspopup", "aria-haspopup", "aria-haspopup", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARIA_SETSIZE = new AttributeName(ALL_NO_NS, "aria-setsize", "aria-setsize", "aria-setsize", "aria-setsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLEAR = new AttributeName(ALL_NO_NS, "clear", "clear", "clear", "clear", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName DISABLED = new AttributeName(ALL_NO_NS, "disabled", "disabled", "disabled", "disabled", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName DEFAULT = new AttributeName(ALL_NO_NS, "default", "default", "default", "default", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName DATA = new AttributeName(ALL_NO_NS, "data", "data", "data", "data", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EQUALCOLUMNS = new AttributeName(ALL_NO_NS, "equalcolumns", "equalcolumns", "equalcolumns", "equalcolumns", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EQUALROWS = new AttributeName(ALL_NO_NS, "equalrows", "equalrows", "equalrows", "equalrows", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HSPACE = new AttributeName(ALL_NO_NS, "hspace", "hspace", "hspace", "hspace", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ISMAP = new AttributeName(ALL_NO_NS, "ismap", "ismap", "ismap", "ismap", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName LOCAL = new AttributeName(ALL_NO_NS, "local", "local", "local", "local", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LSPACE = new AttributeName(ALL_NO_NS, "lspace", "lspace", "lspace", "lspace", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MOVABLELIMITS = new AttributeName(ALL_NO_NS, "movablelimits", "movablelimits", "movablelimits", "movablelimits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NOTATION = new AttributeName(ALL_NO_NS, "notation", "notation", "notation", "notation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDATAAVAILABLE = new AttributeName(ALL_NO_NS, "ondataavailable", "ondataavailable", "ondataavailable", "ondataavailable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONPASTE = new AttributeName(ALL_NO_NS, "onpaste", "onpaste", "onpaste", "onpaste", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RSPACE = new AttributeName(ALL_NO_NS, "rspace", "rspace", "rspace", "rspace", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ROWALIGN = new AttributeName(ALL_NO_NS, "rowalign", "rowalign", "rowalign", "rowalign", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ROTATE = new AttributeName(ALL_NO_NS, "rotate", "rotate", "rotate", "rotate", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SEPARATOR = new AttributeName(ALL_NO_NS, "separator", "separator", "separator", "separator", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SEPARATORS = new AttributeName(ALL_NO_NS, "separators", "separators", "separators", "separators", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VSPACE = new AttributeName(ALL_NO_NS, "vspace", "vspace", "vspace", "vspace", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName XCHANNELSELECTOR = new AttributeName(ALL_NO_NS, "xchannelselector", "xchannelselector", "xChannelSelector", "xchannelselector", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName YCHANNELSELECTOR = new AttributeName(ALL_NO_NS, "ychannelselector", "ychannelselector", "yChannelSelector", "ychannelselector", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ENABLE_BACKGROUND = new AttributeName(ALL_NO_NS, "enable-background", "enable-background", "enable-background", "enable-background", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDBLCLICK = new AttributeName(ALL_NO_NS, "ondblclick", "ondblclick", "ondblclick", "ondblclick", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONABORT = new AttributeName(ALL_NO_NS, "onabort", "onabort", "onabort", "onabort", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CALCMODE = new AttributeName(ALL_NO_NS, "calcmode", "calcmode", "calcMode", "calcmode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CHECKED = new AttributeName(ALL_NO_NS, "checked", "checked", "checked", "checked", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName FENCE = new AttributeName(ALL_NO_NS, "fence", "fence", "fence", "fence", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FETCHPRIORITY = new AttributeName(ALL_NO_NS, "fetchpriority", "fetchpriority", "fetchpriority", "fetchpriority", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NONCE = new AttributeName(ALL_NO_NS, "nonce", "nonce", "nonce", "nonce", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSCROLL = new AttributeName(ALL_NO_NS, "onscroll", "onscroll", "onscroll", "onscroll", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONACTIVATE = new AttributeName(ALL_NO_NS, "onactivate", "onactivate", "onactivate", "onactivate", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OPACITY = new AttributeName(ALL_NO_NS, "opacity", "opacity", "opacity", "opacity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SPACING = new AttributeName(ALL_NO_NS, "spacing", "spacing", "spacing", "spacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SPECULAREXPONENT = new AttributeName(ALL_NO_NS, "specularexponent", "specularexponent", "specularExponent", "specularexponent", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SPECULARCONSTANT = new AttributeName(ALL_NO_NS, "specularconstant", "specularconstant", "specularConstant", "specularconstant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BORDER = new AttributeName(ALL_NO_NS, "border", "border", "border", "border", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ID = new AttributeName(ALL_NO_NS, "id", "id", "id", "id", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GRADIENTTRANSFORM = new AttributeName(ALL_NO_NS, "gradienttransform", "gradienttransform", "gradientTransform", "gradienttransform", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GRADIENTUNITS = new AttributeName(ALL_NO_NS, "gradientunits", "gradientunits", "gradientUnits", "gradientunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HIDDEN = new AttributeName(ALL_NO_NS, "hidden", "hidden", "hidden", "hidden", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HEADERS = new AttributeName(ALL_NO_NS, "headers", "headers", "headers", "headers", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LOADING = new AttributeName(ALL_NO_NS, "loading", "loading", "loading", "loading", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName READONLY = new AttributeName(ALL_NO_NS, "readonly", "readonly", "readonly", "readonly", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName RENDERING_INTENT = new AttributeName(ALL_NO_NS, "rendering-intent", "rendering-intent", "rendering-intent", "rendering-intent", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SHADOWROOTMODE = new AttributeName(ALL_NO_NS, "shadowrootmode", "shadowrootmode", "shadowrootmode", "shadowrootmode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SEED = new AttributeName(ALL_NO_NS, "seed", "seed", "seed", "seed", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SHADOWROOTREFERENCETARGET = new AttributeName(ALL_NO_NS, "shadowrootreferencetarget", "shadowrootreferencetarget", "shadowrootreferencetarget", "shadowrootreferencetarget", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SHADOWROOTCLONABLE = new AttributeName(ALL_NO_NS, "shadowrootclonable", "shadowrootclonable", "shadowrootclonable", "shadowrootclonable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SHADOWROOTSERIALIZABLE = new AttributeName(ALL_NO_NS, "shadowrootserializable", "shadowrootserializable", "shadowrootserializable", "shadowrootserializable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SRCDOC = new AttributeName(ALL_NO_NS, "srcdoc", "srcdoc", "srcdoc", "srcdoc", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STDDEVIATION = new AttributeName(ALL_NO_NS, "stddeviation", "stddeviation", "stdDeviation", "stddeviation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SANDBOX = new AttributeName(ALL_NO_NS, "sandbox", "sandbox", "sandbox", "sandbox", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SHADOWROOTDELEGATESFOCUS = new AttributeName(ALL_NO_NS, "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", "shadowrootdelegatesfocus", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName WORD_SPACING = new AttributeName(ALL_NO_NS, "word-spacing", "word-spacing", "word-spacing", "word-spacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCENTUNDER = new AttributeName(ALL_NO_NS, "accentunder", "accentunder", "accentunder", "accentunder", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCEPT_CHARSET = new AttributeName(ALL_NO_NS, "accept-charset", "accept-charset", "accept-charset", "accept-charset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCESSKEY = new AttributeName(ALL_NO_NS, "accesskey", "accesskey", "accesskey", "accesskey", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCENT = new AttributeName(ALL_NO_NS, "accent", "accent", "accent", "accent", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCEPT = new AttributeName(ALL_NO_NS, "accept", "accept", "accept", "accept", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BEVELLED = new AttributeName(ALL_NO_NS, "bevelled", "bevelled", "bevelled", "bevelled", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BASEFREQUENCY = new AttributeName(ALL_NO_NS, "basefrequency", "basefrequency", "baseFrequency", "basefrequency", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BASELINE_SHIFT = new AttributeName(ALL_NO_NS, "baseline-shift", "baseline-shift", "baseline-shift", "baseline-shift", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BASEPROFILE = new AttributeName(ALL_NO_NS, "baseprofile", "baseprofile", "baseProfile", "baseprofile", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BASELINE = new AttributeName(ALL_NO_NS, "baseline", "baseline", "baseline", "baseline", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BASE = new AttributeName(ALL_NO_NS, "base", "base", "base", "base", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CODE = new AttributeName(ALL_NO_NS, "code", "code", "code", "code", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CODETYPE = new AttributeName(ALL_NO_NS, "codetype", "codetype", "codetype", "codetype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CODEBASE = new AttributeName(ALL_NO_NS, "codebase", "codebase", "codebase", "codebase", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CITE = new AttributeName(ALL_NO_NS, "cite", "cite", "cite", "cite", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DEFER = new AttributeName(ALL_NO_NS, "defer", "defer", "defer", "defer", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName DATETIME = new AttributeName(ALL_NO_NS, "datetime", "datetime", "datetime", "datetime", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DIRECTION = new AttributeName(ALL_NO_NS, "direction", "direction", "direction", "direction", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EDGEMODE = new AttributeName(ALL_NO_NS, "edgemode", "edgemode", "edgeMode", "edgemode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EDGE = new AttributeName(ALL_NO_NS, "edge", "edge", "edge", "edge", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ENTERKEYHINT = new AttributeName(ALL_NO_NS, "enterkeyhint", "enterkeyhint", "enterkeyhint", "enterkeyhint", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FACE = new AttributeName(ALL_NO_NS, "face", "face", "face", "face", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName INDEX = new AttributeName(ALL_NO_NS, "index", "index", "index", "index", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName INTERCEPT = new AttributeName(ALL_NO_NS, "intercept", "intercept", "intercept", "intercept", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName INTEGRITY = new AttributeName(ALL_NO_NS, "integrity", "integrity", "integrity", "integrity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LINEBREAK = new AttributeName(ALL_NO_NS, "linebreak", "linebreak", "linebreak", "linebreak", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LABEL = new AttributeName(ALL_NO_NS, "label", "label", "label", "label", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LINETHICKNESS = new AttributeName(ALL_NO_NS, "linethickness", "linethickness", "linethickness", "linethickness", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MODE = new AttributeName(ALL_NO_NS, "mode", "mode", "mode", "mode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NAME = new AttributeName(ALL_NO_NS, "name", "name", "name", "name", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NORESIZE = new AttributeName(ALL_NO_NS, "noresize", "noresize", "noresize", "noresize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ONBEFOREUNLOAD = new AttributeName(ALL_NO_NS, "onbeforeunload", "onbeforeunload", "onbeforeunload", "onbeforeunload", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONREPEAT = new AttributeName(ALL_NO_NS, "onrepeat", "onrepeat", "onrepeat", "onrepeat", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OBJECT = new AttributeName(ALL_NO_NS, "object", "object", "object", "object", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSELECT = new AttributeName(ALL_NO_NS, "onselect", "onselect", "onselect", "onselect", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ORDER = new AttributeName(ALL_NO_NS, "order", "order", "order", "order", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OTHER = new AttributeName(ALL_NO_NS, "other", "other", "other", "other", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONRESET = new AttributeName(ALL_NO_NS, "onreset", "onreset", "onreset", "onreset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONREADYSTATECHANGE = new AttributeName(ALL_NO_NS, "onreadystatechange", "onreadystatechange", "onreadystatechange", "onreadystatechange", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMESSAGE = new AttributeName(ALL_NO_NS, "onmessage", "onmessage", "onmessage", "onmessage", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBEGIN = new AttributeName(ALL_NO_NS, "onbegin", "onbegin", "onbegin", "onbegin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBEFOREPRINT = new AttributeName(ALL_NO_NS, "onbeforeprint", "onbeforeprint", "onbeforeprint", "onbeforeprint", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ORIENT = new AttributeName(ALL_NO_NS, "orient", "orient", "orient", "orient", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ORIENTATION = new AttributeName(ALL_NO_NS, "orientation", "orientation", "orientation", "orientation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBEFORECOPY = new AttributeName(ALL_NO_NS, "onbeforecopy", "onbeforecopy", "onbeforecopy", "onbeforecopy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSELECTSTART = new AttributeName(ALL_NO_NS, "onselectstart", "onselectstart", "onselectstart", "onselectstart", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBEFOREPASTE = new AttributeName(ALL_NO_NS, "onbeforepaste", "onbeforepaste", "onbeforepaste", "onbeforepaste", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONKEYPRESS = new AttributeName(ALL_NO_NS, "onkeypress", "onkeypress", "onkeypress", "onkeypress", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONKEYUP = new AttributeName(ALL_NO_NS, "onkeyup", "onkeyup", "onkeyup", "onkeyup", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBEFORECUT = new AttributeName(ALL_NO_NS, "onbeforecut", "onbeforecut", "onbeforecut", "onbeforecut", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONKEYDOWN = new AttributeName(ALL_NO_NS, "onkeydown", "onkeydown", "onkeydown", "onkeydown", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONRESIZE = new AttributeName(ALL_NO_NS, "onresize", "onresize", "onresize", "onresize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REPEAT = new AttributeName(ALL_NO_NS, "repeat", "repeat", "repeat", "repeat", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REFERRERPOLICY = new AttributeName(ALL_NO_NS, "referrerpolicy", "referrerpolicy", "referrerpolicy", "referrerpolicy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RULES = new AttributeName(ALL_NO_NS, "rules", "rules", "rules", "rules", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName ROLE = new AttributeName(ALL_NO_NS, "role", "role", "role", "role", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REPEATCOUNT = new AttributeName(ALL_NO_NS, "repeatcount", "repeatcount", "repeatCount", "repeatcount", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REPEATDUR = new AttributeName(ALL_NO_NS, "repeatdur", "repeatdur", "repeatDur", "repeatdur", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SELECTED = new AttributeName(ALL_NO_NS, "selected", "selected", "selected", "selected", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName SIZES = new AttributeName(ALL_NO_NS, "sizes", "sizes", "sizes", "sizes", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SUPERSCRIPTSHIFT = new AttributeName(ALL_NO_NS, "superscriptshift", "superscriptshift", "superscriptshift", "superscriptshift", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STRETCHY = new AttributeName(ALL_NO_NS, "stretchy", "stretchy", "stretchy", "stretchy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCHEME = new AttributeName(ALL_NO_NS, "scheme", "scheme", "scheme", "scheme", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SPREADMETHOD = new AttributeName(ALL_NO_NS, "spreadmethod", "spreadmethod", "spreadMethod", "spreadmethod", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SELECTION = new AttributeName(ALL_NO_NS, "selection", "selection", "selection", "selection", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SIZE = new AttributeName(ALL_NO_NS, "size", "size", "size", "size", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TYPE = new AttributeName(ALL_NO_NS, "type", "type", "type", "type", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName DIFFUSECONSTANT = new AttributeName(ALL_NO_NS, "diffuseconstant", "diffuseconstant", "diffuseConstant", "diffuseconstant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HREF = new AttributeName(ALL_NO_NS, "href", "href", "href", "href", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HREFLANG = new AttributeName(ALL_NO_NS, "hreflang", "hreflang", "hreflang", "hreflang", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONAFTERPRINT = new AttributeName(ALL_NO_NS, "onafterprint", "onafterprint", "onafterprint", "onafterprint", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PROFILE = new AttributeName(ALL_NO_NS, "profile", "profile", "profile", "profile", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SURFACESCALE = new AttributeName(ALL_NO_NS, "surfacescale", "surfacescale", "surfaceScale", "surfacescale", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName XREF = new AttributeName(ALL_NO_NS, "xref", "xref", "xref", "xref", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ALIGN = new AttributeName(ALL_NO_NS, "align", "align", "align", "align", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName ALIGNMENT_BASELINE = new AttributeName(ALL_NO_NS, "alignment-baseline", "alignment-baseline", "alignment-baseline", "alignment-baseline", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ALIGNMENTSCOPE = new AttributeName(ALL_NO_NS, "alignmentscope", "alignmentscope", "alignmentscope", "alignmentscope", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DRAGGABLE = new AttributeName(ALL_NO_NS, "draggable", "draggable", "draggable", "draggable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HEIGHT = new AttributeName(ALL_NO_NS, "height", "height", "height", "height", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IMAGESIZES = new AttributeName(ALL_NO_NS, "imagesizes", "imagesizes", "imagesizes", "imagesizes", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IMAGESRCSET = new AttributeName(ALL_NO_NS, "imagesrcset", "imagesrcset", "imagesrcset", "imagesrcset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IMAGE_RENDERING = new AttributeName(ALL_NO_NS, "image-rendering", "image-rendering", "image-rendering", "image-rendering", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LANGUAGE = new AttributeName(ALL_NO_NS, "language", "language", "language", "language", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LANG = new AttributeName(LANG_NS, "lang", "lang", "lang", "lang", LANG_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LARGEOP = new AttributeName(ALL_NO_NS, "largeop", "largeop", "largeop", "largeop", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LONGDESC = new AttributeName(ALL_NO_NS, "longdesc", "longdesc", "longdesc", "longdesc", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LENGTHADJUST = new AttributeName(ALL_NO_NS, "lengthadjust", "lengthadjust", "lengthAdjust", "lengthadjust", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARGINHEIGHT = new AttributeName(ALL_NO_NS, "marginheight", "marginheight", "marginheight", "marginheight", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARGINWIDTH = new AttributeName(ALL_NO_NS, "marginwidth", "marginwidth", "marginwidth", "marginwidth", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ORIGIN = new AttributeName(ALL_NO_NS, "origin", "origin", "origin", "origin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PING = new AttributeName(ALL_NO_NS, "ping", "ping", "ping", "ping", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TARGET = new AttributeName(ALL_NO_NS, "target", "target", "target", "target", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TARGETX = new AttributeName(ALL_NO_NS, "targetx", "targetx", "targetX", "targetx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TARGETY = new AttributeName(ALL_NO_NS, "targety", "targety", "targetY", "targety", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ARCHIVE = new AttributeName(ALL_NO_NS, "archive", "archive", "archive", "archive", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HIGH = new AttributeName(ALL_NO_NS, "high", "high", "high", "high", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LIGHTING_COLOR = new AttributeName(ALL_NO_NS, "lighting-color", "lighting-color", "lighting-color", "lighting-color", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MATHBACKGROUND = new AttributeName(ALL_NO_NS, "mathbackground", "mathbackground", "mathbackground", "mathbackground", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName METHOD = new AttributeName(ALL_NO_NS, "method", "method", "method", "method", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName MATHVARIANT = new AttributeName(ALL_NO_NS, "mathvariant", "mathvariant", "mathvariant", "mathvariant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MATHCOLOR = new AttributeName(ALL_NO_NS, "mathcolor", "mathcolor", "mathcolor", "mathcolor", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MATHSIZE = new AttributeName(ALL_NO_NS, "mathsize", "mathsize", "mathsize", "mathsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NOSHADE = new AttributeName(ALL_NO_NS, "noshade", "noshade", "noshade", "noshade", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ONCHANGE = new AttributeName(ALL_NO_NS, "onchange", "onchange", "onchange", "onchange", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATHLENGTH = new AttributeName(ALL_NO_NS, "pathlength", "pathlength", "pathLength", "pathlength", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATH = new AttributeName(ALL_NO_NS, "path", "path", "path", "path", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ALTIMG = new AttributeName(ALL_NO_NS, "altimg", "altimg", "altimg", "altimg", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACTIONTYPE = new AttributeName(ALL_NO_NS, "actiontype", "actiontype", "actiontype", "actiontype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACTION = new AttributeName(ALL_NO_NS, "action", "action", "action", "action", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACTIVE = new AttributeName(ALL_NO_NS, "active", "active", "active", "active", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ADDITIVE = new AttributeName(ALL_NO_NS, "additive", "additive", "additive", "additive", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BEGIN = new AttributeName(ALL_NO_NS, "begin", "begin", "begin", "begin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DOMINANT_BASELINE = new AttributeName(ALL_NO_NS, "dominant-baseline", "dominant-baseline", "dominant-baseline", "dominant-baseline", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DIVISOR = new AttributeName(ALL_NO_NS, "divisor", "divisor", "divisor", "divisor", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DEFINITIONURL = new AttributeName(ALL_NO_NS, "definitionurl", "definitionURL", "definitionurl", "definitionurl", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LIMITINGCONEANGLE = new AttributeName(ALL_NO_NS, "limitingconeangle", "limitingconeangle", "limitingConeAngle", "limitingconeangle", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MEDIA = new AttributeName(ALL_NO_NS, "media", "media", "media", "media", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MANIFEST = new AttributeName(ALL_NO_NS, "manifest", "manifest", "manifest", "manifest", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONFINISH = new AttributeName(ALL_NO_NS, "onfinish", "onfinish", "onfinish", "onfinish", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OPTIMUM = new AttributeName(ALL_NO_NS, "optimum", "optimum", "optimum", "optimum", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RADIOGROUP = new AttributeName(ALL_NO_NS, "radiogroup", "radiogroup", "radiogroup", "radiogroup", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RADIUS = new AttributeName(ALL_NO_NS, "radius", "radius", "radius", "radius", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCRIPTLEVEL = new AttributeName(ALL_NO_NS, "scriptlevel", "scriptlevel", "scriptlevel", "scriptlevel", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCRIPTSIZEMULTIPLIER = new AttributeName(ALL_NO_NS, "scriptsizemultiplier", "scriptsizemultiplier", "scriptsizemultiplier", "scriptsizemultiplier", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCRIPTMINSIZE = new AttributeName(ALL_NO_NS, "scriptminsize", "scriptminsize", "scriptminsize", "scriptminsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TABINDEX = new AttributeName(ALL_NO_NS, "tabindex", "tabindex", "tabindex", "tabindex", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VALIGN = new AttributeName(ALL_NO_NS, "valign", "valign", "valign", "valign", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName VISIBILITY = new AttributeName(ALL_NO_NS, "visibility", "visibility", "visibility", "visibility", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BACKGROUND = new AttributeName(ALL_NO_NS, "background", "background", "background", "background", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LINK = new AttributeName(ALL_NO_NS, "link", "link", "link", "link", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKER_MID = new AttributeName(ALL_NO_NS, "marker-mid", "marker-mid", "marker-mid", "marker-mid", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKERHEIGHT = new AttributeName(ALL_NO_NS, "markerheight", "markerheight", "markerHeight", "markerheight", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKER_END = new AttributeName(ALL_NO_NS, "marker-end", "marker-end", "marker-end", "marker-end", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MASK = new AttributeName(ALL_NO_NS, "mask", "mask", "mask", "mask", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKER_START = new AttributeName(ALL_NO_NS, "marker-start", "marker-start", "marker-start", "marker-start", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKERWIDTH = new AttributeName(ALL_NO_NS, "markerwidth", "markerwidth", "markerWidth", "markerwidth", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MASKUNITS = new AttributeName(ALL_NO_NS, "maskunits", "maskunits", "maskUnits", "maskunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MARKERUNITS = new AttributeName(ALL_NO_NS, "markerunits", "markerunits", "markerUnits", "markerunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MASKCONTENTUNITS = new AttributeName(ALL_NO_NS, "maskcontentunits", "maskcontentunits", "maskContentUnits", "maskcontentunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AMPLITUDE = new AttributeName(ALL_NO_NS, "amplitude", "amplitude", "amplitude", "amplitude", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CELLSPACING = new AttributeName(ALL_NO_NS, "cellspacing", "cellspacing", "cellspacing", "cellspacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CELLPADDING = new AttributeName(ALL_NO_NS, "cellpadding", "cellpadding", "cellpadding", "cellpadding", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DECLARE = new AttributeName(ALL_NO_NS, "declare", "declare", "declare", "declare", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName FILL_RULE = new AttributeName(ALL_NO_NS, "fill-rule", "fill-rule", "fill-rule", "fill-rule", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FILL = new AttributeName(ALL_NO_NS, "fill", "fill", "fill", "fill", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FILL_OPACITY = new AttributeName(ALL_NO_NS, "fill-opacity", "fill-opacity", "fill-opacity", "fill-opacity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MAXLENGTH = new AttributeName(ALL_NO_NS, "maxlength", "maxlength", "maxlength", "maxlength", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONCLICK = new AttributeName(ALL_NO_NS, "onclick", "onclick", "onclick", "onclick", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONBLUR = new AttributeName(ALL_NO_NS, "onblur", "onblur", "onblur", "onblur", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REPLACE = new AttributeName(ALL_NO_NS, "replace", "replace", "replace", "replace", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName ROWLINES = new AttributeName(ALL_NO_NS, "rowlines", "rowlines", "rowlines", "rowlines", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCALE = new AttributeName(ALL_NO_NS, "scale", "scale", "scale", "scale", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STYLE = new AttributeName(ALL_NO_NS, "style", "style", "style", "style", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TABLEVALUES = new AttributeName(ALL_NO_NS, "tablevalues", "tablevalues", "tableValues", "tablevalues", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TITLE = new AttributeName(ALL_NO_NS, "title", "title", "title", "title", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AZIMUTH = new AttributeName(ALL_NO_NS, "azimuth", "azimuth", "azimuth", "azimuth", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FORMAT = new AttributeName(ALL_NO_NS, "format", "format", "format", "format", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FRAMEBORDER = new AttributeName(ALL_NO_NS, "frameborder", "frameborder", "frameborder", "frameborder", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FRAME = new AttributeName(ALL_NO_NS, "frame", "frame", "frame", "frame", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName FRAMESPACING = new AttributeName(ALL_NO_NS, "framespacing", "framespacing", "framespacing", "framespacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FROM = new AttributeName(ALL_NO_NS, "from", "from", "from", "from", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FORM = new AttributeName(ALL_NO_NS, "form", "form", "form", "form", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PROMPT = new AttributeName(ALL_NO_NS, "prompt", "prompt", "prompt", "prompt", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PRIMITIVEUNITS = new AttributeName(ALL_NO_NS, "primitiveunits", "primitiveunits", "primitiveUnits", "primitiveunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SYMMETRIC = new AttributeName(ALL_NO_NS, "symmetric", "symmetric", "symmetric", "symmetric", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SUMMARY = new AttributeName(ALL_NO_NS, "summary", "summary", "summary", "summary", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName USEMAP = new AttributeName(ALL_NO_NS, "usemap", "usemap", "usemap", "usemap", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ZOOMANDPAN = new AttributeName(ALL_NO_NS, "zoomandpan", "zoomandpan", "zoomAndPan", "zoomandpan", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ASYNC = new AttributeName(ALL_NO_NS, "async", "async", "async", "async", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ALINK = new AttributeName(ALL_NO_NS, "alink", "alink", "alink", "alink", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IN = new AttributeName(ALL_NO_NS, "in", "in", "in", "in", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EVENT = new AttributeName(ALL_NO_NS, "event", "event", "event", "event", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ICON = new AttributeName(ALL_NO_NS, "icon", "icon", "icon", "icon", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KERNELMATRIX = new AttributeName(ALL_NO_NS, "kernelmatrix", "kernelmatrix", "kernelMatrix", "kernelmatrix", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KERNING = new AttributeName(ALL_NO_NS, "kerning", "kerning", "kerning", "kerning", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KERNELUNITLENGTH = new AttributeName(ALL_NO_NS, "kernelunitlength", "kernelunitlength", "kernelUnitLength", "kernelunitlength", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONUNLOAD = new AttributeName(ALL_NO_NS, "onunload", "onunload", "onunload", "onunload", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OPEN = new AttributeName(ALL_NO_NS, "open", "open", "open", "open", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONINVALID = new AttributeName(ALL_NO_NS, "oninvalid", "oninvalid", "oninvalid", "oninvalid", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONEND = new AttributeName(ALL_NO_NS, "onend", "onend", "onend", "onend", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONINPUT = new AttributeName(ALL_NO_NS, "oninput", "oninput", "oninput", "oninput", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POINTER_EVENTS = new AttributeName(ALL_NO_NS, "pointer-events", "pointer-events", "pointer-events", "pointer-events", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POINTS = new AttributeName(ALL_NO_NS, "points", "points", "points", "points", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POINTSATX = new AttributeName(ALL_NO_NS, "pointsatx", "pointsatx", "pointsAtX", "pointsatx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POINTSATY = new AttributeName(ALL_NO_NS, "pointsaty", "pointsaty", "pointsAtY", "pointsaty", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POINTSATZ = new AttributeName(ALL_NO_NS, "pointsatz", "pointsatz", "pointsAtZ", "pointsatz", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SPAN = new AttributeName(ALL_NO_NS, "span", "span", "span", "span", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STANDBY = new AttributeName(ALL_NO_NS, "standby", "standby", "standby", "standby", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TRANSFORM_ORIGIN = new AttributeName(ALL_NO_NS, "transform-origin", "transform-origin", "transform-origin", "transform-origin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TRANSFORM = new AttributeName(ALL_NO_NS, "transform", "transform", "transform", "transform", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VLINK = new AttributeName(ALL_NO_NS, "vlink", "vlink", "vlink", "vlink", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName WHEN = new AttributeName(ALL_NO_NS, "when", "when", "when", "when", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName XLINK_HREF = new AttributeName(XLINK_NS, "xlink:href", "href", "href", "xlink:href", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XLINK_TITLE = new AttributeName(XLINK_NS, "xlink:title", "title", "title", "xlink:title", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XLINK_ROLE = new AttributeName(XLINK_NS, "xlink:role", "role", "role", "xlink:role", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XLINK_ARCROLE = new AttributeName(XLINK_NS, "xlink:arcrole", "arcrole", "arcrole", "xlink:arcrole", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XMLNS_XLINK = new AttributeName(XMLNS_NS, "xmlns:xlink", "xlink", "xlink", "xmlns:xlink", XMLNS_PREFIX, IS_XMLNS);
+    public static final AttributeName XMLNS = new AttributeName(XMLNS_NS, "xmlns", "xmlns", "xmlns", "xmlns", ALL_NO_PREFIX, IS_XMLNS);
+    public static final AttributeName XLINK_TYPE = new AttributeName(XLINK_NS, "xlink:type", "type", "type", "xlink:type", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XLINK_SHOW = new AttributeName(XLINK_NS, "xlink:show", "show", "show", "xlink:show", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName XLINK_ACTUATE = new AttributeName(XLINK_NS, "xlink:actuate", "actuate", "actuate", "xlink:actuate", XLINK_PREFIX, NCNAME_FOREIGN);
+    public static final AttributeName AUTOPLAY = new AttributeName(ALL_NO_NS, "autoplay", "autoplay", "autoplay", "autoplay", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AUTOCORRECT = new AttributeName(ALL_NO_NS, "autocorrect", "autocorrect", "autocorrect", "autocorrect", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AUTOCOMPLETE = new AttributeName(ALL_NO_NS, "autocomplete", "autocomplete", "autocomplete", "autocomplete", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName AUTOFOCUS = new AttributeName(ALL_NO_NS, "autofocus", "autofocus", "autofocus", "autofocus", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName AUTOCAPITALIZE = new AttributeName(ALL_NO_NS, "autocapitalize", "autocapitalize", "autocapitalize", "autocapitalize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BGCOLOR = new AttributeName(ALL_NO_NS, "bgcolor", "bgcolor", "bgcolor", "bgcolor", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLOR_PROFILE = new AttributeName(ALL_NO_NS, "color-profile", "color-profile", "color-profile", "color-profile", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLOR_RENDERING = new AttributeName(ALL_NO_NS, "color-rendering", "color-rendering", "color-rendering", "color-rendering", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLOR_INTERPOLATION = new AttributeName(ALL_NO_NS, "color-interpolation", "color-interpolation", "color-interpolation", "color-interpolation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLOR = new AttributeName(ALL_NO_NS, "color", "color", "color", "color", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLOR_INTERPOLATION_FILTERS = new AttributeName(ALL_NO_NS, "color-interpolation-filters", "color-interpolation-filters", "color-interpolation-filters", "color-interpolation-filters", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ENCODING = new AttributeName(ALL_NO_NS, "encoding", "encoding", "encoding", "encoding", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName EXPONENT = new AttributeName(ALL_NO_NS, "exponent", "exponent", "exponent", "exponent", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FLOOD_COLOR = new AttributeName(ALL_NO_NS, "flood-color", "flood-color", "flood-color", "flood-color", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FLOOD_OPACITY = new AttributeName(ALL_NO_NS, "flood-opacity", "flood-opacity", "flood-opacity", "flood-opacity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LQUOTE = new AttributeName(ALL_NO_NS, "lquote", "lquote", "lquote", "lquote", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NUMOCTAVES = new AttributeName(ALL_NO_NS, "numoctaves", "numoctaves", "numOctaves", "numoctaves", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NOMODULE = new AttributeName(ALL_NO_NS, "nomodule", "nomodule", "nomodule", "nomodule", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ONLOAD = new AttributeName(ALL_NO_NS, "onload", "onload", "onload", "onload", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEWHEEL = new AttributeName(ALL_NO_NS, "onmousewheel", "onmousewheel", "onmousewheel", "onmousewheel", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEENTER = new AttributeName(ALL_NO_NS, "onmouseenter", "onmouseenter", "onmouseenter", "onmouseenter", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEOVER = new AttributeName(ALL_NO_NS, "onmouseover", "onmouseover", "onmouseover", "onmouseover", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONFOCUSIN = new AttributeName(ALL_NO_NS, "onfocusin", "onfocusin", "onfocusin", "onfocusin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONCONTEXTMENU = new AttributeName(ALL_NO_NS, "oncontextmenu", "oncontextmenu", "oncontextmenu", "oncontextmenu", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONZOOM = new AttributeName(ALL_NO_NS, "onzoom", "onzoom", "onzoom", "onzoom", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONCOPY = new AttributeName(ALL_NO_NS, "oncopy", "oncopy", "oncopy", "oncopy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSELEAVE = new AttributeName(ALL_NO_NS, "onmouseleave", "onmouseleave", "onmouseleave", "onmouseleave", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEMOVE = new AttributeName(ALL_NO_NS, "onmousemove", "onmousemove", "onmousemove", "onmousemove", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEUP = new AttributeName(ALL_NO_NS, "onmouseup", "onmouseup", "onmouseup", "onmouseup", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONFOCUS = new AttributeName(ALL_NO_NS, "onfocus", "onfocus", "onfocus", "onfocus", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEOUT = new AttributeName(ALL_NO_NS, "onmouseout", "onmouseout", "onmouseout", "onmouseout", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONFOCUSOUT = new AttributeName(ALL_NO_NS, "onfocusout", "onfocusout", "onfocusout", "onfocusout", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONMOUSEDOWN = new AttributeName(ALL_NO_NS, "onmousedown", "onmousedown", "onmousedown", "onmousedown", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TO = new AttributeName(ALL_NO_NS, "to", "to", "to", "to", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RQUOTE = new AttributeName(ALL_NO_NS, "rquote", "rquote", "rquote", "rquote", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_LINECAP = new AttributeName(ALL_NO_NS, "stroke-linecap", "stroke-linecap", "stroke-linecap", "stroke-linecap", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_DASHARRAY = new AttributeName(ALL_NO_NS, "stroke-dasharray", "stroke-dasharray", "stroke-dasharray", "stroke-dasharray", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_DASHOFFSET = new AttributeName(ALL_NO_NS, "stroke-dashoffset", "stroke-dashoffset", "stroke-dashoffset", "stroke-dashoffset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_LINEJOIN = new AttributeName(ALL_NO_NS, "stroke-linejoin", "stroke-linejoin", "stroke-linejoin", "stroke-linejoin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_MITERLIMIT = new AttributeName(ALL_NO_NS, "stroke-miterlimit", "stroke-miterlimit", "stroke-miterlimit", "stroke-miterlimit", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE = new AttributeName(ALL_NO_NS, "stroke", "stroke", "stroke", "stroke", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCROLLING = new AttributeName(ALL_NO_NS, "scrolling", "scrolling", "scrolling", "scrolling", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName STROKE_WIDTH = new AttributeName(ALL_NO_NS, "stroke-width", "stroke-width", "stroke-width", "stroke-width", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STROKE_OPACITY = new AttributeName(ALL_NO_NS, "stroke-opacity", "stroke-opacity", "stroke-opacity", "stroke-opacity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COMPACT = new AttributeName(ALL_NO_NS, "compact", "compact", "compact", "compact", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName CLIP = new AttributeName(ALL_NO_NS, "clip", "clip", "clip", "clip", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLIP_RULE = new AttributeName(ALL_NO_NS, "clip-rule", "clip-rule", "clip-rule", "clip-rule", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLIP_PATH = new AttributeName(ALL_NO_NS, "clip-path", "clip-path", "clip-path", "clip-path", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLIPPATHUNITS = new AttributeName(ALL_NO_NS, "clippathunits", "clippathunits", "clipPathUnits", "clippathunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DISPLAY = new AttributeName(ALL_NO_NS, "display", "display", "display", "display", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DISPLAYSTYLE = new AttributeName(ALL_NO_NS, "displaystyle", "displaystyle", "displaystyle", "displaystyle", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GLYPH_ORIENTATION_VERTICAL = new AttributeName(ALL_NO_NS, "glyph-orientation-vertical", "glyph-orientation-vertical", "glyph-orientation-vertical", "glyph-orientation-vertical", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GLYPH_ORIENTATION_HORIZONTAL = new AttributeName(ALL_NO_NS, "glyph-orientation-horizontal", "glyph-orientation-horizontal", "glyph-orientation-horizontal", "glyph-orientation-horizontal", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GLYPHREF = new AttributeName(ALL_NO_NS, "glyphref", "glyphref", "glyphRef", "glyphref", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName HTTP_EQUIV = new AttributeName(ALL_NO_NS, "http-equiv", "http-equiv", "http-equiv", "http-equiv", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KEYPOINTS = new AttributeName(ALL_NO_NS, "keypoints", "keypoints", "keyPoints", "keypoints", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LOOP = new AttributeName(ALL_NO_NS, "loop", "loop", "loop", "loop", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PROPERTY = new AttributeName(ALL_NO_NS, "property", "property", "property", "property", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCOPED = new AttributeName(ALL_NO_NS, "scoped", "scoped", "scoped", "scoped", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STEP = new AttributeName(ALL_NO_NS, "step", "step", "step", "step", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName SHAPE_RENDERING = new AttributeName(ALL_NO_NS, "shape-rendering", "shape-rendering", "shape-rendering", "shape-rendering", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SCOPE = new AttributeName(ALL_NO_NS, "scope", "scope", "scope", "scope", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName SHAPE = new AttributeName(ALL_NO_NS, "shape", "shape", "shape", "shape", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName SLOPE = new AttributeName(ALL_NO_NS, "slope", "slope", "slope", "slope", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STOP_COLOR = new AttributeName(ALL_NO_NS, "stop-color", "stop-color", "stop-color", "stop-color", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STOP_OPACITY = new AttributeName(ALL_NO_NS, "stop-opacity", "stop-opacity", "stop-opacity", "stop-opacity", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEMPLATE = new AttributeName(ALL_NO_NS, "template", "template", "template", "template", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName WRAP = new AttributeName(ALL_NO_NS, "wrap", "wrap", "wrap", "wrap", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ABBR = new AttributeName(ALL_NO_NS, "abbr", "abbr", "abbr", "abbr", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ATTRIBUTENAME = new AttributeName(ALL_NO_NS, "attributename", "attributename", "attributeName", "attributename", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ATTRIBUTETYPE = new AttributeName(ALL_NO_NS, "attributetype", "attributetype", "attributeType", "attributetype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CHAR = new AttributeName(ALL_NO_NS, "char", "char", "char", "char", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COORDS = new AttributeName(ALL_NO_NS, "coords", "coords", "coords", "coords", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CHAROFF = new AttributeName(ALL_NO_NS, "charoff", "charoff", "charoff", "charoff", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CHARSET = new AttributeName(ALL_NO_NS, "charset", "charset", "charset", "charset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName NOWRAP = new AttributeName(ALL_NO_NS, "nowrap", "nowrap", "nowrap", "nowrap", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName NOHREF = new AttributeName(ALL_NO_NS, "nohref", "nohref", "nohref", "nohref", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName ONDRAG = new AttributeName(ALL_NO_NS, "ondrag", "ondrag", "ondrag", "ondrag", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGENTER = new AttributeName(ALL_NO_NS, "ondragenter", "ondragenter", "ondragenter", "ondragenter", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGOVER = new AttributeName(ALL_NO_NS, "ondragover", "ondragover", "ondragover", "ondragover", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGEND = new AttributeName(ALL_NO_NS, "ondragend", "ondragend", "ondragend", "ondragend", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDROP = new AttributeName(ALL_NO_NS, "ondrop", "ondrop", "ondrop", "ondrop", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGDROP = new AttributeName(ALL_NO_NS, "ondragdrop", "ondragdrop", "ondragdrop", "ondragdrop", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONERROR = new AttributeName(ALL_NO_NS, "onerror", "onerror", "onerror", "onerror", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OPERATOR = new AttributeName(ALL_NO_NS, "operator", "operator", "operator", "operator", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OVERFLOW = new AttributeName(ALL_NO_NS, "overflow", "overflow", "overflow", "overflow", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGSTART = new AttributeName(ALL_NO_NS, "ondragstart", "ondragstart", "ondragstart", "ondragstart", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONDRAGLEAVE = new AttributeName(ALL_NO_NS, "ondragleave", "ondragleave", "ondragleave", "ondragleave", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STARTOFFSET = new AttributeName(ALL_NO_NS, "startoffset", "startoffset", "startOffset", "startoffset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName START = new AttributeName(ALL_NO_NS, "start", "start", "start", "start", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AS = new AttributeName(ALL_NO_NS, "as", "as", "as", "as", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName AXIS = new AttributeName(ALL_NO_NS, "axis", "axis", "axis", "axis", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BIAS = new AttributeName(ALL_NO_NS, "bias", "bias", "bias", "bias", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLSPAN = new AttributeName(ALL_NO_NS, "colspan", "colspan", "colspan", "colspan", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLASSID = new AttributeName(ALL_NO_NS, "classid", "classid", "classid", "classid", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CROSSORIGIN = new AttributeName(ALL_NO_NS, "crossorigin", "crossorigin", "crossorigin", "crossorigin", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLS = new AttributeName(ALL_NO_NS, "cols", "cols", "cols", "cols", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CURSOR = new AttributeName(ALL_NO_NS, "cursor", "cursor", "cursor", "cursor", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLOSURE = new AttributeName(ALL_NO_NS, "closure", "closure", "closure", "closure", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLOSE = new AttributeName(ALL_NO_NS, "close", "close", "close", "close", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CLASS = new AttributeName(ALL_NO_NS, "class", "class", "class", "class", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName IS = new AttributeName(ALL_NO_NS, "is", "is", "is", "is", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KEYSYSTEM = new AttributeName(ALL_NO_NS, "keysystem", "keysystem", "keysystem", "keysystem", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KEYSPLINES = new AttributeName(ALL_NO_NS, "keysplines", "keysplines", "keySplines", "keysplines", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LOWSRC = new AttributeName(ALL_NO_NS, "lowsrc", "lowsrc", "lowsrc", "lowsrc", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MAXSIZE = new AttributeName(ALL_NO_NS, "maxsize", "maxsize", "maxsize", "maxsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MINSIZE = new AttributeName(ALL_NO_NS, "minsize", "minsize", "minsize", "minsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName OFFSET = new AttributeName(ALL_NO_NS, "offset", "offset", "offset", "offset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PRESERVEALPHA = new AttributeName(ALL_NO_NS, "preservealpha", "preservealpha", "preserveAlpha", "preservealpha", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PRESERVEASPECTRATIO = new AttributeName(ALL_NO_NS, "preserveaspectratio", "preserveaspectratio", "preserveAspectRatio", "preserveaspectratio", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ROWSPAN = new AttributeName(ALL_NO_NS, "rowspan", "rowspan", "rowspan", "rowspan", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ROWSPACING = new AttributeName(ALL_NO_NS, "rowspacing", "rowspacing", "rowspacing", "rowspacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ROWS = new AttributeName(ALL_NO_NS, "rows", "rows", "rows", "rows", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SRCSET = new AttributeName(ALL_NO_NS, "srcset", "srcset", "srcset", "srcset", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SUBSCRIPTSHIFT = new AttributeName(ALL_NO_NS, "subscriptshift", "subscriptshift", "subscriptshift", "subscriptshift", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VERSION = new AttributeName(ALL_NO_NS, "version", "version", "version", "version", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ALTTEXT = new AttributeName(ALL_NO_NS, "alttext", "alttext", "alttext", "alttext", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CONTENTEDITABLE = new AttributeName(ALL_NO_NS, "contenteditable", "contenteditable", "contenteditable", "contenteditable", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CONTROLS = new AttributeName(ALL_NO_NS, "controls", "controls", "controls", "controls", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CONTENT = new AttributeName(ALL_NO_NS, "content", "content", "content", "content", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CONTEXTMENU = new AttributeName(ALL_NO_NS, "contextmenu", "contextmenu", "contextmenu", "contextmenu", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DEPTH = new AttributeName(ALL_NO_NS, "depth", "depth", "depth", "depth", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ENCTYPE = new AttributeName(ALL_NO_NS, "enctype", "enctype", "enctype", "enctype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName FONT_STRETCH = new AttributeName(ALL_NO_NS, "font-stretch", "font-stretch", "font-stretch", "font-stretch", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FILTER = new AttributeName(ALL_NO_NS, "filter", "filter", "filter", "filter", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONTWEIGHT = new AttributeName(ALL_NO_NS, "fontweight", "fontweight", "fontweight", "fontweight", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_WEIGHT = new AttributeName(ALL_NO_NS, "font-weight", "font-weight", "font-weight", "font-weight", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONTSTYLE = new AttributeName(ALL_NO_NS, "fontstyle", "fontstyle", "fontstyle", "fontstyle", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_STYLE = new AttributeName(ALL_NO_NS, "font-style", "font-style", "font-style", "font-style", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONTFAMILY = new AttributeName(ALL_NO_NS, "fontfamily", "fontfamily", "fontfamily", "fontfamily", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_FAMILY = new AttributeName(ALL_NO_NS, "font-family", "font-family", "font-family", "font-family", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_VARIANT = new AttributeName(ALL_NO_NS, "font-variant", "font-variant", "font-variant", "font-variant", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_SIZE_ADJUST = new AttributeName(ALL_NO_NS, "font-size-adjust", "font-size-adjust", "font-size-adjust", "font-size-adjust", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FILTERUNITS = new AttributeName(ALL_NO_NS, "filterunits", "filterunits", "filterUnits", "filterunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONTSIZE = new AttributeName(ALL_NO_NS, "fontsize", "fontsize", "fontsize", "fontsize", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FONT_SIZE = new AttributeName(ALL_NO_NS, "font-size", "font-size", "font-size", "font-size", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName KEYTIMES = new AttributeName(ALL_NO_NS, "keytimes", "keytimes", "keyTimes", "keytimes", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LETTER_SPACING = new AttributeName(ALL_NO_NS, "letter-spacing", "letter-spacing", "letter-spacing", "letter-spacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName LIST = new AttributeName(ALL_NO_NS, "list", "list", "list", "list", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName MULTIPLE = new AttributeName(ALL_NO_NS, "multiple", "multiple", "multiple", "multiple", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName RT = new AttributeName(ALL_NO_NS, "rt", "rt", "rt", "rt", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSTOP = new AttributeName(ALL_NO_NS, "onstop", "onstop", "onstop", "onstop", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSTART = new AttributeName(ALL_NO_NS, "onstart", "onstart", "onstart", "onstart", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName POSTER = new AttributeName(ALL_NO_NS, "poster", "poster", "poster", "poster", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATTERNTRANSFORM = new AttributeName(ALL_NO_NS, "patterntransform", "patterntransform", "patternTransform", "patterntransform", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATTERN = new AttributeName(ALL_NO_NS, "pattern", "pattern", "pattern", "pattern", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATTERNUNITS = new AttributeName(ALL_NO_NS, "patternunits", "patternunits", "patternUnits", "patternunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName PATTERNCONTENTUNITS = new AttributeName(ALL_NO_NS, "patterncontentunits", "patterncontentunits", "patternContentUnits", "patterncontentunits", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RESTART = new AttributeName(ALL_NO_NS, "restart", "restart", "restart", "restart", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName STITCHTILES = new AttributeName(ALL_NO_NS, "stitchtiles", "stitchtiles", "stitchTiles", "stitchtiles", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName SYSTEMLANGUAGE = new AttributeName(ALL_NO_NS, "systemlanguage", "systemlanguage", "systemLanguage", "systemlanguage", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEXT_RENDERING = new AttributeName(ALL_NO_NS, "text-rendering", "text-rendering", "text-rendering", "text-rendering", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEXT_DECORATION = new AttributeName(ALL_NO_NS, "text-decoration", "text-decoration", "text-decoration", "text-decoration", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEXT_ANCHOR = new AttributeName(ALL_NO_NS, "text-anchor", "text-anchor", "text-anchor", "text-anchor", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEXTLENGTH = new AttributeName(ALL_NO_NS, "textlength", "textlength", "textLength", "textlength", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName TEXT = new AttributeName(ALL_NO_NS, "text", "text", "text", "text", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName WRITING_MODE = new AttributeName(ALL_NO_NS, "writing-mode", "writing-mode", "writing-mode", "writing-mode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName WIDTH = new AttributeName(ALL_NO_NS, "width", "width", "width", "width", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ACCUMULATE = new AttributeName(ALL_NO_NS, "accumulate", "accumulate", "accumulate", "accumulate", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLUMNSPAN = new AttributeName(ALL_NO_NS, "columnspan", "columnspan", "columnspan", "columnspan", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLUMNLINES = new AttributeName(ALL_NO_NS, "columnlines", "columnlines", "columnlines", "columnlines", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLUMNALIGN = new AttributeName(ALL_NO_NS, "columnalign", "columnalign", "columnalign", "columnalign", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLUMNSPACING = new AttributeName(ALL_NO_NS, "columnspacing", "columnspacing", "columnspacing", "columnspacing", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName COLUMNWIDTH = new AttributeName(ALL_NO_NS, "columnwidth", "columnwidth", "columnwidth", "columnwidth", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName GROUPALIGN = new AttributeName(ALL_NO_NS, "groupalign", "groupalign", "groupalign", "groupalign", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName INPUTMODE = new AttributeName(ALL_NO_NS, "inputmode", "inputmode", "inputmode", "inputmode", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONSUBMIT = new AttributeName(ALL_NO_NS, "onsubmit", "onsubmit", "onsubmit", "onsubmit", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ONCUT = new AttributeName(ALL_NO_NS, "oncut", "oncut", "oncut", "oncut", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REQUIRED = new AttributeName(ALL_NO_NS, "required", "required", "required", "required", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
+    public static final AttributeName REQUIREDFEATURES = new AttributeName(ALL_NO_NS, "requiredfeatures", "requiredfeatures", "requiredFeatures", "requiredfeatures", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RESULT = new AttributeName(ALL_NO_NS, "result", "result", "result", "result", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REQUIREDEXTENSIONS = new AttributeName(ALL_NO_NS, "requiredextensions", "requiredextensions", "requiredExtensions", "requiredextensions", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VALUES = new AttributeName(ALL_NO_NS, "values", "values", "values", "values", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VALUETYPE = new AttributeName(ALL_NO_NS, "valuetype", "valuetype", "valuetype", "valuetype", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED);
+    public static final AttributeName VALUE = new AttributeName(ALL_NO_NS, "value", "value", "value", "value", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName ELEVATION = new AttributeName(ALL_NO_NS, "elevation", "elevation", "elevation", "elevation", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VIEWTARGET = new AttributeName(ALL_NO_NS, "viewtarget", "viewtarget", "viewTarget", "viewtarget", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName VIEWBOX = new AttributeName(ALL_NO_NS, "viewbox", "viewbox", "viewBox", "viewbox", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CX = new AttributeName(ALL_NO_NS, "cx", "cx", "cx", "cx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DX = new AttributeName(ALL_NO_NS, "dx", "dx", "dx", "dx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FX = new AttributeName(ALL_NO_NS, "fx", "fx", "fx", "fx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RX = new AttributeName(ALL_NO_NS, "rx", "rx", "rx", "rx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REFX = new AttributeName(ALL_NO_NS, "refx", "refx", "refX", "refx", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName BY = new AttributeName(ALL_NO_NS, "by", "by", "by", "by", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName CY = new AttributeName(ALL_NO_NS, "cy", "cy", "cy", "cy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName DY = new AttributeName(ALL_NO_NS, "dy", "dy", "dy", "dy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName FY = new AttributeName(ALL_NO_NS, "fy", "fy", "fy", "fy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName RY = new AttributeName(ALL_NO_NS, "ry", "ry", "ry", "ry", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
+    public static final AttributeName REFY = new AttributeName(ALL_NO_NS, "refy", "refy", "refY", "refy", ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
     private final static @NoLength AttributeName[] ATTRIBUTE_NAMES = {
-    D,
-    K,
-    R,
-    X,
+    MARKERUNITS,
+    BASELINE,
+    STOP_COLOR,
+    CLEAR,
+    XREF,
+    AUTOPLAY,
+    FONT_STYLE,
+    ARIA_DISABLED,
+    OPACITY,
+    ONBEFOREPRINT,
+    PATH,
+    ALINK,
+    ONMOUSEDOWN,
+    COLS,
+    COLUMNLINES,
     Y,
-    Z,
-    BY,
-    CX,
-    CY,
-    DX,
-    DY,
-    G2,
-    G1,
-    FX,
-    FY,
-    K4,
-    K2,
+    ARIA_MULTISELECTABLE,
+    ROTATE,
+    SHADOWROOTCLONABLE,
+    LINEBREAK,
+    REPEATDUR,
+    ORIGIN,
+    RADIUS,
+    TABLEVALUES,
+    POINTSATZ,
+    NUMOCTAVES,
+    CLIPPATHUNITS,
+    ONDRAGEND,
+    ROWS,
+    PATTERNTRANSFORM,
+    VIEWTARGET,
+    MIN,
     K3,
-    K1,
-    ID,
-    IN,
-    U2,
-    U1,
+    ARIA_CHANNEL,
+    ARIA_VALUENOW,
+    LOCAL,
+    ONABORT,
+    HIDDEN,
+    ACCEPT_CHARSET,
+    DIRECTION,
+    OBJECT,
+    ONBEFORECUT,
+    SIZE,
+    IMAGE_RENDERING,
+    MATHBACKGROUND,
+    DIVISOR,
+    LINK,
+    FILL_OPACITY,
+    FORM,
+    OPEN,
+    XLINK_TITLE,
+    COLOR_INTERPOLATION,
+    ONZOOM,
+    STROKE,
+    LOOP,
+    COORDS,
+    STARTOFFSET,
+    LOWSRC,
+    CONTEXTMENU,
+    KEYTIMES,
+    TEXT_DECORATION,
+    REQUIRED,
+    CY,
+    END,
+    SRC,
+    Y1,
+    ARIA_GRAB,
+    ARIA_REQUIRED,
+    ARIA_ATOMIC,
+    ARIA_OWNS,
+    ARIA_BUSY,
+    EQUALCOLUMNS,
+    ONDATAAVAILABLE,
+    XCHANNELSELECTOR,
+    FETCHPRIORITY,
+    BORDER,
+    RENDERING_INTENT,
+    SANDBOX,
+    BEVELLED,
+    CODEBASE,
+    FACE,
+    NAME,
+    ONRESET,
+    ONSELECTSTART,
+    REFERRERPOLICY,
+    STRETCHY,
+    HREFLANG,
+    DRAGGABLE,
+    LONGDESC,
+    TARGETY,
+    MATHSIZE,
+    ACTIVE,
+    MANIFEST,
+    TABINDEX,
+    MASK,
+    CELLPADDING,
+    REPLACE,
+    FRAMEBORDER,
+    SUMMARY,
+    KERNELMATRIX,
+    POINTER_EVENTS,
+    TRANSFORM,
+    XMLNS,
+    AUTOCAPITALIZE,
+    EXPONENT,
+    ONMOUSEENTER,
+    ONMOUSEUP,
+    STROKE_DASHARRAY,
+    COMPACT,
+    GLYPH_ORIENTATION_HORIZONTAL,
+    SHAPE_RENDERING,
+    ABBR,
+    NOHREF,
+    OPERATOR,
+    BIAS,
+    CLASS,
+    PRESERVEALPHA,
+    ALTTEXT,
+    FILTER,
+    FONT_SIZE_ADJUST,
     RT,
-    RX,
+    RESTART,
+    WRITING_MODE,
+    GROUPALIGN,
+    VALUES,
+    FX,
     RY,
-    TO,
-    Y2,
-    Y1,
-    X1,
-    X2,
-    ALT,
     DIR,
-    DUR,
-    END,
-    FOR,
     IN2,
-    MAX,
-    MIN,
-    LOW,
     REL,
-    REV,
-    SRC,
-    AXIS,
-    ABBR,
-    BBOX,
-    CITE,
+    R,
+    K1,
+    X2,
+    XML_SPACE,
+    ARIA_LABELLEDBY,
+    ARIA_SELECTED,
+    ARIA_PRESSED,
+    ARIA_SECRET,
+    ARIA_TEMPLATEID,
+    ARIA_MULTILINE,
+    ARIA_RELEVANT,
+    ARIA_AUTOCOMPLETE,
+    ARIA_HASPOPUP,
+    DEFAULT,
+    HSPACE,
+    MOVABLELIMITS,
+    RSPACE,
+    SEPARATORS,
+    ENABLE_BACKGROUND,
+    CHECKED,
+    ONSCROLL,
+    SPECULAREXPONENT,
+    GRADIENTTRANSFORM,
+    LOADING,
+    SEED,
+    SRCDOC,
+    WORD_SPACING,
+    ACCENT,
+    BASELINE_SHIFT,
     CODE,
-    BIAS,
-    COLS,
-    CLIP,
-    CHAR,
-    BASE,
+    DEFER,
     EDGE,
-    DATA,
-    FILL,
-    FROM,
-    FORM,
-    FACE,
-    HIGH,
-    HREF,
-    OPEN,
-    ICON,
-    NAME,
-    MODE,
-    MASK,
-    LINK,
-    LANG,
-    LIST,
-    TYPE,
-    WHEN,
-    WRAP,
-    TEXT,
-    PATH,
-    PING,
-    REFX,
-    REFY,
-    SIZE,
-    SEED,
-    ROWS,
-    SPAN,
-    STEP,
+    INTERCEPT,
+    LINETHICKNESS,
+    ONBEFOREUNLOAD,
+    ORDER,
+    ONMESSAGE,
+    ORIENTATION,
+    ONKEYPRESS,
+    ONRESIZE,
     ROLE,
-    XREF,
-    ASYNC,
-    ALINK,
-    ALIGN,
-    CLOSE,
-    COLOR,
-    CLASS,
-    CLEAR,
+    SIZES,
+    SPREADMETHOD,
+    DIFFUSECONSTANT,
+    PROFILE,
+    ALIGNMENT_BASELINE,
+    IMAGESIZES,
+    LANG,
+    MARGINHEIGHT,
+    TARGET,
+    HIGH,
+    MATHVARIANT,
+    ONCHANGE,
+    ACTIONTYPE,
     BEGIN,
-    DEPTH,
-    DEFER,
-    FENCE,
-    FRAME,
-    ISMAP,
-    ONEND,
-    INDEX,
-    ORDER,
-    OTHER,
-    ONCUT,
-    NARGS,
-    MEDIA,
-    LABEL,
-    LOCAL,
-    WIDTH,
-    TITLE,
-    VLINK,
-    VALUE,
-    SLOPE,
-    SHAPE,
-    SCOPE,
+    LIMITINGCONEANGLE,
+    OPTIMUM,
+    SCRIPTSIZEMULTIPLIER,
+    VISIBILITY,
+    MARKERHEIGHT,
+    MARKERWIDTH,
+    AMPLITUDE,
+    FILL_RULE,
+    ONCLICK,
     SCALE,
-    SPEED,
-    STYLE,
-    RULES,
-    STEMH,
-    STEMV,
-    START,
-    XMLNS,
-    ACCEPT,
-    ACCENT,
-    ASCENT,
-    ACTIVE,
-    ALTIMG,
-    ACTION,
-    BORDER,
-    CURSOR,
-    COORDS,
-    FILTER,
-    FORMAT,
-    HIDDEN,
-    HSPACE,
-    HEIGHT,
-    ONMOVE,
+    AZIMUTH,
+    FRAMESPACING,
+    PRIMITIVEUNITS,
+    ZOOMANDPAN,
+    EVENT,
+    KERNELUNITLENGTH,
+    ONEND,
+    POINTSATX,
+    STANDBY,
+    WHEN,
+    XLINK_ARCROLE,
+    XLINK_SHOW,
+    AUTOCOMPLETE,
+    COLOR_PROFILE,
+    COLOR_INTERPOLATION_FILTERS,
+    FLOOD_OPACITY,
     ONLOAD,
-    ONDRAG,
-    ORIGIN,
-    ONZOOM,
-    ONHELP,
-    ONSTOP,
-    ONDROP,
-    ONBLUR,
-    OBJECT,
-    OFFSET,
-    ORIENT,
-    ONCOPY,
-    NOWRAP,
-    NOHREF,
-    MACROS,
-    METHOD,
-    LOWSRC,
-    LSPACE,
-    LQUOTE,
-    USEMAP,
-    WIDTHS,
-    TARGET,
-    VALUES,
-    VALIGN,
-    VSPACE,
-    POSTER,
-    POINTS,
-    PROMPT,
-    SCOPED,
-    STRING,
-    SCHEME,
-    STROKE,
-    RADIUS,
-    RESULT,
-    REPEAT,
-    RSPACE,
-    ROTATE,
+    ONFOCUSIN,
+    ONMOUSELEAVE,
+    ONMOUSEOUT,
     RQUOTE,
-    ALTTEXT,
-    ARCHIVE,
-    AZIMUTH,
-    CLOSURE,
-    CHECKED,
-    CLASSID,
-    CHAROFF,
-    BGCOLOR,
-    COLSPAN,
+    STROKE_LINEJOIN,
+    STROKE_WIDTH,
+    CLIP_RULE,
+    DISPLAYSTYLE,
+    HTTP_EQUIV,
+    SCOPED,
+    SHAPE,
+    TEMPLATE,
+    ATTRIBUTETYPE,
     CHARSET,
-    COMPACT,
-    CONTENT,
-    ENCTYPE,
-    DATASRC,
-    DATAFLD,
-    DECLARE,
-    DISPLAY,
-    DIVISOR,
-    DEFAULT,
-    DESCENT,
-    KERNING,
-    HANGING,
-    HEADERS,
-    ONPASTE,
-    ONCLICK,
-    OPTIMUM,
-    ONBEGIN,
-    ONKEYUP,
-    ONFOCUS,
-    ONERROR,
-    ONINPUT,
-    ONABORT,
-    ONSTART,
-    ONRESET,
-    OPACITY,
-    NOSHADE,
+    ONDRAGENTER,
+    ONDRAGDROP,
+    ONDRAGSTART,
+    AS,
+    CLASSID,
+    CLOSURE,
+    KEYSYSTEM,
     MINSIZE,
-    MAXSIZE,
-    LOOPEND,
-    LARGEOP,
-    UNICODE,
-    TARGETX,
-    TARGETY,
-    VIEWBOX,
-    VERSION,
-    PATTERN,
-    PROFILE,
-    SPACING,
-    RESTART,
     ROWSPAN,
-    SANDBOX,
-    SUMMARY,
-    STANDBY,
-    REPLACE,
-    AUTOPLAY,
-    ADDITIVE,
-    CALCMODE,
-    CODETYPE,
-    CODEBASE,
+    SUBSCRIPTSHIFT,
     CONTROLS,
-    BEVELLED,
-    BASELINE,
-    EXPONENT,
-    EDGEMODE,
-    ENCODING,
-    GLYPHREF,
-    DATETIME,
-    DISABLED,
+    ENCTYPE,
+    FONT_WEIGHT,
+    FONT_FAMILY,
     FONTSIZE,
-    KEYTIMES,
-    PANOSE_1,
-    HREFLANG,
-    ONRESIZE,
-    ONCHANGE,
-    ONBOUNCE,
-    ONUNLOAD,
-    ONFINISH,
-    ONSCROLL,
-    OPERATOR,
-    OVERFLOW,
+    LIST,
+    ONSTART,
+    PATTERNUNITS,
+    SYSTEMLANGUAGE,
+    TEXTLENGTH,
+    ACCUMULATE,
+    COLUMNSPACING,
     ONSUBMIT,
-    ONREPEAT,
-    ONSELECT,
-    NOTATION,
-    NORESIZE,
-    MANIFEST,
-    MATHSIZE,
-    MULTIPLE,
-    LONGDESC,
-    LANGUAGE,
-    TEMPLATE,
-    TABINDEX,
-    READONLY,
-    SELECTED,
-    ROWLINES,
-    SEAMLESS,
-    ROWALIGN,
-    STRETCHY,
-    REQUIRED,
-    XML_BASE,
+    RESULT,
+    VALUE,
+    CX,
+    REFX,
+    FY,
+    REFY,
+    ALT,
+    DUR,
+    FOR,
+    LOW,
+    MAX,
+    REV,
+    D,
+    X,
+    Z,
+    X1,
+    K2,
+    Y2,
+    K4,
     XML_LANG,
-    X_HEIGHT,
-    ARIA_OWNS,
-    AUTOFOCUS,
+    ARIA_VALUEMAX,
+    ARIA_DESCRIBEDBY,
+    ARIA_CHECKED,
+    ARIA_DROPEFFECT,
+    ARIA_EXPANDED,
+    ARIA_LEVEL,
+    ARIA_HIDDEN,
+    ARIA_POSINSET,
+    ARIA_INVALID,
+    ARIA_VALUEMIN,
+    ARIA_CONTROLS,
+    ARIA_READONLY,
+    ARIA_ACTIVEDESCENDANT,
+    ARIA_DATATYPE,
     ARIA_SORT,
-    ACCESSKEY,
-    ARIA_BUSY,
-    ARIA_GRAB,
-    AMPLITUDE,
+    ARIA_FLOWTO,
     ARIA_LIVE,
-    CLIP_RULE,
-    CLIP_PATH,
+    ARIA_SETSIZE,
+    DISABLED,
+    DATA,
     EQUALROWS,
-    ELEVATION,
-    DIRECTION,
-    DRAGGABLE,
-    FILTERRES,
-    FILL_RULE,
-    FONTSTYLE,
-    FONT_SIZE,
-    KEYPOINTS,
-    HIDEFOCUS,
-    ONMESSAGE,
-    INTERCEPT,
-    ONDRAGEND,
-    ONMOVEEND,
-    ONINVALID,
-    ONKEYDOWN,
-    ONFOCUSIN,
-    ONMOUSEUP,
-    INPUTMODE,
-    ONROWEXIT,
-    MATHCOLOR,
-    MASKUNITS,
-    MAXLENGTH,
-    LINEBREAK,
-    LOOPSTART,
-    TRANSFORM,
-    V_HANGING,
-    VALUETYPE,
-    POINTSATZ,
-    POINTSATX,
-    POINTSATY,
-    PLAYCOUNT,
-    SYMMETRIC,
-    SCROLLING,
-    REPEATDUR,
-    SELECTION,
+    ISMAP,
+    LSPACE,
+    NOTATION,
+    ONPASTE,
+    ROWALIGN,
     SEPARATOR,
-    XML_SPACE,
-    AUTOSUBMIT,
-    ALPHABETIC,
-    ACTIONTYPE,
-    ACCUMULATE,
-    ARIA_LEVEL,
-    COLUMNSPAN,
-    CAP_HEIGHT,
-    BACKGROUND,
-    GLYPH_NAME,
-    GROUPALIGN,
-    FONTFAMILY,
-    FONTWEIGHT,
-    FONT_STYLE,
-    KEYSPLINES,
-    HTTP_EQUIV,
-    ONACTIVATE,
-    OCCURRENCE,
-    IRRELEVANT,
+    VSPACE,
+    YCHANNELSELECTOR,
     ONDBLCLICK,
-    ONDRAGDROP,
-    ONKEYPRESS,
-    ONROWENTER,
-    ONDRAGOVER,
-    ONFOCUSOUT,
-    ONMOUSEOUT,
-    NUMOCTAVES,
-    MARKER_MID,
-    MARKER_END,
-    TEXTLENGTH,
-    VISIBILITY,
-    VIEWTARGET,
-    VERT_ADV_Y,
-    PATHLENGTH,
-    REPEAT_MAX,
-    RADIOGROUP,
-    STOP_COLOR,
-    SEPARATORS,
-    REPEAT_MIN,
-    ROWSPACING,
-    ZOOMANDPAN,
-    XLINK_TYPE,
-    XLINK_ROLE,
-    XLINK_HREF,
-    XLINK_SHOW,
+    CALCMODE,
+    FENCE,
+    NONCE,
+    ONACTIVATE,
+    SPACING,
+    SPECULARCONSTANT,
+    ID,
+    GRADIENTUNITS,
+    HEADERS,
+    READONLY,
+    SHADOWROOTMODE,
+    SHADOWROOTREFERENCETARGET,
+    SHADOWROOTSERIALIZABLE,
+    STDDEVIATION,
+    SHADOWROOTDELEGATESFOCUS,
     ACCENTUNDER,
-    ARIA_SECRET,
-    ARIA_ATOMIC,
-    ARIA_HIDDEN,
-    ARIA_FLOWTO,
-    ARABIC_FORM,
-    CELLPADDING,
-    CELLSPACING,
-    COLUMNWIDTH,
-    COLUMNALIGN,
-    COLUMNLINES,
-    CONTEXTMENU,
+    ACCESSKEY,
+    ACCEPT,
+    BASEFREQUENCY,
     BASEPROFILE,
-    FONT_FAMILY,
-    FRAMEBORDER,
-    FILTERUNITS,
-    FLOOD_COLOR,
-    FONT_WEIGHT,
-    HORIZ_ADV_X,
-    ONDRAGLEAVE,
-    ONMOUSEMOVE,
-    ORIENTATION,
-    ONMOUSEDOWN,
-    ONMOUSEOVER,
-    ONDRAGENTER,
-    IDEOGRAPHIC,
-    ONBEFORECUT,
-    ONFORMINPUT,
-    ONDRAGSTART,
-    ONMOVESTART,
-    MARKERUNITS,
-    MATHVARIANT,
-    MARGINWIDTH,
-    MARKERWIDTH,
-    TEXT_ANCHOR,
-    TABLEVALUES,
-    SCRIPTLEVEL,
+    BASE,
+    CODETYPE,
+    CITE,
+    DATETIME,
+    EDGEMODE,
+    ENTERKEYHINT,
+    INDEX,
+    INTEGRITY,
+    LABEL,
+    MODE,
+    NORESIZE,
+    ONREPEAT,
+    ONSELECT,
+    OTHER,
+    ONREADYSTATECHANGE,
+    ONBEGIN,
+    ORIENT,
+    ONBEFORECOPY,
+    ONBEFOREPASTE,
+    ONKEYUP,
+    ONKEYDOWN,
+    REPEAT,
+    RULES,
     REPEATCOUNT,
-    STITCHTILES,
-    STARTOFFSET,
-    SCROLLDELAY,
-    XMLNS_XLINK,
-    XLINK_TITLE,
-    ARIA_INVALID,
-    ARIA_PRESSED,
-    ARIA_CHECKED,
-    AUTOCOMPLETE,
-    ARIA_SETSIZE,
-    ARIA_CHANNEL,
-    EQUALCOLUMNS,
-    DISPLAYSTYLE,
-    DATAFORMATAS,
-    FILL_OPACITY,
-    FONT_VARIANT,
-    FONT_STRETCH,
-    FRAMESPACING,
-    KERNELMATRIX,
-    ONDEACTIVATE,
-    ONROWSDELETE,
-    ONMOUSELEAVE,
-    ONFORMCHANGE,
-    ONCELLCHANGE,
-    ONMOUSEWHEEL,
-    ONMOUSEENTER,
+    SELECTED,
+    SUPERSCRIPTSHIFT,
+    SCHEME,
+    SELECTION,
+    TYPE,
+    HREF,
     ONAFTERPRINT,
-    ONBEFORECOPY,
-    MARGINHEIGHT,
-    MARKERHEIGHT,
-    MARKER_START,
-    MATHEMATICAL,
-    LENGTHADJUST,
-    UNSELECTABLE,
-    UNICODE_BIDI,
-    UNITS_PER_EM,
-    WORD_SPACING,
-    WRITING_MODE,
-    V_ALPHABETIC,
-    PATTERNUNITS,
-    SPREADMETHOD,
     SURFACESCALE,
-    STROKE_WIDTH,
-    REPEAT_START,
-    STDDEVIATION,
-    STOP_OPACITY,
-    ARIA_CONTROLS,
-    ARIA_HASPOPUP,
-    ACCENT_HEIGHT,
-    ARIA_VALUENOW,
-    ARIA_RELEVANT,
-    ARIA_POSINSET,
-    ARIA_VALUEMAX,
-    ARIA_READONLY,
-    ARIA_SELECTED,
-    ARIA_REQUIRED,
-    ARIA_EXPANDED,
-    ARIA_DISABLED,
-    ATTRIBUTETYPE,
-    ATTRIBUTENAME,
-    ARIA_DATATYPE,
-    ARIA_VALUEMIN,
-    BASEFREQUENCY,
-    COLUMNSPACING,
-    COLOR_PROFILE,
-    CLIPPATHUNITS,
+    ALIGN,
+    ALIGNMENTSCOPE,
+    HEIGHT,
+    IMAGESRCSET,
+    LANGUAGE,
+    LARGEOP,
+    LENGTHADJUST,
+    MARGINWIDTH,
+    PING,
+    TARGETX,
+    ARCHIVE,
+    LIGHTING_COLOR,
+    METHOD,
+    MATHCOLOR,
+    NOSHADE,
+    PATHLENGTH,
+    ALTIMG,
+    ACTION,
+    ADDITIVE,
+    DOMINANT_BASELINE,
     DEFINITIONURL,
-    GRADIENTUNITS,
-    FLOOD_OPACITY,
-    ONAFTERUPDATE,
-    ONERRORUPDATE,
-    ONBEFOREPASTE,
-    ONLOSECAPTURE,
-    ONCONTEXTMENU,
-    ONSELECTSTART,
-    ONBEFOREPRINT,
-    MOVABLELIMITS,
-    LINETHICKNESS,
-    UNICODE_RANGE,
-    THINMATHSPACE,
-    VERT_ORIGIN_X,
-    VERT_ORIGIN_Y,
-    V_IDEOGRAPHIC,
-    PRESERVEALPHA,
+    MEDIA,
+    ONFINISH,
+    RADIOGROUP,
+    SCRIPTLEVEL,
     SCRIPTMINSIZE,
-    SPECIFICATION,
+    VALIGN,
+    BACKGROUND,
+    MARKER_MID,
+    MARKER_END,
+    MARKER_START,
+    MASKUNITS,
+    MASKCONTENTUNITS,
+    CELLSPACING,
+    DECLARE,
+    FILL,
+    MAXLENGTH,
+    ONBLUR,
+    ROWLINES,
+    STYLE,
+    TITLE,
+    FORMAT,
+    FRAME,
+    FROM,
+    PROMPT,
+    SYMMETRIC,
+    USEMAP,
+    ASYNC,
+    IN,
+    ICON,
+    KERNING,
+    ONUNLOAD,
+    ONINVALID,
+    ONINPUT,
+    POINTS,
+    POINTSATY,
+    SPAN,
+    TRANSFORM_ORIGIN,
+    VLINK,
+    XLINK_HREF,
+    XLINK_ROLE,
+    XMLNS_XLINK,
+    XLINK_TYPE,
     XLINK_ACTUATE,
-    XLINK_ARCROLE,
-    ACCEPT_CHARSET,
-    ALIGNMENTSCOPE,
-    ARIA_MULTILINE,
-    BASELINE_SHIFT,
-    HORIZ_ORIGIN_X,
-    HORIZ_ORIGIN_Y,
-    ONBEFOREUPDATE,
-    ONFILTERCHANGE,
-    ONROWSINSERTED,
-    ONBEFOREUNLOAD,
-    MATHBACKGROUND,
-    LETTER_SPACING,
-    LIGHTING_COLOR,
-    THICKMATHSPACE,
-    TEXT_RENDERING,
-    V_MATHEMATICAL,
-    POINTER_EVENTS,
-    PRIMITIVEUNITS,
-    SYSTEMLANGUAGE,
-    STROKE_LINECAP,
-    SUBSCRIPTSHIFT,
-    STROKE_OPACITY,
-    ARIA_DROPEFFECT,
-    ARIA_LABELLEDBY,
-    ARIA_TEMPLATEID,
+    AUTOCORRECT,
+    AUTOFOCUS,
+    BGCOLOR,
     COLOR_RENDERING,
-    CONTENTEDITABLE,
-    DIFFUSECONSTANT,
-    ONDATAAVAILABLE,
-    ONCONTROLSELECT,
-    IMAGE_RENDERING,
-    MEDIUMMATHSPACE,
-    TEXT_DECORATION,
-    SHAPE_RENDERING,
-    STROKE_LINEJOIN,
-    REPEAT_TEMPLATE,
-    ARIA_DESCRIBEDBY,
-    CONTENTSTYLETYPE,
-    FONT_SIZE_ADJUST,
-    KERNELUNITLENGTH,
-    ONBEFOREACTIVATE,
-    ONPROPERTYCHANGE,
-    ONDATASETCHANGED,
-    MASKCONTENTUNITS,
-    PATTERNTRANSFORM,
-    REQUIREDFEATURES,
-    RENDERING_INTENT,
-    SPECULAREXPONENT,
-    SPECULARCONSTANT,
-    SUPERSCRIPTSHIFT,
-    STROKE_DASHARRAY,
-    XCHANNELSELECTOR,
-    YCHANNELSELECTOR,
-    ARIA_AUTOCOMPLETE,
-    CONTENTSCRIPTTYPE,
-    ENABLE_BACKGROUND,
-    DOMINANT_BASELINE,
-    GRADIENTTRANSFORM,
-    ONBEFORDEACTIVATE,
-    ONDATASETCOMPLETE,
-    OVERLINE_POSITION,
-    ONBEFOREEDITFOCUS,
-    LIMITINGCONEANGLE,
-    VERYTHINMATHSPACE,
+    COLOR,
+    ENCODING,
+    FLOOD_COLOR,
+    LQUOTE,
+    NOMODULE,
+    ONMOUSEWHEEL,
+    ONMOUSEOVER,
+    ONCONTEXTMENU,
+    ONCOPY,
+    ONMOUSEMOVE,
+    ONFOCUS,
+    ONFOCUSOUT,
+    TO,
+    STROKE_LINECAP,
     STROKE_DASHOFFSET,
     STROKE_MITERLIMIT,
-    ALIGNMENT_BASELINE,
-    ONREADYSTATECHANGE,
-    OVERLINE_THICKNESS,
-    UNDERLINE_POSITION,
-    VERYTHICKMATHSPACE,
-    REQUIREDEXTENSIONS,
-    COLOR_INTERPOLATION,
-    UNDERLINE_THICKNESS,
+    SCROLLING,
+    STROKE_OPACITY,
+    CLIP,
+    CLIP_PATH,
+    DISPLAY,
+    GLYPH_ORIENTATION_VERTICAL,
+    GLYPHREF,
+    KEYPOINTS,
+    PROPERTY,
+    STEP,
+    SCOPE,
+    SLOPE,
+    STOP_OPACITY,
+    WRAP,
+    ATTRIBUTENAME,
+    CHAR,
+    CHAROFF,
+    NOWRAP,
+    ONDRAG,
+    ONDRAGOVER,
+    ONDROP,
+    ONERROR,
+    OVERFLOW,
+    ONDRAGLEAVE,
+    START,
+    AXIS,
+    COLSPAN,
+    CROSSORIGIN,
+    CURSOR,
+    CLOSE,
+    IS,
+    KEYSPLINES,
+    MAXSIZE,
+    OFFSET,
     PRESERVEASPECTRATIO,
+    ROWSPACING,
+    SRCSET,
+    VERSION,
+    CONTENTEDITABLE,
+    CONTENT,
+    DEPTH,
+    FONT_STRETCH,
+    FONTWEIGHT,
+    FONTSTYLE,
+    FONTFAMILY,
+    FONT_VARIANT,
+    FILTERUNITS,
+    FONT_SIZE,
+    LETTER_SPACING,
+    MULTIPLE,
+    ONSTOP,
+    POSTER,
+    PATTERN,
     PATTERNCONTENTUNITS,
-    ARIA_MULTISELECTABLE,
-    SCRIPTSIZEMULTIPLIER,
-    ARIA_ACTIVEDESCENDANT,
-    VERYVERYTHINMATHSPACE,
-    VERYVERYTHICKMATHSPACE,
-    STRIKETHROUGH_POSITION,
-    STRIKETHROUGH_THICKNESS,
-    EXTERNALRESOURCESREQUIRED,
-    GLYPH_ORIENTATION_VERTICAL,
-    COLOR_INTERPOLATION_FILTERS,
-    GLYPH_ORIENTATION_HORIZONTAL,
+    STITCHTILES,
+    TEXT_RENDERING,
+    TEXT_ANCHOR,
+    TEXT,
+    WIDTH,
+    COLUMNSPAN,
+    COLUMNALIGN,
+    COLUMNWIDTH,
+    INPUTMODE,
+    ONCUT,
+    REQUIREDFEATURES,
+    REQUIREDEXTENSIONS,
+    VALUETYPE,
+    ELEVATION,
+    VIEWBOX,
+    DX,
+    RX,
+    BY,
+    DY,
     };
     private final static int[] ATTRIBUTE_HASHES = {
-    1153,
-    1383,
-    1601,
-    1793,
-    1827,
-    1857,
-    68600,
-    69146,
-    69177,
-    70237,
-    70270,
-    71572,
-    71669,
-    72415,
-    72444,
-    74846,
-    74904,
-    74943,
-    75001,
-    75276,
-    75590,
-    84742,
-    84839,
-    85575,
-    85963,
-    85992,
-    87204,
-    88074,
-    88171,
-    89130,
-    89163,
-    3207892,
-    3283895,
-    3284791,
-    3338752,
-    3358197,
-    3369562,
-    3539124,
-    3562402,
-    3574260,
-    3670335,
-    3696933,
-    3721879,
-    135280021,
-    135346322,
-    136317019,
-    136475749,
-    136548517,
-    136652214,
-    136884919,
-    136902418,
-    136942992,
-    137292068,
-    139120259,
-    139785574,
-    142250603,
-    142314056,
-    142331176,
-    142519584,
-    144752417,
-    145106895,
-    146147200,
-    146765926,
-    148805544,
-    149655723,
-    149809441,
-    150018784,
-    150445028,
-    150923321,
-    152528754,
-    152536216,
-    152647366,
-    152962785,
-    155219321,
-    155654904,
-    157317483,
-    157350248,
-    157437941,
-    157447478,
-    157604838,
-    157685404,
-    157894402,
-    158315188,
-    166078431,
-    169409980,
-    169700259,
-    169856932,
-    170007032,
-    170409695,
-    170466488,
-    170513710,
-    170608367,
-    173028944,
-    173896963,
-    176090625,
-    176129212,
-    179390001,
-    179489057,
-    179627464,
-    179840468,
-    179849042,
-    180004216,
-    181779081,
-    183027151,
-    183645319,
-    183698797,
-    185922012,
-    185997252,
-    188312483,
-    188675799,
-    190977533,
-    190992569,
-    191006194,
-    191033518,
-    191038774,
-    191096249,
-    191166163,
-    191194426,
-    191522106,
-    191568039,
-    200104642,
-    202506661,
-    202537381,
-    202602917,
-    203070590,
-    203120766,
-    203389054,
-    203690071,
-    203971238,
-    203986524,
-    209040857,
-    209125756,
-    212055489,
-    212322418,
-    212746849,
-    213002877,
-    213055164,
-    213088023,
-    213259873,
-    213273386,
-    213435118,
-    213437318,
-    213438231,
-    213493071,
-    213532268,
-    213542834,
-    213584431,
-    213659891,
-    215285828,
-    215880731,
-    216112976,
-    216684637,
-    217369699,
-    217565298,
-    217576549,
-    218186795,
-    219743185,
-    220082234,
-    221623802,
-    221986406,
-    222283890,
-    223089542,
-    223138630,
-    223311265,
-    224547358,
-    224587256,
-    224589550,
-    224655650,
-    224785518,
-    224810917,
-    224813302,
-    225429618,
-    225432950,
-    225440869,
-    236107233,
-    236709921,
-    236838947,
-    237117095,
-    237143271,
-    237172455,
-    237209953,
-    237354143,
-    237372743,
-    237668065,
-    237703073,
-    237714273,
-    239743521,
-    240512803,
-    240522627,
-    240560417,
-    240656513,
-    241015715,
-    241062755,
-    241065383,
-    243523041,
-    245865199,
-    246261793,
-    246556195,
-    246774817,
-    246923491,
-    246928419,
-    246981667,
-    247014847,
-    247058369,
-    247112833,
-    247118177,
-    247119137,
-    247128739,
-    247316903,
-    249533729,
-    250235623,
-    250269543,
-    251083937,
-    251402351,
-    252339047,
-    253260911,
-    253293679,
-    254844367,
-    255547879,
-    256077281,
-    256345377,
-    258124199,
-    258354465,
-    258605063,
-    258744193,
-    258845603,
-    258856961,
-    258926689,
-    269869248,
-    270174334,
-    270709417,
-    270778994,
-    270781796,
-    271102503,
-    271478858,
-    271490090,
-    272870654,
-    273335275,
-    273369140,
-    273924313,
-    274108530,
-    274116736,
-    276818662,
-    277476156,
-    279156579,
-    279349675,
-    280108533,
-    280128712,
-    280132869,
-    280162403,
-    280280292,
-    280413430,
-    280506130,
-    280677397,
-    280678580,
-    280686710,
-    280689066,
-    282736758,
-    283110901,
-    283275116,
-    283823226,
-    283890012,
-    284479340,
-    284606461,
-    286700477,
-    286798916,
-    291557706,
-    291665349,
-    291804100,
-    292138018,
-    292166446,
-    292418738,
-    292451039,
-    300298041,
-    300374839,
-    300597935,
-    303073389,
-    303083839,
-    303266673,
-    303354997,
-    303430688,
-    303576261,
-    303724281,
-    303819694,
-    304242723,
-    304382625,
-    306247792,
-    307227811,
-    307468786,
-    307724489,
-    309671175,
-    310252031,
-    310358241,
-    310373094,
-    311015256,
-    313357609,
-    313683893,
-    313701861,
-    313706996,
-    313707317,
-    313710350,
-    314027746,
-    314038181,
-    314091299,
-    314205627,
-    314233813,
-    316741830,
-    316797986,
-    317486755,
-    317794164,
-    318721061,
-    320076137,
-    322657125,
-    322887778,
-    323506876,
-    323572412,
-    323605180,
-    323938869,
-    325060058,
-    325320188,
-    325398738,
-    325541490,
-    325671619,
-    333868843,
-    336806130,
-    337212108,
-    337282686,
-    337285434,
-    337585223,
-    338036037,
-    338298087,
-    338566051,
-    340943551,
-    341190970,
-    342995704,
-    343352124,
-    343912673,
-    344585053,
-    346977248,
-    347218098,
-    347262163,
-    347278576,
-    347438191,
-    347655959,
-    347684788,
-    347726430,
-    347727772,
-    347776035,
-    347776629,
-    349500753,
-    350880161,
-    350887073,
-    353384123,
-    355496998,
-    355906922,
-    355979793,
-    356545959,
-    358637867,
-    358905016,
-    359164318,
-    359247286,
-    359350571,
-    359579447,
-    365560330,
-    367399355,
-    367420285,
-    367510727,
-    368013212,
-    370234760,
-    370353345,
-    370710317,
-    371074566,
-    371122285,
-    371194213,
-    371448425,
-    371448430,
-    371545055,
-    371596922,
-    371758751,
-    371964792,
-    372151328,
-    376550136,
-    376710172,
-    376795771,
-    376826271,
-    376906556,
-    380514830,
-    380774774,
-    380775037,
-    381030322,
-    381136500,
-    381281631,
-    381282269,
-    381285504,
-    381330595,
-    381331422,
-    381335911,
-    381336484,
-    383907298,
-    383917408,
-    384595009,
-    384595013,
-    387799894,
-    387823201,
-    392581647,
-    392584937,
-    392742684,
-    392906485,
-    393003349,
-    400644707,
-    400973830,
-    404428547,
-    404432113,
-    404432865,
-    404469244,
-    404478897,
-    404694860,
-    406887479,
-    408294949,
-    408789955,
-    410022510,
-    410467324,
-    410586448,
-    410945965,
-    411845275,
-    414327152,
-    414327932,
-    414329781,
-    414346257,
-    414346439,
-    414639928,
-    414835998,
-    414894517,
-    414986533,
-    417465377,
-    417465381,
-    417492216,
-    418259232,
-    419310946,
-    420103495,
-    420242342,
-    420380455,
-    420658662,
-    420717432,
-    423183880,
-    424539259,
-    425929170,
-    425972964,
-    426050649,
-    426126450,
-    426142833,
-    426607922,
-    437289840,
-    437347469,
-    437412335,
-    437423943,
-    437455540,
-    437462252,
-    437597991,
-    437617485,
-    437986305,
-    437986507,
-    437986828,
-    437987072,
-    438015591,
-    438034813,
-    438038966,
-    438179623,
-    438347971,
-    438483573,
-    438547062,
-    438895551,
-    441592676,
-    442032555,
-    443548979,
-    447881379,
-    447881655,
-    447881895,
-    447887844,
-    448416189,
-    448445746,
-    448449012,
-    450942191,
-    452816744,
-    453668677,
-    454434495,
-    456610076,
-    456642844,
-    456738709,
-    457544600,
-    459451897,
-    459680944,
-    468058810,
-    468083581,
-    470964084,
-    471470955,
-    471567278,
-    472267822,
-    481177859,
-    481210627,
-    481435874,
-    481455115,
-    481485378,
-    481490218,
-    485105638,
-    486005878,
-    486383494,
-    487988916,
-    488103783,
-    490661867,
-    491574090,
-    491578272,
-    493041952,
-    493441205,
-    493582844,
-    493716979,
-    504577572,
-    504740359,
-    505091638,
-    505592418,
-    505656212,
-    509516275,
-    514998531,
-    515571132,
-    515594682,
-    518712698,
-    521362273,
-    526592419,
-    526807354,
-    527348842,
-    538294791,
-    539214049,
-    544689535,
-    545535009,
-    548544752,
-    548563346,
-    548595116,
-    551679010,
-    558034099,
-    560329411,
-    560356209,
-    560671018,
-    560671152,
-    560692590,
-    560845442,
-    569212097,
-    569474241,
-    572252718,
-    572768481,
-    575326764,
-    576174758,
-    576190819,
-    582099184,
-    582099438,
-    582372519,
-    582558889,
-    586552164,
-    591325418,
-    594231990,
-    594243961,
-    605711268,
-    615672071,
-    616086845,
-    621792370,
-    624879850,
-    627432831,
-    640040548,
-    654392808,
-    658675477,
-    659420283,
-    672891587,
-    694768102,
-    705890982,
-    725543146,
-    759097578,
-    761686526,
-    795383908,
-    843809551,
-    878105336,
-    908643300,
-    945213471,
+    1854497003,
+    1747939528,
+    1941454586,
+    1681174213,
+    1776114564,
+    1915025672,
+    2001669450,
+    1680165421,
+    1721347639,
+    1754792749,
+    1805715716,
+    1898428101,
+    1922699851,
+    1983347764,
+    2016787611,
+    71827457,
+    1680282148,
+    1689324870,
+    1740045858,
+    1752985897,
+    1756471625,
+    1788254870,
+    1823580230,
+    1874698443,
+    1906423097,
+    1921894426,
+    1933145837,
+    1972863609,
+    1991392548,
+    2007019632,
+    2060302634,
+    57205395,
+    911736834,
+    1680181996,
+    1680368221,
+    1685882101,
+    1704526375,
+    1734182982,
+    1747299630,
+    1749027145,
+    1754606246,
+    1754907227,
+    1757053236,
+    1785174319,
+    1804036350,
+    1816144023,
+    1853862084,
+    1867620412,
+    1884343396,
+    1905628916,
+    1910441627,
+    1916278099,
+    1922567078,
+    1924585254,
+    1937777860,
+    1966439670,
+    1974849131,
+    1988132214,
+    2000162011,
+    2004199576,
+    2009071951,
+    2024616088,
+    2081947650,
+    53006051,
+    60345635,
+    885522434,
+    1680095865,
+    1680165533,
+    1680229115,
+    1680343801,
+    1680437801,
+    1682440540,
+    1687620127,
+    1692408896,
+    1716623661,
+    1731048742,
+    1739583824,
+    1740130375,
+    1747792072,
+    1748552744,
+    1749856356,
+    1754214628,
+    1754645079,
+    1754858317,
+    1756190926,
+    1756804936,
+    1767875272,
+    1782518297,
+    1786821704,
+    1791070327,
+    1804235064,
+    1814656326,
+    1820928104,
+    1824377064,
+    1854464212,
+    1865910347,
+    1873590471,
+    1884142379,
+    1891186903,
+    1903612236,
+    1906408542,
+    1908462185,
+    1910503637,
+    1915394254,
+    1917327080,
+    1922413292,
+    1922671417,
+    1924462384,
+    1932870919,
+    1934917372,
+    1941409583,
+    1965349396,
+    1972196486,
+    1972909592,
+    1982640164,
+    1983461061,
+    1990062797,
+    1999273799,
+    2001578182,
+    2001814704,
+    2005925890,
+    2008084807,
+    2010452700,
+    2018908874,
+    2026741958,
+    2066743298,
+    2089811970,
+    52488851,
+    55077603,
+    59825747,
+    68157441,
+    878182402,
+    901775362,
+    1037879561,
+    1680159327,
+    1680165437,
+    1680165692,
+    1680198203,
+    1680231247,
+    1680315086,
+    1680345965,
+    1680413393,
+    1680452349,
+    1681879063,
+    1683805446,
+    1686731997,
+    1689048326,
+    1689839946,
+    1699185409,
+    1714763319,
+    1721189160,
+    1723336432,
+    1733874289,
+    1736416327,
+    1739927860,
+    1740096054,
+    1742183484,
+    1747446838,
+    1747839118,
+    1748306996,
+    1748869205,
+    1749399124,
+    1751679545,
+    1753297133,
+    1754546894,
+    1754643237,
+    1754647353,
+    1754798923,
+    1754872618,
+    1754958648,
+    1756302628,
+    1756737685,
+    1756874572,
+    1765800271,
+    1772032615,
+    1780975314,
+    1785051290,
+    1786740932,
+    1787193500,
+    1790814502,
+    1801312388,
+    1804069019,
+    1804978712,
+    1814558026,
+    1814986837,
+    1820262641,
+    1822002839,
+    1823841492,
+    1825677514,
+    1854302364,
+    1854474395,
+    1864698185,
+    1867448617,
+    1872034503,
+    1874261045,
+    1881750231,
+    1884267068,
+    1889633006,
+    1894552650,
+    1900548965,
+    1903759600,
+    1905754853,
+    1906419001,
+    1907701479,
+    1909819252,
+    1910441773,
+    1910527802,
+    1915295948,
+    1916210285,
+    1916337499,
+    1917953597,
+    1922319046,
+    1922470745,
+    1922665052,
+    1922679386,
+    1924206934,
+    1924570799,
+    1924738716,
+    1932986153,
+    1933508940,
+    1935597338,
+    1941253366,
+    1941438085,
+    1942026440,
+    1965561677,
+    1966454567,
+    1972744939,
+    1972904522,
+    1972962123,
+    1980235778,
+    1983266615,
+    1983416119,
+    1987410233,
+    1988788535,
+    1991021879,
+    1991643278,
+    2000125224,
+    2001210183,
+    2001634459,
+    2001710299,
+    2001898808,
+    2004957380,
+    2006516551,
+    2007064812,
+    2008408414,
+    2009141482,
+    2015950026,
+    2016910397,
+    2023146024,
+    2024763702,
+    2026975253,
+    2065170434,
+    2075005220,
+    2083520514,
+    2091784484,
+    50917059,
+    52489043,
+    53537523,
+    56685811,
+    57210387,
+    59830867,
+    60817409,
+    71303169,
+    72351745,
+    884998146,
+    894959618,
+    902299650,
+    928514050,
+    1038063816,
+    1680140893,
+    1680159328,
+    1680165436,
+    1680165487,
+    1680165613,
+    1680181850,
+    1680185931,
+    1680198381,
+    1680230940,
+    1680251485,
+    1680311085,
+    1680323325,
+    1680345685,
+    1680347981,
+    1680411449,
+    1680433915,
+    1680446153,
+    1680511804,
+    1681733672,
+    1681969220,
+    1682587945,
+    1684319541,
+    1685902598,
+    1687164232,
+    1687751191,
+    1689130184,
+    1689788441,
+    1691145478,
+    1692933184,
+    1704262346,
+    1714745560,
+    1716303957,
+    1720503541,
+    1721305962,
+    1723309623,
+    1723336528,
+    1732771842,
+    1733919469,
+    1734404167,
+    1739561208,
+    1739914974,
+    1739962169,
+    1740045862,
+    1740119884,
+    1740222216,
+    1747295467,
+    1747309881,
+    1747479606,
+    1747800157,
+    1747906667,
+    1748021284,
+    1748503880,
+    1748566068,
+    1748971848,
+    1749350104,
+    1749549708,
+    1751507685,
+    1751755561,
+    1753049109,
+    1753550036,
+    1754434872,
+    1754579720,
+    1754612424,
+    1754644293,
+    1754647074,
+    1754698327,
+    1754794646,
+    1754835516,
+    1754860061,
+    1754899031,
+    1754927689,
+    1756147974,
+    1756219733,
+    1756360955,
+    1756704824,
+    1756762256,
+    1756836998,
+    1756889417,
+    1757421892,
+    1767725700,
+    1771569964,
+    1773606972,
+    1780879045,
+    1781007934,
+    1784574102,
+    1785053243,
+    1786622296,
+    1786775671,
+    1786851500,
+    1787365531,
+    1788842244,
+    1791068279,
+    1797886599,
+    1803561214,
+    1804054854,
+    1804081401,
+    1804405895,
+    1805715690,
+    1814517574,
+    1814560070,
+    1814656840,
+    1816104145,
+    1816178925,
+    1820727381,
+    1821958888,
+    1823574314,
+    1823829083,
+    1824159037,
+    1825437894,
+    1848600826,
+    1854285018,
+    1854366938,
+    1854466380,
+    1854497001,
+    1854497008,
+    1865910331,
+    1866496199,
+    1867462756,
+    1871251689,
+    1872343590,
+    1873656984,
+    1874270021,
+    1874788501,
+    1884079398,
+    1884246821,
+    1884295780,
+    1889569526,
+    1890996553,
+    1891937366,
+    1898415413,
+    1900544002,
+    1902640276,
+    1903659239,
+    1905541832,
+    1905672729,
+    1905902311,
+    1906408598,
+    1906421049,
+    1907660596,
+    1908316832,
+    1909438149,
+    1910328970,
+    1910441770,
+    1910487243,
+    1910507338,
+    1910572893,
+    1915048235,
+    1915341049,
+    1915757815,
+    1916247343,
+    1916286197,
+    1917295176,
+    1917857531,
+    1921061206,
+    1921977416,
+    1922400908,
+    1922413307,
+    1922566877,
+    1922607670,
+    1922665179,
+    1922677495,
+    1922679610,
+    1923088386,
+    1924443742,
+    1924517489,
+    1924583073,
+    1924629705,
+    1924773438,
+    1932959284,
+    1933123337,
+    1933369607,
+    1934917290,
+    1934970504,
+    1937336473,
+    1939976792,
+    1941286708,
+    1941435445,
+    1941440197,
+    1941550652,
+    1943317364,
+    1965512429,
+    1966384692,
+    1966442279,
+    1972151670,
+    1972656710,
+    1972744954,
+    1972904518,
+    1972908839,
+    1972922984,
+    1972996699,
+    1975062341,
+    1982254612,
+    1983157559,
+    1983290011,
+    1983398182,
+    1983432389,
+    1984430082,
+    1987422362,
+    1988784439,
+    1989522022,
+    1990107683,
+    1991220282,
+    1991625270,
+    1993343287,
+    2000096287,
+    2000160071,
+    2000752725,
+    2001527900,
+    2001634458,
+    2001669449,
+    2001710298,
+    2001732764,
+    2001826027,
+    2001898809,
+    2004846654,
+    2005342360,
+    2006459190,
+    2006824246,
+    2007021895,
+    2007064819,
+    2008401563,
+    2009041198,
+    2009079867,
+    2009231684,
+    2010716309,
+    2016711994,
+    2016810187,
+    2017010843,
+    2019887833,
+    2023342821,
+    2024647008,
+    2024794274,
+    2026893641,
+    2034765641,
+    2060474743,
+    2065694722,
+    2073034754,
+    2081423362,
+    2082471938,
     };
-
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/CoalescingTreeBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/CoalescingTreeBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/CoalescingTreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/CoalescingTreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,34 +1,34 @@
 /*
  * Copyright (c) 2008-2010 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
-import nu.validator.htmlparser.annotation.NoLength;
-
 import org.xml.sax.SAXException;
 
+import nu.validator.htmlparser.annotation.NoLength;
+
 /**
  * A common superclass for tree builders that coalesce their text nodes.
- * 
+ *
  * @version $Id$
  * @author hsivonen
  */
@@ -36,15 +36,8 @@ public abstract class CoalescingTreeBuil
 
     protected final void accumulateCharacters(@NoLength char[] buf, int start,
             int length) throws SAXException {
-        int newLen = charBufferLen + length;
-        if (newLen > charBuffer.length) {
-            char[] newBuf = new char[newLen];
-            System.arraycopy(charBuffer, 0, newBuf, 0, charBufferLen);
-            charBuffer = null; // release the old buffer in C++
-            charBuffer = newBuf;
-        }
         System.arraycopy(buf, start, charBuffer, charBufferLen, length);
-        charBufferLen = newLen;
+        charBufferLen += length;
     }
 
     /**
@@ -55,13 +48,6 @@ public abstract class CoalescingTreeBuil
         appendCharacters(parent, new String(buf, start, length));
     }
 
-    /**
-     * @see nu.validator.htmlparser.impl.TreeBuilder#appendIsindexPrompt(java.lang.Object)
-     */
-    @Override protected void appendIsindexPrompt(T parent) throws SAXException {
-        appendCharacters(parent, "This is a searchable index. Enter search keywords: ");
-    }
-
     protected abstract void appendCharacters(T parent, String text) throws SAXException;
 
     /**
@@ -73,7 +59,7 @@ public abstract class CoalescingTreeBuil
     }
 
     protected abstract void appendComment(T parent, String comment) throws SAXException;
-    
+
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilder#appendCommentToDocument(char[], int, int)
      */
@@ -84,7 +70,7 @@ public abstract class CoalescingTreeBuil
     }
 
     protected abstract void appendCommentToDocument(String comment) throws SAXException;
-    
+
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilder#insertFosterParentedCharacters(char[], int, int, java.lang.Object, java.lang.Object)
      */
@@ -92,6 +78,6 @@ public abstract class CoalescingTreeBuil
             int length, T table, T stackParent) throws SAXException {
         insertFosterParentedCharacters(new String(buf, start, length), table, stackParent);
     }
-    
+
     protected abstract void insertFosterParentedCharacters(String text, T table, T stackParent) throws SAXException;
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/ElementName.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/ElementName.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/ElementName.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/ElementName.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,38 +1,52 @@
 /*
- * Copyright (c) 2008-2011 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
-import java.util.Arrays;
+// uncomment to regenerate self
+//import java.io.BufferedReader;
+//import java.io.File;
+//import java.io.FileInputStream;
+//import java.io.IOException;
+//import java.io.InputStreamReader;
+//import java.util.Arrays;
+//import java.util.Collections;
+//import java.util.HashMap;
+//import java.util.LinkedList;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Map.Entry;
+//import java.util.regex.Matcher;
+//import java.util.regex.Pattern;
 
 import nu.validator.htmlparser.annotation.Inline;
 import nu.validator.htmlparser.annotation.Local;
 import nu.validator.htmlparser.annotation.NoLength;
-import nu.validator.htmlparser.annotation.Virtual;
+import nu.validator.htmlparser.annotation.Unsigned;
 import nu.validator.htmlparser.common.Interner;
 
 public final class ElementName
-// uncomment when regenerating self
-//        implements Comparable<ElementName> 
+        // uncomment when regenerating self
+//        implements Comparable<ElementName>
 {
 
     /**
@@ -41,14 +55,14 @@ public final class ElementName
     public static final int GROUP_MASK = 127;
 
     /**
-     * Indicates that the element is not a pre-interned element. Forbidden 
-     * on preinterned elements.
+     * Indicates that the element is not a pre-interned element. Forbidden on
+     * preinterned elements.
      */
-    public static final int CUSTOM = (1 << 30);
+    public static final int NOT_INTERNED = (1 << 30);
 
     /**
-     * Indicates that the element is in the "special" category. This bit
-     * should not be pre-set on MathML or SVG specials--only on HTML specials.
+     * Indicates that the element is in the "special" category. This bit should
+     * not be pre-set on MathML or SVG specials--only on HTML specials.
      */
     public static final int SPECIAL = (1 << 29);
 
@@ -59,8 +73,8 @@ public final class ElementName
     public static final int FOSTER_PARENTING = (1 << 28);
 
     /**
-     * The element is scoping. This bit should be pre-set on elements
-     * that are scoping as HTML.
+     * The element is scoping. This bit should be pre-set on elements that are
+     * scoping as HTML.
      */
     public static final int SCOPING = (1 << 27);
 
@@ -84,103 +98,269 @@ public final class ElementName
      */
     public static final int OPTIONAL_END_TAG = (1 << 23);
 
-    public static final ElementName NULL_ELEMENT_NAME = new ElementName(null);
+    private @Local String name;
 
-    public final @Local String name;
+    private @Local String camelCaseName;
 
-    public final @Local String camelCaseName;
+    // CPPONLY: private @HtmlCreator Object htmlCreator;
+
+    // CPPONLY: private @SvgCreator Object svgCreator;
 
     /**
      * The lowest 7 bits are the dispatch group. The high bits are flags.
      */
     public final int flags;
 
+    @Inline public @Local String getName() {
+        return name;
+    }
+
+    @Inline public @Local String getCamelCaseName() {
+        return camelCaseName;
+    }
+
+    // CPPONLY: @Inline public @HtmlCreator Object getHtmlCreator() {
+    // CPPONLY: return htmlCreator;
+    // CPPONLY: }
+
+    // CPPONLY: @Inline public @SvgCreator Object getSvgCreator() {
+    // CPPONLY: return svgCreator;
+    // CPPONLY: }
+
     @Inline public int getFlags() {
         return flags;
     }
-    
-    public int getGroup() {
-        return flags & GROUP_MASK;
+
+    @Inline public int getGroup() {
+        return flags & ElementName.GROUP_MASK;
     }
-    
-    // [NOCPP[
-    
-    public boolean isCustom() {
-        return (flags & CUSTOM) != 0;
+
+    @Inline public boolean isInterned() {
+        return (flags & ElementName.NOT_INTERNED) == 0;
     }
-    
-    // ]NOCPP]
 
-    static ElementName elementNameByBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
-        int hash = ElementName.bufToHash(buf, length);
-        int index = Arrays.binarySearch(ElementName.ELEMENT_HASHES, hash);
+    @Inline static int levelOrderBinarySearch(int[] data, int key) {
+        int n = data.length;
+        int i = 0;
+
+        while (i < n) {
+            int val = data[i];
+            if (val < key) {
+                i = 2 * i + 2;
+            } else if (val > key) {
+                i = 2 * i + 1;
+            } else {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    @Inline static ElementName elementNameByBuffer(@NoLength char[] buf,
+            int length) {
+        @Unsigned int hash = ElementName.bufToHash(buf, length);
+        int[] hashes;
+        hashes = ElementName.ELEMENT_HASHES;
+        int index = levelOrderBinarySearch(hashes, hash);
         if (index < 0) {
-            return new ElementName(Portability.newLocalNameFromBuffer(buf, offset, length, interner));
+            return null;
         } else {
             ElementName elementName = ElementName.ELEMENT_NAMES[index];
             @Local String name = elementName.name;
-            if (!Portability.localEqualsBuffer(name, buf, offset, length)) {
-                return new ElementName(Portability.newLocalNameFromBuffer(buf,
-                        offset, length, interner));
+            if (!Portability.localEqualsBuffer(name, buf, length)) {
+                return null;
             }
             return elementName;
         }
     }
 
     /**
-     * This method has to return a unique integer for each well-known
+     * This method has to return a unique positive integer for each well-known
      * lower-cased element name.
-     * 
+     *
      * @param buf
      * @param len
      * @return
      */
-    private static int bufToHash(@NoLength char[] buf, int len) {
-        int hash = len;
-        hash <<= 5;
-        hash += buf[0] - 0x60;
-        int j = len;
-        for (int i = 0; i < 4 && j > 0; i++) {
-            j--;
-            hash <<= 5;
-            hash += buf[j] - 0x60;
+    @Inline private static @Unsigned int bufToHash(@NoLength char[] buf,
+            int length) {
+        @Unsigned int len = length;
+        @Unsigned int first = buf[0];
+        first <<= 19;
+        @Unsigned int second = 1 << 23;
+        @Unsigned int third = 0;
+        @Unsigned int fourth = 0;
+        @Unsigned int fifth = 0;
+        if (length >= 4) {
+            second = buf[length - 4];
+            second <<= 4;
+            third = buf[length - 3];
+            third <<= 9;
+            fourth = buf[length - 2];
+            fourth <<= 14;
+            fifth = buf[length - 1];
+            fifth <<= 24;
+        } else if (length == 3) {
+            second = buf[1];
+            second <<= 4;
+            third = buf[2];
+            third <<= 9;
+        } else if (length == 2) {
+            second = buf[1];
+            second <<= 24;
         }
-        return hash;
+        return len + first + second + third + fourth + fifth;
     }
 
     private ElementName(@Local String name, @Local String camelCaseName,
+            // CPPONLY: @HtmlCreator Object htmlCreator, @SvgCreator Object
+            // CPPONLY: svgCreator,
             int flags) {
         this.name = name;
         this.camelCaseName = camelCaseName;
+        // CPPONLY: this.htmlCreator = htmlCreator;
+        // CPPONLY: this.svgCreator = svgCreator;
         this.flags = flags;
     }
 
-    protected ElementName(@Local String name) {
-        this.name = name;
-        this.camelCaseName = name;
-        this.flags = TreeBuilder.OTHER | CUSTOM;
+    public ElementName() {
+        this.name = null;
+        this.camelCaseName = null;
+        // CPPONLY: this.htmlCreator = NS_NewHTMLUnknownElement;
+        // CPPONLY: this.svgCreator = NS_NewSVGUnknownElement;
+        this.flags = TreeBuilder.OTHER | NOT_INTERNED;
     }
-    
-    @Virtual void release() {
-        // No-op in Java. 
-        // Implement as delete this in subclass.
-        // Be sure to release the local name
-    }
-    
-    @SuppressWarnings("unused") private void destructor() {
+
+    public void destructor() {
+        // The translator adds refcount debug code here.
     }
 
-    @Virtual public ElementName cloneElementName(Interner interner) {
-        return this;
+    @Inline public void setNameForNonInterned(@Local String name
+    // CPPONLY: , boolean custom
+    ) {
+        // No need to worry about refcounting the local name, because in the
+        // C++ case the scoped atom table remembers its own atoms.
+        this.name = name;
+        this.camelCaseName = name;
+        // CPPONLY: if (custom) {
+        // CPPONLY: this.htmlCreator = NS_NewCustomElement;
+        // CPPONLY: } else {
+        // CPPONLY: this.htmlCreator = NS_NewHTMLUnknownElement;
+        // CPPONLY: }
+        // The assertion below relies on TreeBuilder.OTHER being zero!
+        // TreeBuilder.OTHER isn't referenced here, because it would create
+        // a circular C++ header dependency given that this method is inlined.
+        assert this.flags == ElementName.NOT_INTERNED;
     }
-    
+
+    // CPPONLY: @Inline public boolean isCustom() {
+    // CPPONLY: return this.htmlCreator == NS_NewCustomElement;
+    // CPPONLY: }
+
+    public static final ElementName ANNOTATION_XML = new ElementName(
+            "annotation-xml", "annotation-xml",
+            // CPPONLY: NS_NewHTMLUnknownElement, NS_NewSVGUnknownElement,
+            TreeBuilder.ANNOTATION_XML | SCOPING_AS_MATHML);
+
     // START CODE ONLY USED FOR GENERATING CODE uncomment and run to regenerate
 
+//    private static final Pattern HTML_TAG_DEF = Pattern.compile(
+//            "^HTML_TAG\\(([^,]+),\\s*([^,]+),\\s*[^,]+\\).*$");
+//
+//    private static final Pattern HTML_HTMLELEMENT_TAG_DEF = Pattern.compile(
+//            "^HTML_HTMLELEMENT_TAG\\(([^\\)]+)\\).*$");
+//
+//    private static final Pattern SVG_TAG_DEF = Pattern.compile(
+//            "^SVG_(?:FROM_PARSER_)?TAG\\(([^,]+),\\s*([^\\)]+)\\).*$");
+//
+//    private static final Map<String, String> htmlMap = new HashMap<String, String>();
+//
+//    private static final Map<String, String> svgMap = new HashMap<String, String>();
+//
+//    private static void ingestHtmlTags(File htmlList) throws IOException {
+//        // This doesn't need to be efficient, so let's make it easy to write.
+//        BufferedReader htmlReader = new BufferedReader(
+//                new InputStreamReader(new FileInputStream(htmlList), "utf-8"));
+//        try {
+//            String line;
+//            while ((line = htmlReader.readLine()) != null) {
+//                if (!line.startsWith("HTML_")) {
+//                    continue;
+//                }
+//                if (line.startsWith("HTML_OTHER")) {
+//                    continue;
+//                }
+//                Matcher m = HTML_TAG_DEF.matcher(line);
+//                if (m.matches()) {
+//                    String iface = m.group(2);
+//                    if ("Unknown".equals(iface)) {
+//                        continue;
+//                    }
+//                    htmlMap.put(m.group(1), "NS_NewHTML" + iface + "Element");
+//                } else {
+//                    m = HTML_HTMLELEMENT_TAG_DEF.matcher(line);
+//                    if (!m.matches()) {
+//                        throw new RuntimeException(
+//                                "Malformed HTML element definition: " + line);
+//                    }
+//                    htmlMap.put(m.group(1), "NS_NewHTMLElement");
+//                }
+//            }
+//        } finally {
+//            htmlReader.close();
+//        }
+//    }
+//
+//    private static void ingestSvgTags(File svgList) throws IOException {
+//        // This doesn't need to be efficient, so let's make it easy to write.
+//        BufferedReader svgReader = new BufferedReader(
+//                new InputStreamReader(new FileInputStream(svgList), "utf-8"));
+//        try {
+//            String line;
+//            while ((line = svgReader.readLine()) != null) {
+//                if (!line.startsWith("SVG_")) {
+//                    continue;
+//                }
+//                Matcher m = SVG_TAG_DEF.matcher(line);
+//                if (!m.matches()) {
+//                    throw new RuntimeException(
+//                            "Malformed SVG element definition: " + line);
+//                }
+//                String name = m.group(1);
+//                if ("svgSwitch".equals(name)) {
+//                    name = "switch";
+//                }
+//                svgMap.put(name, "NS_NewSVG" + m.group(2) + "Element");
+//            }
+//        } finally {
+//            svgReader.close();
+//        }
+//    }
+//
+//    private static String htmlCreator(String name) {
+//        String creator = htmlMap.remove(name);
+//        if (creator != null) {
+//            return creator;
+//        }
+//        return "NS_NewHTMLUnknownElement";
+//    }
+//
+//    private static String svgCreator(String name) {
+//        String creator = svgMap.remove(name);
+//        if (creator != null) {
+//            return creator;
+//        }
+//        return "NS_NewSVGUnknownElement";
+//    }
+//
 //    /**
 //     * @see java.lang.Object#toString()
 //     */
 //    @Override public String toString() {
-//        return "(\"" + name + "\", \"" + camelCaseName + "\", " + decomposedFlags() + ")";
+//        return "(\"" + name + "\", \"" + camelCaseName + "\", \n// CPP"
+//                + "ONLY: " + htmlCreator(name) + ",\n// CPP" + "ONLY: "
+//                + svgCreator(camelCaseName) + ", \n" + decomposedFlags() + ")";
 //    }
 //
 //    private String decomposedFlags() {
@@ -194,7 +374,7 @@ public final class ElementName
 //        }
 //        if ((flags & SCOPING) != 0) {
 //            buf.append(" | SCOPING");
-//        }        
+//        }
 //        if ((flags & SCOPING_AS_MATHML) != 0) {
 //            buf.append(" | SCOPING_AS_MATHML");
 //        }
@@ -206,12 +386,17 @@ public final class ElementName
 //        }
 //        return buf.toString();
 //    }
-//    
+//
 //    private String constName() {
 //        char[] buf = new char[name.length()];
 //        for (int i = 0; i < name.length(); i++) {
 //            char c = name.charAt(i);
 //            if (c == '-') {
+//                if (!"annotation-xml".equals(name)) {
+//                    throw new RuntimeException(
+//                            "Non-annotation-xml element name with hyphen: "
+//                                    + name);
+//                }
 //                buf[i] = '_';
 //            } else if (c >= '0' && c <= '9') {
 //                buf[i] = c;
@@ -270,8 +455,6 @@ public final class ElementName
 //                return "IMAGE";
 //            case TreeBuilder.INPUT:
 //                return "INPUT";
-//            case TreeBuilder.ISINDEX:
-//                return "ISINDEX";
 //            case TreeBuilder.LI:
 //                return "LI";
 //            case TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND:
@@ -316,6 +499,8 @@ public final class ElementName
 //                return "TEXTAREA";
 //            case TreeBuilder.TITLE:
 //                return "TITLE";
+//            case TreeBuilder.TEMPLATE:
+//                return "TEMPLATE";
 //            case TreeBuilder.TR:
 //                return "TR";
 //            case TreeBuilder.XMP:
@@ -330,8 +515,8 @@ public final class ElementName
 //                return "H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6";
 //            case TreeBuilder.OBJECT:
 //                return "OBJECT";
-//            case TreeBuilder.OUTPUT_OR_LABEL:
-//                return "OUTPUT_OR_LABEL";
+//            case TreeBuilder.OUTPUT:
+//                return "OUTPUT";
 //            case TreeBuilder.MARQUEE_OR_APPLET:
 //                return "MARQUEE_OR_APPLET";
 //            case TreeBuilder.PRE_OR_LISTING:
@@ -344,22 +529,24 @@ public final class ElementName
 //                return "IFRAME";
 //            case TreeBuilder.NOEMBED:
 //                return "NOEMBED";
-//            case TreeBuilder.EMBED_OR_IMG:
-//                return "EMBED_OR_IMG";
+//            case TreeBuilder.EMBED:
+//                return "EMBED";
+//            case TreeBuilder.IMG:
+//                return "IMG";
 //            case TreeBuilder.AREA_OR_WBR:
 //                return "AREA_OR_WBR";
 //            case TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
 //                return "DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU";
 //            case TreeBuilder.FIELDSET:
 //                return "FIELDSET";
-//            case TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
-//                return "ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY";
+//            case TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY:
+//                return "ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY";
 //            case TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
 //                return "RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR";
+//            case TreeBuilder.RB_OR_RTC:
+//                return "RB_OR_RTC";
 //            case TreeBuilder.RT_OR_RP:
 //                return "RT_OR_RP";
-//            case TreeBuilder.COMMAND:
-//                return "COMMAND";
 //            case TreeBuilder.PARAM_OR_SOURCE_OR_TRACK:
 //                return "PARAM_OR_SOURCE_OR_TRACK";
 //            case TreeBuilder.MGLYPH_OR_MALIGNMARK:
@@ -374,1216 +561,1342 @@ public final class ElementName
 //        return null;
 //    }
 //
+//    private static void fillLevelOrderArray(List<ElementName> sorted, int depth,
+//            int rootIdx, ElementName[] levelOrder) {
+//        if (rootIdx >= levelOrder.length) {
+//            return;
+//        }
+//
+//        if (depth > 0) {
+//            fillLevelOrderArray(sorted, depth - 1, rootIdx * 2 + 1, levelOrder);
+//        }
+//
+//        if (!sorted.isEmpty()) {
+//            levelOrder[rootIdx] = sorted.remove(0);
+//        }
+//
+//        if (depth > 0) {
+//            fillLevelOrderArray(sorted, depth - 1, rootIdx * 2 + 2, levelOrder);
+//        }
+//    }
+//
 //    /**
 //     * Regenerate self
-//     * 
-//     * @param args
+//     *
+//     * The args should be the paths to m-c files
+//     * parser/htmlparser/nsHTMLTagList.h and dom/svg/SVGTagList.h.
 //     */
 //    public static void main(String[] args) {
+//        File htmlList = new File(args[0]);
+//        File svgList = new File(args[1]);
+//        try {
+//            ingestHtmlTags(htmlList);
+//        } catch (IOException e) {
+//            throw new RuntimeException(e);
+//        }
+//        try {
+//            ingestSvgTags(svgList);
+//        } catch (IOException e) {
+//            throw new RuntimeException(e);
+//        }
+//
 //        Arrays.sort(ELEMENT_NAMES);
-//        for (int i = 1; i < ELEMENT_NAMES.length; i++) {
-//            if (ELEMENT_NAMES[i].hash() == ELEMENT_NAMES[i - 1].hash()) {
-//                System.err.println("Hash collision: " + ELEMENT_NAMES[i].name
-//                        + ", " + ELEMENT_NAMES[i - 1].name);
+//        for (int i = 0; i < ELEMENT_NAMES.length; i++) {
+//            int hash = ELEMENT_NAMES[i].hash();
+//            if (hash < 0) {
+//                System.err.println("Negative hash: " + ELEMENT_NAMES[i].name);
 //                return;
 //            }
+//            for (int j = i + 1; j < ELEMENT_NAMES.length; j++) {
+//                if (hash == ELEMENT_NAMES[j].hash()) {
+//                    System.err.println(
+//                            "Hash collision: " + ELEMENT_NAMES[i].name + ", "
+//                                    + ELEMENT_NAMES[j].name);
+//                    return;
+//                }
+//            }
 //        }
 //        for (int i = 0; i < ELEMENT_NAMES.length; i++) {
 //            ElementName el = ELEMENT_NAMES[i];
-//            System.out.println("public static final ElementName "
-//                    + el.constName() + " = new ElementName" + el.toString()
-//                    + ";");
+//            System.out.println(
+//                    "public static final ElementName " + el.constName()
+//                            + " = new ElementName" + el.toString() + ";");
 //        }
-//        System.out.println("private final static @NoLength ElementName[] ELEMENT_NAMES = {");
-//        for (int i = 0; i < ELEMENT_NAMES.length; i++) {
-//            ElementName el = ELEMENT_NAMES[i];
+//
+//        LinkedList<ElementName> sortedNames = new LinkedList<ElementName>();
+//        Collections.addAll(sortedNames, ELEMENT_NAMES);
+//        ElementName[] levelOrder = new ElementName[ELEMENT_NAMES.length];
+//        int bstDepth = (int) Math.ceil(
+//                Math.log(ELEMENT_NAMES.length) / Math.log(2));
+//        fillLevelOrderArray(sortedNames, bstDepth, 0, levelOrder);
+//
+//        System.out.println(
+//                "private final static @NoLength ElementName[] ELEMENT_NAMES = {");
+//        for (int i = 0; i < levelOrder.length; i++) {
+//            ElementName el = levelOrder[i];
 //            System.out.println(el.constName() + ",");
 //        }
 //        System.out.println("};");
 //        System.out.println("private final static int[] ELEMENT_HASHES = {");
-//        for (int i = 0; i < ELEMENT_NAMES.length; i++) {
-//            ElementName el = ELEMENT_NAMES[i];
+//        for (int i = 0; i < levelOrder.length; i++) {
+//            ElementName el = levelOrder[i];
 //            System.out.println(Integer.toString(el.hash()) + ",");
 //        }
 //        System.out.println("};");
+//
+//        for (Entry<String, String> entry : htmlMap.entrySet()) {
+//            System.err.println("Missing HTML element: " + entry.getKey());
+//        }
+//        for (Entry<String, String> entry : svgMap.entrySet()) {
+//            System.err.println("Missing SVG element: " + entry.getKey());
+//        }
 //    }
 
     // START GENERATED CODE
-    public static final ElementName A = new ElementName("a", "a", TreeBuilder.A);
-    public static final ElementName B = new ElementName("b", "b", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName G = new ElementName("g", "g", TreeBuilder.OTHER);
-    public static final ElementName I = new ElementName("i", "i", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName P = new ElementName("p", "p", TreeBuilder.P | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName Q = new ElementName("q", "q", TreeBuilder.OTHER);
-    public static final ElementName S = new ElementName("s", "s", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName U = new ElementName("u", "u", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName BR = new ElementName("br", "br", TreeBuilder.BR | SPECIAL);
-    public static final ElementName CI = new ElementName("ci", "ci", TreeBuilder.OTHER);
-    public static final ElementName CN = new ElementName("cn", "cn", TreeBuilder.OTHER);
-    public static final ElementName DD = new ElementName("dd", "dd", TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName DL = new ElementName("dl", "dl", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
-    public static final ElementName DT = new ElementName("dt", "dt", TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName EM = new ElementName("em", "em", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName EQ = new ElementName("eq", "eq", TreeBuilder.OTHER);
-    public static final ElementName FN = new ElementName("fn", "fn", TreeBuilder.OTHER);
-    public static final ElementName H1 = new ElementName("h1", "h1", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName H2 = new ElementName("h2", "h2", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName H3 = new ElementName("h3", "h3", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName H4 = new ElementName("h4", "h4", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName H5 = new ElementName("h5", "h5", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName H6 = new ElementName("h6", "h6", TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
-    public static final ElementName GT = new ElementName("gt", "gt", TreeBuilder.OTHER);
-    public static final ElementName HR = new ElementName("hr", "hr", TreeBuilder.HR | SPECIAL);
-    public static final ElementName IN = new ElementName("in", "in", TreeBuilder.OTHER);
-    public static final ElementName LI = new ElementName("li", "li", TreeBuilder.LI | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName LN = new ElementName("ln", "ln", TreeBuilder.OTHER);
-    public static final ElementName LT = new ElementName("lt", "lt", TreeBuilder.OTHER);
-    public static final ElementName MI = new ElementName("mi", "mi", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
-    public static final ElementName MN = new ElementName("mn", "mn", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
-    public static final ElementName MO = new ElementName("mo", "mo", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
-    public static final ElementName MS = new ElementName("ms", "ms", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
-    public static final ElementName OL = new ElementName("ol", "ol", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
-    public static final ElementName OR = new ElementName("or", "or", TreeBuilder.OTHER);
-    public static final ElementName PI = new ElementName("pi", "pi", TreeBuilder.OTHER);
-    public static final ElementName RP = new ElementName("rp", "rp", TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
-    public static final ElementName RT = new ElementName("rt", "rt", TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
-    public static final ElementName TD = new ElementName("td", "td", TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
-    public static final ElementName TH = new ElementName("th", "th", TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
-    public static final ElementName TR = new ElementName("tr", "tr", TreeBuilder.TR | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
-    public static final ElementName TT = new ElementName("tt", "tt", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName UL = new ElementName("ul", "ul", TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
-    public static final ElementName AND = new ElementName("and", "and", TreeBuilder.OTHER);
-    public static final ElementName ARG = new ElementName("arg", "arg", TreeBuilder.OTHER);
-    public static final ElementName ABS = new ElementName("abs", "abs", TreeBuilder.OTHER);
-    public static final ElementName BIG = new ElementName("big", "big", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName BDO = new ElementName("bdo", "bdo", TreeBuilder.OTHER);
-    public static final ElementName CSC = new ElementName("csc", "csc", TreeBuilder.OTHER);
-    public static final ElementName COL = new ElementName("col", "col", TreeBuilder.COL | SPECIAL);
-    public static final ElementName COS = new ElementName("cos", "cos", TreeBuilder.OTHER);
-    public static final ElementName COT = new ElementName("cot", "cot", TreeBuilder.OTHER);
-    public static final ElementName DEL = new ElementName("del", "del", TreeBuilder.OTHER);
-    public static final ElementName DFN = new ElementName("dfn", "dfn", TreeBuilder.OTHER);
-    public static final ElementName DIR = new ElementName("dir", "dir", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName DIV = new ElementName("div", "div", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
-    public static final ElementName EXP = new ElementName("exp", "exp", TreeBuilder.OTHER);
-    public static final ElementName GCD = new ElementName("gcd", "gcd", TreeBuilder.OTHER);
-    public static final ElementName GEQ = new ElementName("geq", "geq", TreeBuilder.OTHER);
-    public static final ElementName IMG = new ElementName("img", "img", TreeBuilder.EMBED_OR_IMG | SPECIAL);
-    public static final ElementName INS = new ElementName("ins", "ins", TreeBuilder.OTHER);
-    public static final ElementName INT = new ElementName("int", "int", TreeBuilder.OTHER);
-    public static final ElementName KBD = new ElementName("kbd", "kbd", TreeBuilder.OTHER);
-    public static final ElementName LOG = new ElementName("log", "log", TreeBuilder.OTHER);
-    public static final ElementName LCM = new ElementName("lcm", "lcm", TreeBuilder.OTHER);
-    public static final ElementName LEQ = new ElementName("leq", "leq", TreeBuilder.OTHER);
-    public static final ElementName MTD = new ElementName("mtd", "mtd", TreeBuilder.OTHER);
-    public static final ElementName MIN = new ElementName("min", "min", TreeBuilder.OTHER);
-    public static final ElementName MAP = new ElementName("map", "map", TreeBuilder.OTHER);
-    public static final ElementName MTR = new ElementName("mtr", "mtr", TreeBuilder.OTHER);
-    public static final ElementName MAX = new ElementName("max", "max", TreeBuilder.OTHER);
-    public static final ElementName NEQ = new ElementName("neq", "neq", TreeBuilder.OTHER);
-    public static final ElementName NOT = new ElementName("not", "not", TreeBuilder.OTHER);
-    public static final ElementName NAV = new ElementName("nav", "nav", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName PRE = new ElementName("pre", "pre", TreeBuilder.PRE_OR_LISTING | SPECIAL);
-    public static final ElementName REM = new ElementName("rem", "rem", TreeBuilder.OTHER);
-    public static final ElementName SUB = new ElementName("sub", "sub", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
-    public static final ElementName SEC = new ElementName("sec", "sec", TreeBuilder.OTHER);
-    public static final ElementName SVG = new ElementName("svg", "svg", TreeBuilder.SVG);
-    public static final ElementName SUM = new ElementName("sum", "sum", TreeBuilder.OTHER);
-    public static final ElementName SIN = new ElementName("sin", "sin", TreeBuilder.OTHER);
-    public static final ElementName SEP = new ElementName("sep", "sep", TreeBuilder.OTHER);
-    public static final ElementName SUP = new ElementName("sup", "sup", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
-    public static final ElementName SET = new ElementName("set", "set", TreeBuilder.OTHER);
-    public static final ElementName TAN = new ElementName("tan", "tan", TreeBuilder.OTHER);
-    public static final ElementName USE = new ElementName("use", "use", TreeBuilder.OTHER);
-    public static final ElementName VAR = new ElementName("var", "var", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
-    public static final ElementName WBR = new ElementName("wbr", "wbr", TreeBuilder.AREA_OR_WBR | SPECIAL);
-    public static final ElementName XMP = new ElementName("xmp", "xmp", TreeBuilder.XMP);
-    public static final ElementName XOR = new ElementName("xor", "xor", TreeBuilder.OTHER);
-    public static final ElementName AREA = new ElementName("area", "area", TreeBuilder.AREA_OR_WBR | SPECIAL);
-    public static final ElementName ABBR = new ElementName("abbr", "abbr", TreeBuilder.OTHER);
-    public static final ElementName BASE = new ElementName("base", "base", TreeBuilder.BASE | SPECIAL);
-    public static final ElementName BVAR = new ElementName("bvar", "bvar", TreeBuilder.OTHER);
-    public static final ElementName BODY = new ElementName("body", "body", TreeBuilder.BODY | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName CARD = new ElementName("card", "card", TreeBuilder.OTHER);
-    public static final ElementName CODE = new ElementName("code", "code", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName CITE = new ElementName("cite", "cite", TreeBuilder.OTHER);
-    public static final ElementName CSCH = new ElementName("csch", "csch", TreeBuilder.OTHER);
-    public static final ElementName COSH = new ElementName("cosh", "cosh", TreeBuilder.OTHER);
-    public static final ElementName COTH = new ElementName("coth", "coth", TreeBuilder.OTHER);
-    public static final ElementName CURL = new ElementName("curl", "curl", TreeBuilder.OTHER);
-    public static final ElementName DESC = new ElementName("desc", "desc", TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
-    public static final ElementName DIFF = new ElementName("diff", "diff", TreeBuilder.OTHER);
-    public static final ElementName DEFS = new ElementName("defs", "defs", TreeBuilder.OTHER);
-    public static final ElementName FORM = new ElementName("form", "form", TreeBuilder.FORM | SPECIAL);
-    public static final ElementName FONT = new ElementName("font", "font", TreeBuilder.FONT);
-    public static final ElementName GRAD = new ElementName("grad", "grad", TreeBuilder.OTHER);
-    public static final ElementName HEAD = new ElementName("head", "head", TreeBuilder.HEAD | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName HTML = new ElementName("html", "html", TreeBuilder.HTML | SPECIAL | SCOPING | OPTIONAL_END_TAG);
-    public static final ElementName LINE = new ElementName("line", "line", TreeBuilder.OTHER);
-    public static final ElementName LINK = new ElementName("link", "link", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
-    public static final ElementName LIST = new ElementName("list", "list", TreeBuilder.OTHER);
-    public static final ElementName META = new ElementName("meta", "meta", TreeBuilder.META | SPECIAL);
-    public static final ElementName MSUB = new ElementName("msub", "msub", TreeBuilder.OTHER);
-    public static final ElementName MODE = new ElementName("mode", "mode", TreeBuilder.OTHER);
-    public static final ElementName MATH = new ElementName("math", "math", TreeBuilder.MATH);
-    public static final ElementName MARK = new ElementName("mark", "mark", TreeBuilder.OTHER);
-    public static final ElementName MASK = new ElementName("mask", "mask", TreeBuilder.OTHER);
-    public static final ElementName MEAN = new ElementName("mean", "mean", TreeBuilder.OTHER);
-    public static final ElementName MSUP = new ElementName("msup", "msup", TreeBuilder.OTHER);
-    public static final ElementName MENU = new ElementName("menu", "menu", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
-    public static final ElementName MROW = new ElementName("mrow", "mrow", TreeBuilder.OTHER);
-    public static final ElementName NONE = new ElementName("none", "none", TreeBuilder.OTHER);
-    public static final ElementName NOBR = new ElementName("nobr", "nobr", TreeBuilder.NOBR);
-    public static final ElementName NEST = new ElementName("nest", "nest", TreeBuilder.OTHER);
-    public static final ElementName PATH = new ElementName("path", "path", TreeBuilder.OTHER);
-    public static final ElementName PLUS = new ElementName("plus", "plus", TreeBuilder.OTHER);
-    public static final ElementName RULE = new ElementName("rule", "rule", TreeBuilder.OTHER);
-    public static final ElementName REAL = new ElementName("real", "real", TreeBuilder.OTHER);
-    public static final ElementName RELN = new ElementName("reln", "reln", TreeBuilder.OTHER);
-    public static final ElementName RECT = new ElementName("rect", "rect", TreeBuilder.OTHER);
-    public static final ElementName ROOT = new ElementName("root", "root", TreeBuilder.OTHER);
-    public static final ElementName RUBY = new ElementName("ruby", "ruby", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
-    public static final ElementName SECH = new ElementName("sech", "sech", TreeBuilder.OTHER);
-    public static final ElementName SINH = new ElementName("sinh", "sinh", TreeBuilder.OTHER);
-    public static final ElementName SPAN = new ElementName("span", "span", TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
-    public static final ElementName SAMP = new ElementName("samp", "samp", TreeBuilder.OTHER);
-    public static final ElementName STOP = new ElementName("stop", "stop", TreeBuilder.OTHER);
-    public static final ElementName SDEV = new ElementName("sdev", "sdev", TreeBuilder.OTHER);
-    public static final ElementName TIME = new ElementName("time", "time", TreeBuilder.OTHER);
-    public static final ElementName TRUE = new ElementName("true", "true", TreeBuilder.OTHER);
-    public static final ElementName TREF = new ElementName("tref", "tref", TreeBuilder.OTHER);
-    public static final ElementName TANH = new ElementName("tanh", "tanh", TreeBuilder.OTHER);
-    public static final ElementName TEXT = new ElementName("text", "text", TreeBuilder.OTHER);
-    public static final ElementName VIEW = new ElementName("view", "view", TreeBuilder.OTHER);
-    public static final ElementName ASIDE = new ElementName("aside", "aside", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName AUDIO = new ElementName("audio", "audio", TreeBuilder.OTHER);
-    public static final ElementName APPLY = new ElementName("apply", "apply", TreeBuilder.OTHER);
-    public static final ElementName EMBED = new ElementName("embed", "embed", TreeBuilder.EMBED_OR_IMG | SPECIAL);
-    public static final ElementName FRAME = new ElementName("frame", "frame", TreeBuilder.FRAME | SPECIAL);
-    public static final ElementName FALSE = new ElementName("false", "false", TreeBuilder.OTHER);
-    public static final ElementName FLOOR = new ElementName("floor", "floor", TreeBuilder.OTHER);
-    public static final ElementName GLYPH = new ElementName("glyph", "glyph", TreeBuilder.OTHER);
-    public static final ElementName HKERN = new ElementName("hkern", "hkern", TreeBuilder.OTHER);
-    public static final ElementName IMAGE = new ElementName("image", "image", TreeBuilder.IMAGE | SPECIAL);
-    public static final ElementName IDENT = new ElementName("ident", "ident", TreeBuilder.OTHER);
-    public static final ElementName INPUT = new ElementName("input", "input", TreeBuilder.INPUT | SPECIAL);
-    public static final ElementName LABEL = new ElementName("label", "label", TreeBuilder.OUTPUT_OR_LABEL);
-    public static final ElementName LIMIT = new ElementName("limit", "limit", TreeBuilder.OTHER);
-    public static final ElementName MFRAC = new ElementName("mfrac", "mfrac", TreeBuilder.OTHER);
-    public static final ElementName MPATH = new ElementName("mpath", "mpath", TreeBuilder.OTHER);
-    public static final ElementName METER = new ElementName("meter", "meter", TreeBuilder.OTHER);
-    public static final ElementName MOVER = new ElementName("mover", "mover", TreeBuilder.OTHER);
-    public static final ElementName MINUS = new ElementName("minus", "minus", TreeBuilder.OTHER);
-    public static final ElementName MROOT = new ElementName("mroot", "mroot", TreeBuilder.OTHER);
-    public static final ElementName MSQRT = new ElementName("msqrt", "msqrt", TreeBuilder.OTHER);
-    public static final ElementName MTEXT = new ElementName("mtext", "mtext", TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
-    public static final ElementName NOTIN = new ElementName("notin", "notin", TreeBuilder.OTHER);
-    public static final ElementName PIECE = new ElementName("piece", "piece", TreeBuilder.OTHER);
-    public static final ElementName PARAM = new ElementName("param", "param", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK | SPECIAL);
-    public static final ElementName POWER = new ElementName("power", "power", TreeBuilder.OTHER);
-    public static final ElementName REALS = new ElementName("reals", "reals", TreeBuilder.OTHER);
-    public static final ElementName STYLE = new ElementName("style", "style", TreeBuilder.STYLE | SPECIAL);
-    public static final ElementName SMALL = new ElementName("small", "small", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName THEAD = new ElementName("thead", "thead", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
-    public static final ElementName TABLE = new ElementName("table", "table", TreeBuilder.TABLE | SPECIAL | FOSTER_PARENTING | SCOPING);
-    public static final ElementName TITLE = new ElementName("title", "title", TreeBuilder.TITLE | SPECIAL | SCOPING_AS_SVG);
-    public static final ElementName TRACK = new ElementName("track", "track", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK);
-    public static final ElementName TSPAN = new ElementName("tspan", "tspan", TreeBuilder.OTHER);
-    public static final ElementName TIMES = new ElementName("times", "times", TreeBuilder.OTHER);
-    public static final ElementName TFOOT = new ElementName("tfoot", "tfoot", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
-    public static final ElementName TBODY = new ElementName("tbody", "tbody", TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
-    public static final ElementName UNION = new ElementName("union", "union", TreeBuilder.OTHER);
-    public static final ElementName VKERN = new ElementName("vkern", "vkern", TreeBuilder.OTHER);
-    public static final ElementName VIDEO = new ElementName("video", "video", TreeBuilder.OTHER);
-    public static final ElementName ARCSEC = new ElementName("arcsec", "arcsec", TreeBuilder.OTHER);
-    public static final ElementName ARCCSC = new ElementName("arccsc", "arccsc", TreeBuilder.OTHER);
-    public static final ElementName ARCTAN = new ElementName("arctan", "arctan", TreeBuilder.OTHER);
-    public static final ElementName ARCSIN = new ElementName("arcsin", "arcsin", TreeBuilder.OTHER);
-    public static final ElementName ARCCOS = new ElementName("arccos", "arccos", TreeBuilder.OTHER);
-    public static final ElementName APPLET = new ElementName("applet", "applet", TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
-    public static final ElementName ARCCOT = new ElementName("arccot", "arccot", TreeBuilder.OTHER);
-    public static final ElementName APPROX = new ElementName("approx", "approx", TreeBuilder.OTHER);
-    public static final ElementName BUTTON = new ElementName("button", "button", TreeBuilder.BUTTON | SPECIAL);
-    public static final ElementName CIRCLE = new ElementName("circle", "circle", TreeBuilder.OTHER);
-    public static final ElementName CENTER = new ElementName("center", "center", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
-    public static final ElementName CURSOR = new ElementName("cursor", "cursor", TreeBuilder.OTHER);
-    public static final ElementName CANVAS = new ElementName("canvas", "canvas", TreeBuilder.OTHER);
-    public static final ElementName DIVIDE = new ElementName("divide", "divide", TreeBuilder.OTHER);
-    public static final ElementName DEGREE = new ElementName("degree", "degree", TreeBuilder.OTHER);
-    public static final ElementName DOMAIN = new ElementName("domain", "domain", TreeBuilder.OTHER);
-    public static final ElementName EXISTS = new ElementName("exists", "exists", TreeBuilder.OTHER);
-    public static final ElementName FETILE = new ElementName("fetile", "feTile", TreeBuilder.OTHER);
-    public static final ElementName FIGURE = new ElementName("figure", "figure", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName FORALL = new ElementName("forall", "forall", TreeBuilder.OTHER);
-    public static final ElementName FILTER = new ElementName("filter", "filter", TreeBuilder.OTHER);
-    public static final ElementName FOOTER = new ElementName("footer", "footer", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName HGROUP = new ElementName("hgroup", "hgroup", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName HEADER = new ElementName("header", "header", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName IFRAME = new ElementName("iframe", "iframe", TreeBuilder.IFRAME | SPECIAL);
-    public static final ElementName KEYGEN = new ElementName("keygen", "keygen", TreeBuilder.KEYGEN | SPECIAL);
-    public static final ElementName LAMBDA = new ElementName("lambda", "lambda", TreeBuilder.OTHER);
-    public static final ElementName LEGEND = new ElementName("legend", "legend", TreeBuilder.OTHER);
-    public static final ElementName MSPACE = new ElementName("mspace", "mspace", TreeBuilder.OTHER);
-    public static final ElementName MTABLE = new ElementName("mtable", "mtable", TreeBuilder.OTHER);
-    public static final ElementName MSTYLE = new ElementName("mstyle", "mstyle", TreeBuilder.OTHER);
-    public static final ElementName MGLYPH = new ElementName("mglyph", "mglyph", TreeBuilder.MGLYPH_OR_MALIGNMARK);
-    public static final ElementName MEDIAN = new ElementName("median", "median", TreeBuilder.OTHER);
-    public static final ElementName MUNDER = new ElementName("munder", "munder", TreeBuilder.OTHER);
-    public static final ElementName MARKER = new ElementName("marker", "marker", TreeBuilder.OTHER);
-    public static final ElementName MERROR = new ElementName("merror", "merror", TreeBuilder.OTHER);
-    public static final ElementName MOMENT = new ElementName("moment", "moment", TreeBuilder.OTHER);
-    public static final ElementName MATRIX = new ElementName("matrix", "matrix", TreeBuilder.OTHER);
-    public static final ElementName OPTION = new ElementName("option", "option", TreeBuilder.OPTION | OPTIONAL_END_TAG);
-    public static final ElementName OBJECT = new ElementName("object", "object", TreeBuilder.OBJECT | SPECIAL | SCOPING);
-    public static final ElementName OUTPUT = new ElementName("output", "output", TreeBuilder.OUTPUT_OR_LABEL);
-    public static final ElementName PRIMES = new ElementName("primes", "primes", TreeBuilder.OTHER);
-    public static final ElementName SOURCE = new ElementName("source", "source", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK);
-    public static final ElementName STRIKE = new ElementName("strike", "strike", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName STRONG = new ElementName("strong", "strong", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
-    public static final ElementName SWITCH = new ElementName("switch", "switch", TreeBuilder.OTHER);
-    public static final ElementName SYMBOL = new ElementName("symbol", "symbol", TreeBuilder.OTHER);
-    public static final ElementName SELECT = new ElementName("select", "select", TreeBuilder.SELECT | SPECIAL);
-    public static final ElementName SUBSET = new ElementName("subset", "subset", TreeBuilder.OTHER);
-    public static final ElementName SCRIPT = new ElementName("script", "script", TreeBuilder.SCRIPT | SPECIAL);
-    public static final ElementName TBREAK = new ElementName("tbreak", "tbreak", TreeBuilder.OTHER);
-    public static final ElementName VECTOR = new ElementName("vector", "vector", TreeBuilder.OTHER);
-    public static final ElementName ARTICLE = new ElementName("article", "article", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName ANIMATE = new ElementName("animate", "animate", TreeBuilder.OTHER);
-    public static final ElementName ARCSECH = new ElementName("arcsech", "arcsech", TreeBuilder.OTHER);
-    public static final ElementName ARCCSCH = new ElementName("arccsch", "arccsch", TreeBuilder.OTHER);
-    public static final ElementName ARCTANH = new ElementName("arctanh", "arctanh", TreeBuilder.OTHER);
-    public static final ElementName ARCSINH = new ElementName("arcsinh", "arcsinh", TreeBuilder.OTHER);
-    public static final ElementName ARCCOSH = new ElementName("arccosh", "arccosh", TreeBuilder.OTHER);
-    public static final ElementName ARCCOTH = new ElementName("arccoth", "arccoth", TreeBuilder.OTHER);
-    public static final ElementName ACRONYM = new ElementName("acronym", "acronym", TreeBuilder.OTHER);
-    public static final ElementName ADDRESS = new ElementName("address", "address", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName BGSOUND = new ElementName("bgsound", "bgsound", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
-    public static final ElementName COMMAND = new ElementName("command", "command", TreeBuilder.COMMAND | SPECIAL);
-    public static final ElementName COMPOSE = new ElementName("compose", "compose", TreeBuilder.OTHER);
-    public static final ElementName CEILING = new ElementName("ceiling", "ceiling", TreeBuilder.OTHER);
-    public static final ElementName CSYMBOL = new ElementName("csymbol", "csymbol", TreeBuilder.OTHER);
-    public static final ElementName CAPTION = new ElementName("caption", "caption", TreeBuilder.CAPTION | SPECIAL | SCOPING);
-    public static final ElementName DISCARD = new ElementName("discard", "discard", TreeBuilder.OTHER);
-    public static final ElementName DECLARE = new ElementName("declare", "declare", TreeBuilder.OTHER);
-    public static final ElementName DETAILS = new ElementName("details", "details", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName ELLIPSE = new ElementName("ellipse", "ellipse", TreeBuilder.OTHER);
-    public static final ElementName FEFUNCA = new ElementName("fefunca", "feFuncA", TreeBuilder.OTHER);
-    public static final ElementName FEFUNCB = new ElementName("fefuncb", "feFuncB", TreeBuilder.OTHER);
-    public static final ElementName FEBLEND = new ElementName("feblend", "feBlend", TreeBuilder.OTHER);
-    public static final ElementName FEFLOOD = new ElementName("feflood", "feFlood", TreeBuilder.OTHER);
-    public static final ElementName FEIMAGE = new ElementName("feimage", "feImage", TreeBuilder.OTHER);
-    public static final ElementName FEMERGE = new ElementName("femerge", "feMerge", TreeBuilder.OTHER);
-    public static final ElementName FEFUNCG = new ElementName("fefuncg", "feFuncG", TreeBuilder.OTHER);
-    public static final ElementName FEFUNCR = new ElementName("fefuncr", "feFuncR", TreeBuilder.OTHER);
-    public static final ElementName HANDLER = new ElementName("handler", "handler", TreeBuilder.OTHER);
-    public static final ElementName INVERSE = new ElementName("inverse", "inverse", TreeBuilder.OTHER);
-    public static final ElementName IMPLIES = new ElementName("implies", "implies", TreeBuilder.OTHER);
-    public static final ElementName ISINDEX = new ElementName("isindex", "isindex", TreeBuilder.ISINDEX | SPECIAL);
-    public static final ElementName LOGBASE = new ElementName("logbase", "logbase", TreeBuilder.OTHER);
-    public static final ElementName LISTING = new ElementName("listing", "listing", TreeBuilder.PRE_OR_LISTING | SPECIAL);
-    public static final ElementName MFENCED = new ElementName("mfenced", "mfenced", TreeBuilder.OTHER);
-    public static final ElementName MPADDED = new ElementName("mpadded", "mpadded", TreeBuilder.OTHER);
-    public static final ElementName MARQUEE = new ElementName("marquee", "marquee", TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
-    public static final ElementName MACTION = new ElementName("maction", "maction", TreeBuilder.OTHER);
-    public static final ElementName MSUBSUP = new ElementName("msubsup", "msubsup", TreeBuilder.OTHER);
-    public static final ElementName NOEMBED = new ElementName("noembed", "noembed", TreeBuilder.NOEMBED | SPECIAL);
-    public static final ElementName POLYGON = new ElementName("polygon", "polygon", TreeBuilder.OTHER);
-    public static final ElementName PATTERN = new ElementName("pattern", "pattern", TreeBuilder.OTHER);
-    public static final ElementName PRODUCT = new ElementName("product", "product", TreeBuilder.OTHER);
-    public static final ElementName SETDIFF = new ElementName("setdiff", "setdiff", TreeBuilder.OTHER);
-    public static final ElementName SECTION = new ElementName("section", "section", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName SUMMARY = new ElementName("summary", "summary", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName TENDSTO = new ElementName("tendsto", "tendsto", TreeBuilder.OTHER);
-    public static final ElementName UPLIMIT = new ElementName("uplimit", "uplimit", TreeBuilder.OTHER);
-    public static final ElementName ALTGLYPH = new ElementName("altglyph", "altGlyph", TreeBuilder.OTHER);
-    public static final ElementName BASEFONT = new ElementName("basefont", "basefont", TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
-    public static final ElementName CLIPPATH = new ElementName("clippath", "clipPath", TreeBuilder.OTHER);
-    public static final ElementName CODOMAIN = new ElementName("codomain", "codomain", TreeBuilder.OTHER);
-    public static final ElementName COLGROUP = new ElementName("colgroup", "colgroup", TreeBuilder.COLGROUP | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName EMPTYSET = new ElementName("emptyset", "emptyset", TreeBuilder.OTHER);
-    public static final ElementName FACTOROF = new ElementName("factorof", "factorof", TreeBuilder.OTHER);
-    public static final ElementName FIELDSET = new ElementName("fieldset", "fieldset", TreeBuilder.FIELDSET | SPECIAL);
-    public static final ElementName FRAMESET = new ElementName("frameset", "frameset", TreeBuilder.FRAMESET | SPECIAL);
-    public static final ElementName FEOFFSET = new ElementName("feoffset", "feOffset", TreeBuilder.OTHER);
-    public static final ElementName GLYPHREF = new ElementName("glyphref", "glyphRef", TreeBuilder.OTHER);
-    public static final ElementName INTERVAL = new ElementName("interval", "interval", TreeBuilder.OTHER);
-    public static final ElementName INTEGERS = new ElementName("integers", "integers", TreeBuilder.OTHER);
-    public static final ElementName INFINITY = new ElementName("infinity", "infinity", TreeBuilder.OTHER);
-    public static final ElementName LISTENER = new ElementName("listener", "listener", TreeBuilder.OTHER);
-    public static final ElementName LOWLIMIT = new ElementName("lowlimit", "lowlimit", TreeBuilder.OTHER);
-    public static final ElementName METADATA = new ElementName("metadata", "metadata", TreeBuilder.OTHER);
-    public static final ElementName MENCLOSE = new ElementName("menclose", "menclose", TreeBuilder.OTHER);
-    public static final ElementName MPHANTOM = new ElementName("mphantom", "mphantom", TreeBuilder.OTHER);
-    public static final ElementName NOFRAMES = new ElementName("noframes", "noframes", TreeBuilder.NOFRAMES | SPECIAL);
-    public static final ElementName NOSCRIPT = new ElementName("noscript", "noscript", TreeBuilder.NOSCRIPT | SPECIAL);
-    public static final ElementName OPTGROUP = new ElementName("optgroup", "optgroup", TreeBuilder.OPTGROUP | SPECIAL | OPTIONAL_END_TAG);
-    public static final ElementName POLYLINE = new ElementName("polyline", "polyline", TreeBuilder.OTHER);
-    public static final ElementName PREFETCH = new ElementName("prefetch", "prefetch", TreeBuilder.OTHER);
-    public static final ElementName PROGRESS = new ElementName("progress", "progress", TreeBuilder.OTHER);
-    public static final ElementName PRSUBSET = new ElementName("prsubset", "prsubset", TreeBuilder.OTHER);
-    public static final ElementName QUOTIENT = new ElementName("quotient", "quotient", TreeBuilder.OTHER);
-    public static final ElementName SELECTOR = new ElementName("selector", "selector", TreeBuilder.OTHER);
-    public static final ElementName TEXTAREA = new ElementName("textarea", "textarea", TreeBuilder.TEXTAREA | SPECIAL);
-    public static final ElementName TEXTPATH = new ElementName("textpath", "textPath", TreeBuilder.OTHER);
-    public static final ElementName VARIANCE = new ElementName("variance", "variance", TreeBuilder.OTHER);
-    public static final ElementName ANIMATION = new ElementName("animation", "animation", TreeBuilder.OTHER);
-    public static final ElementName CONJUGATE = new ElementName("conjugate", "conjugate", TreeBuilder.OTHER);
-    public static final ElementName CONDITION = new ElementName("condition", "condition", TreeBuilder.OTHER);
-    public static final ElementName COMPLEXES = new ElementName("complexes", "complexes", TreeBuilder.OTHER);
-    public static final ElementName FONT_FACE = new ElementName("font-face", "font-face", TreeBuilder.OTHER);
-    public static final ElementName FACTORIAL = new ElementName("factorial", "factorial", TreeBuilder.OTHER);
-    public static final ElementName INTERSECT = new ElementName("intersect", "intersect", TreeBuilder.OTHER);
-    public static final ElementName IMAGINARY = new ElementName("imaginary", "imaginary", TreeBuilder.OTHER);
-    public static final ElementName LAPLACIAN = new ElementName("laplacian", "laplacian", TreeBuilder.OTHER);
-    public static final ElementName MATRIXROW = new ElementName("matrixrow", "matrixrow", TreeBuilder.OTHER);
-    public static final ElementName NOTSUBSET = new ElementName("notsubset", "notsubset", TreeBuilder.OTHER);
-    public static final ElementName OTHERWISE = new ElementName("otherwise", "otherwise", TreeBuilder.OTHER);
-    public static final ElementName PIECEWISE = new ElementName("piecewise", "piecewise", TreeBuilder.OTHER);
-    public static final ElementName PLAINTEXT = new ElementName("plaintext", "plaintext", TreeBuilder.PLAINTEXT | SPECIAL);
-    public static final ElementName RATIONALS = new ElementName("rationals", "rationals", TreeBuilder.OTHER);
-    public static final ElementName SEMANTICS = new ElementName("semantics", "semantics", TreeBuilder.OTHER);
-    public static final ElementName TRANSPOSE = new ElementName("transpose", "transpose", TreeBuilder.OTHER);
-    public static final ElementName ANNOTATION = new ElementName("annotation", "annotation", TreeBuilder.OTHER);
-    public static final ElementName BLOCKQUOTE = new ElementName("blockquote", "blockquote", TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
-    public static final ElementName DIVERGENCE = new ElementName("divergence", "divergence", TreeBuilder.OTHER);
-    public static final ElementName EULERGAMMA = new ElementName("eulergamma", "eulergamma", TreeBuilder.OTHER);
-    public static final ElementName EQUIVALENT = new ElementName("equivalent", "equivalent", TreeBuilder.OTHER);
-    public static final ElementName FIGCAPTION = new ElementName("figcaption", "figcaption", TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY | SPECIAL);
-    public static final ElementName IMAGINARYI = new ElementName("imaginaryi", "imaginaryi", TreeBuilder.OTHER);
-    public static final ElementName MALIGNMARK = new ElementName("malignmark", "malignmark", TreeBuilder.MGLYPH_OR_MALIGNMARK);
-    public static final ElementName MUNDEROVER = new ElementName("munderover", "munderover", TreeBuilder.OTHER);
-    public static final ElementName MLABELEDTR = new ElementName("mlabeledtr", "mlabeledtr", TreeBuilder.OTHER);
-    public static final ElementName NOTANUMBER = new ElementName("notanumber", "notanumber", TreeBuilder.OTHER);
-    public static final ElementName SOLIDCOLOR = new ElementName("solidcolor", "solidcolor", TreeBuilder.OTHER);
-    public static final ElementName ALTGLYPHDEF = new ElementName("altglyphdef", "altGlyphDef", TreeBuilder.OTHER);
-    public static final ElementName DETERMINANT = new ElementName("determinant", "determinant", TreeBuilder.OTHER);
-    public static final ElementName FEMERGENODE = new ElementName("femergenode", "feMergeNode", TreeBuilder.OTHER);
-    public static final ElementName FECOMPOSITE = new ElementName("fecomposite", "feComposite", TreeBuilder.OTHER);
-    public static final ElementName FESPOTLIGHT = new ElementName("fespotlight", "feSpotLight", TreeBuilder.OTHER);
-    public static final ElementName MALIGNGROUP = new ElementName("maligngroup", "maligngroup", TreeBuilder.OTHER);
-    public static final ElementName MPRESCRIPTS = new ElementName("mprescripts", "mprescripts", TreeBuilder.OTHER);
-    public static final ElementName MOMENTABOUT = new ElementName("momentabout", "momentabout", TreeBuilder.OTHER);
-    public static final ElementName NOTPRSUBSET = new ElementName("notprsubset", "notprsubset", TreeBuilder.OTHER);
-    public static final ElementName PARTIALDIFF = new ElementName("partialdiff", "partialdiff", TreeBuilder.OTHER);
-    public static final ElementName ALTGLYPHITEM = new ElementName("altglyphitem", "altGlyphItem", TreeBuilder.OTHER);
-    public static final ElementName ANIMATECOLOR = new ElementName("animatecolor", "animateColor", TreeBuilder.OTHER);
-    public static final ElementName DATATEMPLATE = new ElementName("datatemplate", "datatemplate", TreeBuilder.OTHER);
-    public static final ElementName EXPONENTIALE = new ElementName("exponentiale", "exponentiale", TreeBuilder.OTHER);
-    public static final ElementName FETURBULENCE = new ElementName("feturbulence", "feTurbulence", TreeBuilder.OTHER);
-    public static final ElementName FEPOINTLIGHT = new ElementName("fepointlight", "fePointLight", TreeBuilder.OTHER);
-    public static final ElementName FEMORPHOLOGY = new ElementName("femorphology", "feMorphology", TreeBuilder.OTHER);
-    public static final ElementName OUTERPRODUCT = new ElementName("outerproduct", "outerproduct", TreeBuilder.OTHER);
-    public static final ElementName ANIMATEMOTION = new ElementName("animatemotion", "animateMotion", TreeBuilder.OTHER);
-    public static final ElementName COLOR_PROFILE = new ElementName("color-profile", "color-profile", TreeBuilder.OTHER);
-    public static final ElementName FONT_FACE_SRC = new ElementName("font-face-src", "font-face-src", TreeBuilder.OTHER);
-    public static final ElementName FONT_FACE_URI = new ElementName("font-face-uri", "font-face-uri", TreeBuilder.OTHER);
-    public static final ElementName FOREIGNOBJECT = new ElementName("foreignobject", "foreignObject", TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
-    public static final ElementName FECOLORMATRIX = new ElementName("fecolormatrix", "feColorMatrix", TreeBuilder.OTHER);
-    public static final ElementName MISSING_GLYPH = new ElementName("missing-glyph", "missing-glyph", TreeBuilder.OTHER);
-    public static final ElementName MMULTISCRIPTS = new ElementName("mmultiscripts", "mmultiscripts", TreeBuilder.OTHER);
-    public static final ElementName SCALARPRODUCT = new ElementName("scalarproduct", "scalarproduct", TreeBuilder.OTHER);
-    public static final ElementName VECTORPRODUCT = new ElementName("vectorproduct", "vectorproduct", TreeBuilder.OTHER);
-    public static final ElementName ANNOTATION_XML = new ElementName("annotation-xml", "annotation-xml", TreeBuilder.ANNOTATION_XML | SCOPING_AS_MATHML);
-    public static final ElementName DEFINITION_SRC = new ElementName("definition-src", "definition-src", TreeBuilder.OTHER);
-    public static final ElementName FONT_FACE_NAME = new ElementName("font-face-name", "font-face-name", TreeBuilder.OTHER);
-    public static final ElementName FEGAUSSIANBLUR = new ElementName("fegaussianblur", "feGaussianBlur", TreeBuilder.OTHER);
-    public static final ElementName FEDISTANTLIGHT = new ElementName("fedistantlight", "feDistantLight", TreeBuilder.OTHER);
-    public static final ElementName LINEARGRADIENT = new ElementName("lineargradient", "linearGradient", TreeBuilder.OTHER);
-    public static final ElementName NATURALNUMBERS = new ElementName("naturalnumbers", "naturalnumbers", TreeBuilder.OTHER);
-    public static final ElementName RADIALGRADIENT = new ElementName("radialgradient", "radialGradient", TreeBuilder.OTHER);
-    public static final ElementName ANIMATETRANSFORM = new ElementName("animatetransform", "animateTransform", TreeBuilder.OTHER);
-    public static final ElementName CARTESIANPRODUCT = new ElementName("cartesianproduct", "cartesianproduct", TreeBuilder.OTHER);
-    public static final ElementName FONT_FACE_FORMAT = new ElementName("font-face-format", "font-face-format", TreeBuilder.OTHER);
-    public static final ElementName FECONVOLVEMATRIX = new ElementName("feconvolvematrix", "feConvolveMatrix", TreeBuilder.OTHER);
-    public static final ElementName FEDIFFUSELIGHTING = new ElementName("fediffuselighting", "feDiffuseLighting", TreeBuilder.OTHER);
-    public static final ElementName FEDISPLACEMENTMAP = new ElementName("fedisplacementmap", "feDisplacementMap", TreeBuilder.OTHER);
-    public static final ElementName FESPECULARLIGHTING = new ElementName("fespecularlighting", "feSpecularLighting", TreeBuilder.OTHER);
-    public static final ElementName DOMAINOFAPPLICATION = new ElementName("domainofapplication", "domainofapplication", TreeBuilder.OTHER);
-    public static final ElementName FECOMPONENTTRANSFER = new ElementName("fecomponenttransfer", "feComponentTransfer", TreeBuilder.OTHER);
-    private final static @NoLength ElementName[] ELEMENT_NAMES = {
-    A,
-    B,
-    G,
-    I,
-    P,
-    Q,
-    S,
-    U,
-    BR,
-    CI,
-    CN,
-    DD,
-    DL,
-    DT,
-    EM,
-    EQ,
-    FN,
-    H1,
-    H2,
-    H3,
-    H4,
-    H5,
-    H6,
-    GT,
-    HR,
-    IN,
-    LI,
-    LN,
-    LT,
-    MI,
-    MN,
-    MO,
-    MS,
-    OL,
-    OR,
-    PI,
-    RP,
-    RT,
-    TD,
-    TH,
-    TR,
-    TT,
-    UL,
-    AND,
-    ARG,
-    ABS,
-    BIG,
-    BDO,
-    CSC,
-    COL,
-    COS,
-    COT,
-    DEL,
-    DFN,
-    DIR,
-    DIV,
-    EXP,
-    GCD,
-    GEQ,
-    IMG,
-    INS,
-    INT,
-    KBD,
-    LOG,
-    LCM,
-    LEQ,
-    MTD,
-    MIN,
-    MAP,
-    MTR,
-    MAX,
-    NEQ,
-    NOT,
-    NAV,
-    PRE,
-    REM,
-    SUB,
-    SEC,
-    SVG,
-    SUM,
-    SIN,
-    SEP,
-    SUP,
-    SET,
-    TAN,
-    USE,
-    VAR,
-    WBR,
-    XMP,
-    XOR,
-    AREA,
-    ABBR,
-    BASE,
-    BVAR,
-    BODY,
-    CARD,
-    CODE,
-    CITE,
-    CSCH,
-    COSH,
-    COTH,
-    CURL,
-    DESC,
-    DIFF,
-    DEFS,
-    FORM,
-    FONT,
-    GRAD,
-    HEAD,
-    HTML,
-    LINE,
-    LINK,
-    LIST,
-    META,
-    MSUB,
-    MODE,
-    MATH,
-    MARK,
-    MASK,
-    MEAN,
-    MSUP,
-    MENU,
-    MROW,
-    NONE,
-    NOBR,
-    NEST,
-    PATH,
-    PLUS,
-    RULE,
-    REAL,
-    RELN,
-    RECT,
-    ROOT,
-    RUBY,
-    SECH,
-    SINH,
-    SPAN,
-    SAMP,
-    STOP,
-    SDEV,
-    TIME,
-    TRUE,
-    TREF,
-    TANH,
-    TEXT,
-    VIEW,
-    ASIDE,
-    AUDIO,
-    APPLY,
-    EMBED,
-    FRAME,
-    FALSE,
-    FLOOR,
-    GLYPH,
-    HKERN,
-    IMAGE,
-    IDENT,
-    INPUT,
-    LABEL,
-    LIMIT,
-    MFRAC,
-    MPATH,
-    METER,
-    MOVER,
-    MINUS,
-    MROOT,
-    MSQRT,
-    MTEXT,
-    NOTIN,
-    PIECE,
-    PARAM,
-    POWER,
-    REALS,
-    STYLE,
-    SMALL,
-    THEAD,
-    TABLE,
-    TITLE,
-    TRACK,
-    TSPAN,
-    TIMES,
-    TFOOT,
-    TBODY,
-    UNION,
-    VKERN,
-    VIDEO,
-    ARCSEC,
-    ARCCSC,
-    ARCTAN,
-    ARCSIN,
-    ARCCOS,
-    APPLET,
-    ARCCOT,
-    APPROX,
-    BUTTON,
-    CIRCLE,
-    CENTER,
-    CURSOR,
-    CANVAS,
-    DIVIDE,
-    DEGREE,
-    DOMAIN,
-    EXISTS,
-    FETILE,
-    FIGURE,
-    FORALL,
-    FILTER,
-    FOOTER,
-    HGROUP,
-    HEADER,
-    IFRAME,
-    KEYGEN,
-    LAMBDA,
-    LEGEND,
-    MSPACE,
-    MTABLE,
-    MSTYLE,
-    MGLYPH,
-    MEDIAN,
-    MUNDER,
-    MARKER,
-    MERROR,
-    MOMENT,
-    MATRIX,
-    OPTION,
-    OBJECT,
-    OUTPUT,
-    PRIMES,
-    SOURCE,
-    STRIKE,
-    STRONG,
-    SWITCH,
-    SYMBOL,
-    SELECT,
-    SUBSET,
-    SCRIPT,
-    TBREAK,
-    VECTOR,
-    ARTICLE,
-    ANIMATE,
-    ARCSECH,
-    ARCCSCH,
-    ARCTANH,
-    ARCSINH,
-    ARCCOSH,
-    ARCCOTH,
-    ACRONYM,
-    ADDRESS,
-    BGSOUND,
-    COMMAND,
-    COMPOSE,
-    CEILING,
-    CSYMBOL,
-    CAPTION,
-    DISCARD,
-    DECLARE,
-    DETAILS,
-    ELLIPSE,
-    FEFUNCA,
-    FEFUNCB,
-    FEBLEND,
-    FEFLOOD,
-    FEIMAGE,
-    FEMERGE,
-    FEFUNCG,
-    FEFUNCR,
-    HANDLER,
-    INVERSE,
-    IMPLIES,
-    ISINDEX,
-    LOGBASE,
-    LISTING,
-    MFENCED,
-    MPADDED,
-    MARQUEE,
-    MACTION,
-    MSUBSUP,
-    NOEMBED,
-    POLYGON,
-    PATTERN,
-    PRODUCT,
-    SETDIFF,
-    SECTION,
-    SUMMARY,
-    TENDSTO,
-    UPLIMIT,
-    ALTGLYPH,
-    BASEFONT,
-    CLIPPATH,
-    CODOMAIN,
-    COLGROUP,
-    EMPTYSET,
-    FACTOROF,
-    FIELDSET,
-    FRAMESET,
-    FEOFFSET,
-    GLYPHREF,
-    INTERVAL,
-    INTEGERS,
-    INFINITY,
-    LISTENER,
-    LOWLIMIT,
-    METADATA,
-    MENCLOSE,
-    MPHANTOM,
-    NOFRAMES,
-    NOSCRIPT,
-    OPTGROUP,
-    POLYLINE,
-    PREFETCH,
-    PROGRESS,
-    PRSUBSET,
-    QUOTIENT,
-    SELECTOR,
-    TEXTAREA,
-    TEXTPATH,
-    VARIANCE,
-    ANIMATION,
-    CONJUGATE,
-    CONDITION,
-    COMPLEXES,
-    FONT_FACE,
-    FACTORIAL,
-    INTERSECT,
-    IMAGINARY,
-    LAPLACIAN,
-    MATRIXROW,
-    NOTSUBSET,
-    OTHERWISE,
-    PIECEWISE,
-    PLAINTEXT,
-    RATIONALS,
-    SEMANTICS,
-    TRANSPOSE,
-    ANNOTATION,
-    BLOCKQUOTE,
-    DIVERGENCE,
-    EULERGAMMA,
-    EQUIVALENT,
-    FIGCAPTION,
-    IMAGINARYI,
-    MALIGNMARK,
-    MUNDEROVER,
-    MLABELEDTR,
-    NOTANUMBER,
-    SOLIDCOLOR,
-    ALTGLYPHDEF,
-    DETERMINANT,
-    FEMERGENODE,
-    FECOMPOSITE,
-    FESPOTLIGHT,
-    MALIGNGROUP,
-    MPRESCRIPTS,
-    MOMENTABOUT,
-    NOTPRSUBSET,
-    PARTIALDIFF,
-    ALTGLYPHITEM,
-    ANIMATECOLOR,
-    DATATEMPLATE,
-    EXPONENTIALE,
-    FETURBULENCE,
-    FEPOINTLIGHT,
-    FEMORPHOLOGY,
-    OUTERPRODUCT,
-    ANIMATEMOTION,
-    COLOR_PROFILE,
-    FONT_FACE_SRC,
-    FONT_FACE_URI,
-    FOREIGNOBJECT,
-    FECOLORMATRIX,
-    MISSING_GLYPH,
-    MMULTISCRIPTS,
-    SCALARPRODUCT,
-    VECTORPRODUCT,
-    ANNOTATION_XML,
-    DEFINITION_SRC,
-    FONT_FACE_NAME,
-    FEGAUSSIANBLUR,
-    FEDISTANTLIGHT,
-    LINEARGRADIENT,
-    NATURALNUMBERS,
-    RADIALGRADIENT,
-    ANIMATETRANSFORM,
-    CARTESIANPRODUCT,
-    FONT_FACE_FORMAT,
-    FECONVOLVEMATRIX,
-    FEDIFFUSELIGHTING,
-    FEDISPLACEMENTMAP,
-    FESPECULARLIGHTING,
-    DOMAINOFAPPLICATION,
-    FECOMPONENTTRANSFER,
-    };
-    private final static int[] ELEMENT_HASHES = {
-    1057,
-    1090,
-    1255,
-    1321,
-    1552,
-    1585,
-    1651,
-    1717,
-    68162,
-    68899,
-    69059,
-    69764,
-    70020,
-    70276,
-    71077,
-    71205,
-    72134,
-    72232,
-    72264,
-    72296,
-    72328,
-    72360,
-    72392,
-    73351,
-    74312,
-    75209,
-    78124,
-    78284,
-    78476,
-    79149,
-    79309,
-    79341,
-    79469,
-    81295,
-    81487,
-    82224,
-    84498,
-    84626,
-    86164,
-    86292,
-    86612,
-    86676,
-    87445,
-    3183041,
-    3186241,
-    3198017,
-    3218722,
-    3226754,
-    3247715,
-    3256803,
-    3263971,
-    3264995,
-    3289252,
-    3291332,
-    3295524,
-    3299620,
-    3326725,
-    3379303,
-    3392679,
-    3448233,
-    3460553,
-    3461577,
-    3510347,
-    3546604,
-    3552364,
-    3556524,
-    3576461,
-    3586349,
-    3588141,
-    3590797,
-    3596333,
-    3622062,
-    3625454,
-    3627054,
-    3675728,
-    3749042,
-    3771059,
-    3771571,
-    3776211,
-    3782323,
-    3782963,
-    3784883,
-    3785395,
-    3788979,
-    3815476,
-    3839605,
-    3885110,
-    3917911,
-    3948984,
-    3951096,
-    135304769,
-    135858241,
-    136498210,
-    136906434,
-    137138658,
-    137512995,
-    137531875,
-    137548067,
-    137629283,
-    137645539,
-    137646563,
-    137775779,
-    138529956,
-    138615076,
-    139040932,
-    140954086,
-    141179366,
-    141690439,
-    142738600,
-    143013512,
-    146979116,
-    147175724,
-    147475756,
-    147902637,
-    147936877,
-    148017645,
-    148131885,
-    148228141,
-    148229165,
-    148309165,
-    148395629,
-    148551853,
-    148618829,
-    149076462,
-    149490158,
-    149572782,
-    151277616,
-    151639440,
-    153268914,
-    153486514,
-    153563314,
-    153750706,
-    153763314,
-    153914034,
-    154406067,
-    154417459,
-    154600979,
-    154678323,
-    154680979,
-    154866835,
-    155366708,
-    155375188,
-    155391572,
-    155465780,
-    155869364,
-    158045494,
-    168988979,
-    169321621,
-    169652752,
-    173151309,
-    174240818,
-    174247297,
-    174669292,
-    175391532,
-    176638123,
-    177380397,
-    177879204,
-    177886734,
-    180753473,
-    181020073,
-    181503558,
-    181686320,
-    181999237,
-    181999311,
-    182048201,
-    182074866,
-    182078003,
-    182083764,
-    182920847,
-    184716457,
-    184976961,
-    185145071,
-    187281445,
-    187872052,
-    188100653,
-    188875944,
-    188919873,
-    188920457,
-    189107250,
-    189203987,
-    189371817,
-    189414886,
-    189567458,
-    190266670,
-    191318187,
-    191337609,
-    202479203,
-    202493027,
-    202835587,
-    202843747,
-    203013219,
-    203036048,
-    203045987,
-    203177552,
-    203898516,
-    204648562,
-    205067918,
-    205078130,
-    205096654,
-    205689142,
-    205690439,
-    205988909,
-    207213161,
-    207794484,
-    207800999,
-    208023602,
-    208213644,
-    208213647,
-    210261490,
-    210310273,
-    210940978,
-    213325049,
-    213946445,
-    214055079,
-    215125040,
-    215134273,
-    215135028,
-    215237420,
-    215418148,
-    215553166,
-    215553394,
-    215563858,
-    215627949,
-    215754324,
-    217529652,
-    217713834,
-    217732628,
-    218731945,
-    221417045,
-    221424946,
-    221493746,
-    221515401,
-    221658189,
-    221908140,
-    221910626,
-    221921586,
-    222659762,
-    225001091,
-    236105833,
-    236113965,
-    236194995,
-    236195427,
-    236206132,
-    236206387,
-    236211683,
-    236212707,
-    236381647,
-    236571826,
-    237124271,
-    238172205,
-    238210544,
-    238270764,
-    238435405,
-    238501172,
-    239224867,
-    239257644,
-    239710497,
-    240307721,
-    241208789,
-    241241557,
-    241318060,
-    241319404,
-    241343533,
-    241344069,
-    241405397,
-    241765845,
-    243864964,
-    244502085,
-    244946220,
-    245109902,
-    247647266,
-    247707956,
-    248648814,
-    248648836,
-    248682161,
-    248986932,
-    249058914,
-    249697357,
-    252132601,
-    252135604,
-    252317348,
-    255007012,
-    255278388,
-    255641645,
-    256365156,
-    257566121,
-    269763372,
-    271202790,
-    271863856,
-    272049197,
-    272127474,
-    274339449,
-    274939471,
-    275388004,
-    275388005,
-    275388006,
-    275977800,
-    278267602,
-    278513831,
-    278712622,
-    281613765,
-    281683369,
-    282120228,
-    282250732,
-    282508942,
-    283743649,
-    283787570,
-    284710386,
-    285391148,
-    285478533,
-    285854898,
-    285873762,
-    286931113,
-    288964227,
-    289445441,
-    289689648,
-    291671489,
-    303512884,
-    305319975,
-    305610036,
-    305764101,
-    308448294,
-    308675890,
-    312085683,
-    312264750,
-    315032867,
-    316391000,
-    317331042,
-    317902135,
-    318950711,
-    319447220,
-    321499182,
-    322538804,
-    323145200,
-    337067316,
-    337826293,
-    339905989,
-    340833697,
-    341457068,
-    342310196,
-    345302593,
-    349554733,
-    349771471,
-    349786245,
-    350819405,
-    356072847,
-    370349192,
-    373962798,
-    375558638,
-    375574835,
-    376053993,
-    383276530,
-    383373833,
-    383407586,
-    384439906,
-    386079012,
-    404133513,
-    404307343,
-    407031852,
-    408072233,
-    409112005,
-    409608425,
-    409771500,
-    419040932,
-    437730612,
-    439529766,
-    442616365,
-    442813037,
-    443157674,
-    443295316,
-    450118444,
-    450482697,
-    456789668,
-    459935396,
-    471217869,
-    474073645,
-    476230702,
-    476665218,
-    476717289,
-    483014825,
-    485083298,
-    489306281,
-    538364390,
-    540675748,
-    543819186,
-    543958612,
-    576960820,
-    577242548,
-    610515252,
-    642202932,
-    644420819,
-    };
+public static final ElementName BIG = new ElementName("big", "big",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName BDI = new ElementName("bdi", "bdi",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName BDO = new ElementName("bdo", "bdo",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName COL = new ElementName("col", "col",
+// CPPONLY: NS_NewHTMLTableColElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.COL | SPECIAL);
+public static final ElementName DEL = new ElementName("del", "del",
+// CPPONLY: NS_NewHTMLModElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName DFN = new ElementName("dfn", "dfn",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName DIR = new ElementName("dir", "dir",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName DIV = new ElementName("div", "div",
+// CPPONLY: NS_NewHTMLDivElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+public static final ElementName IMG = new ElementName("img", "img",
+// CPPONLY: NS_NewHTMLImageElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.IMG | SPECIAL);
+public static final ElementName INS = new ElementName("ins", "ins",
+// CPPONLY: NS_NewHTMLModElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName KBD = new ElementName("kbd", "kbd",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName MAP = new ElementName("map", "map",
+// CPPONLY: NS_NewHTMLMapElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName NAV = new ElementName("nav", "nav",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName PRE = new ElementName("pre", "pre",
+// CPPONLY: NS_NewHTMLPreElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PRE_OR_LISTING | SPECIAL);
+public static final ElementName A = new ElementName("a", "a",
+// CPPONLY: NS_NewHTMLAnchorElement,
+// CPPONLY: NS_NewSVGAElement,
+TreeBuilder.A);
+public static final ElementName B = new ElementName("b", "b",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName RTC = new ElementName("rtc", "rtc",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RB_OR_RTC | OPTIONAL_END_TAG);
+public static final ElementName SUB = new ElementName("sub", "sub",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+public static final ElementName SVG = new ElementName("svg", "svg",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGSVGElement,
+TreeBuilder.SVG);
+public static final ElementName SUP = new ElementName("sup", "sup",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+public static final ElementName SET = new ElementName("set", "set",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGSetElement,
+TreeBuilder.OTHER);
+public static final ElementName USE = new ElementName("use", "use",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUseElement,
+TreeBuilder.OTHER);
+public static final ElementName VAR = new ElementName("var", "var",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+public static final ElementName G = new ElementName("g", "g",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGGElement,
+TreeBuilder.OTHER);
+public static final ElementName WBR = new ElementName("wbr", "wbr",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.AREA_OR_WBR | SPECIAL);
+public static final ElementName XMP = new ElementName("xmp", "xmp",
+// CPPONLY: NS_NewHTMLPreElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.XMP | SPECIAL);
+public static final ElementName I = new ElementName("i", "i",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName P = new ElementName("p", "p",
+// CPPONLY: NS_NewHTMLParagraphElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.P | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName Q = new ElementName("q", "q",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName S = new ElementName("s", "s",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName U = new ElementName("u", "u",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName H1 = new ElementName("h1", "h1",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName H2 = new ElementName("h2", "h2",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName H3 = new ElementName("h3", "h3",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName H4 = new ElementName("h4", "h4",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName H5 = new ElementName("h5", "h5",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName H6 = new ElementName("h6", "h6",
+// CPPONLY: NS_NewHTMLHeadingElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 | SPECIAL);
+public static final ElementName AREA = new ElementName("area", "area",
+// CPPONLY: NS_NewHTMLAreaElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.AREA_OR_WBR | SPECIAL);
+public static final ElementName DATA = new ElementName("data", "data",
+// CPPONLY: NS_NewHTMLDataElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName FEFUNCA = new ElementName("fefunca", "feFuncA",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEFuncAElement,
+TreeBuilder.OTHER);
+public static final ElementName METADATA = new ElementName("metadata", "metadata",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGMetadataElement,
+TreeBuilder.OTHER);
+public static final ElementName META = new ElementName("meta", "meta",
+// CPPONLY: NS_NewHTMLMetaElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.META | SPECIAL);
+public static final ElementName TEXTAREA = new ElementName("textarea", "textarea",
+// CPPONLY: NS_NewHTMLTextAreaElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TEXTAREA | SPECIAL);
+public static final ElementName FEFUNCB = new ElementName("fefuncb", "feFuncB",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEFuncBElement,
+TreeBuilder.OTHER);
+public static final ElementName RB = new ElementName("rb", "rb",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RB_OR_RTC | OPTIONAL_END_TAG);
+public static final ElementName DESC = new ElementName("desc", "desc",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGDescElement,
+TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
+public static final ElementName DD = new ElementName("dd", "dd",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName BGSOUND = new ElementName("bgsound", "bgsound",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+public static final ElementName EMBED = new ElementName("embed", "embed",
+// CPPONLY: NS_NewHTMLEmbedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.EMBED | SPECIAL);
+public static final ElementName FEBLEND = new ElementName("feblend", "feBlend",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEBlendElement,
+TreeBuilder.OTHER);
+public static final ElementName FEFLOOD = new ElementName("feflood", "feFlood",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEFloodElement,
+TreeBuilder.OTHER);
+public static final ElementName HEAD = new ElementName("head", "head",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.HEAD | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName LEGEND = new ElementName("legend", "legend",
+// CPPONLY: NS_NewHTMLLegendElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName NOEMBED = new ElementName("noembed", "noembed",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.NOEMBED | SPECIAL);
+public static final ElementName TD = new ElementName("td", "td",
+// CPPONLY: NS_NewHTMLTableCellElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+public static final ElementName THEAD = new ElementName("thead", "thead",
+// CPPONLY: NS_NewHTMLTableSectionElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+public static final ElementName ASIDE = new ElementName("aside", "aside",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName ARTICLE = new ElementName("article", "article",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName ANIMATE = new ElementName("animate", "animate",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGAnimateElement,
+TreeBuilder.OTHER);
+public static final ElementName BASE = new ElementName("base", "base",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.BASE | SPECIAL);
+public static final ElementName BLOCKQUOTE = new ElementName("blockquote", "blockquote",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+public static final ElementName CODE = new ElementName("code", "code",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName CIRCLE = new ElementName("circle", "circle",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGCircleElement,
+TreeBuilder.OTHER);
+public static final ElementName CITE = new ElementName("cite", "cite",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName ELLIPSE = new ElementName("ellipse", "ellipse",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGEllipseElement,
+TreeBuilder.OTHER);
+public static final ElementName FETURBULENCE = new ElementName("feturbulence", "feTurbulence",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFETurbulenceElement,
+TreeBuilder.OTHER);
+public static final ElementName FEMERGENODE = new ElementName("femergenode", "feMergeNode",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEMergeNodeElement,
+TreeBuilder.OTHER);
+public static final ElementName FEIMAGE = new ElementName("feimage", "feImage",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEImageElement,
+TreeBuilder.OTHER);
+public static final ElementName FEMERGE = new ElementName("femerge", "feMerge",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEMergeElement,
+TreeBuilder.OTHER);
+public static final ElementName FETILE = new ElementName("fetile", "feTile",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFETileElement,
+TreeBuilder.OTHER);
+public static final ElementName FRAME = new ElementName("frame", "frame",
+// CPPONLY: NS_NewHTMLFrameElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.FRAME | SPECIAL);
+public static final ElementName FIGURE = new ElementName("figure", "figure",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName FECOMPOSITE = new ElementName("fecomposite", "feComposite",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFECompositeElement,
+TreeBuilder.OTHER);
+public static final ElementName IMAGE = new ElementName("image", "image",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGImageElement,
+TreeBuilder.IMAGE);
+public static final ElementName IFRAME = new ElementName("iframe", "iframe",
+// CPPONLY: NS_NewHTMLIFrameElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.IFRAME | SPECIAL);
+public static final ElementName LINE = new ElementName("line", "line",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGLineElement,
+TreeBuilder.OTHER);
+public static final ElementName MARQUEE = new ElementName("marquee", "marquee",
+// CPPONLY: NS_NewHTMLMarqueeElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
+public static final ElementName POLYLINE = new ElementName("polyline", "polyline",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGPolylineElement,
+TreeBuilder.OTHER);
+public static final ElementName PICTURE = new ElementName("picture", "picture",
+// CPPONLY: NS_NewHTMLPictureElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName SOURCE = new ElementName("source", "source",
+// CPPONLY: NS_NewHTMLSourceElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PARAM_OR_SOURCE_OR_TRACK);
+public static final ElementName STRIKE = new ElementName("strike", "strike",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName STYLE = new ElementName("style", "style",
+// CPPONLY: NS_NewHTMLStyleElement,
+// CPPONLY: NS_NewSVGStyleElement,
+TreeBuilder.STYLE | SPECIAL);
+public static final ElementName TABLE = new ElementName("table", "table",
+// CPPONLY: NS_NewHTMLTableElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TABLE | SPECIAL | FOSTER_PARENTING | SCOPING);
+public static final ElementName TITLE = new ElementName("title", "title",
+// CPPONLY: NS_NewHTMLTitleElement,
+// CPPONLY: NS_NewSVGTitleElement,
+TreeBuilder.TITLE | SPECIAL | SCOPING_AS_SVG);
+public static final ElementName TIME = new ElementName("time", "time",
+// CPPONLY: NS_NewHTMLTimeElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName TEMPLATE = new ElementName("template", "template",
+// CPPONLY: NS_NewHTMLTemplateElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TEMPLATE | SPECIAL | SCOPING);
+public static final ElementName ALTGLYPHDEF = new ElementName("altglyphdef", "altGlyphDef",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName GLYPHREF = new ElementName("glyphref", "glyphRef",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName DIALOG = new ElementName("dialog", "dialog",
+// CPPONLY: NS_NewHTMLDialogElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName FEFUNCG = new ElementName("fefuncg", "feFuncG",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEFuncGElement,
+TreeBuilder.OTHER);
+public static final ElementName FEDIFFUSELIGHTING = new ElementName("fediffuselighting", "feDiffuseLighting",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEDiffuseLightingElement,
+TreeBuilder.OTHER);
+public static final ElementName FESPECULARLIGHTING = new ElementName("fespecularlighting", "feSpecularLighting",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFESpecularLightingElement,
+TreeBuilder.OTHER);
+public static final ElementName LISTING = new ElementName("listing", "listing",
+// CPPONLY: NS_NewHTMLPreElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PRE_OR_LISTING | SPECIAL);
+public static final ElementName STRONG = new ElementName("strong", "strong",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName ALTGLYPH = new ElementName("altglyph", "altGlyph",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName CLIPPATH = new ElementName("clippath", "clipPath",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGClipPathElement,
+TreeBuilder.OTHER);
+public static final ElementName MGLYPH = new ElementName("mglyph", "mglyph",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MGLYPH_OR_MALIGNMARK);
+public static final ElementName MATH = new ElementName("math", "math",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MATH);
+public static final ElementName MPATH = new ElementName("mpath", "mpath",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGMPathElement,
+TreeBuilder.OTHER);
+public static final ElementName PATH = new ElementName("path", "path",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGPathElement,
+TreeBuilder.OTHER);
+public static final ElementName TH = new ElementName("th", "th",
+// CPPONLY: NS_NewHTMLTableCellElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TD_OR_TH | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+public static final ElementName SEARCH = new ElementName("search", "search",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName SWITCH = new ElementName("switch", "switch",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGSwitchElement,
+TreeBuilder.OTHER);
+public static final ElementName TEXTPATH = new ElementName("textpath", "textPath",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGTextPathElement,
+TreeBuilder.OTHER);
+public static final ElementName LI = new ElementName("li", "li",
+// CPPONLY: NS_NewHTMLLIElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.LI | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName MI = new ElementName("mi", "mi",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+public static final ElementName LINK = new ElementName("link", "link",
+// CPPONLY: NS_NewHTMLLinkElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+public static final ElementName MARK = new ElementName("mark", "mark",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName MALIGNMARK = new ElementName("malignmark", "malignmark",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MGLYPH_OR_MALIGNMARK);
+public static final ElementName MASK = new ElementName("mask", "mask",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGMaskElement,
+TreeBuilder.OTHER);
+public static final ElementName TRACK = new ElementName("track", "track",
+// CPPONLY: NS_NewHTMLTrackElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PARAM_OR_SOURCE_OR_TRACK | SPECIAL);
+public static final ElementName DL = new ElementName("dl", "dl",
+// CPPONLY: NS_NewHTMLSharedListElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+public static final ElementName HTML = new ElementName("html", "html",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.HTML | SPECIAL | SCOPING | OPTIONAL_END_TAG);
+public static final ElementName OL = new ElementName("ol", "ol",
+// CPPONLY: NS_NewHTMLSharedListElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+public static final ElementName LABEL = new ElementName("label", "label",
+// CPPONLY: NS_NewHTMLLabelElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName UL = new ElementName("ul", "ul",
+// CPPONLY: NS_NewHTMLSharedListElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.UL_OR_OL_OR_DL | SPECIAL);
+public static final ElementName SMALL = new ElementName("small", "small",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName SYMBOL = new ElementName("symbol", "symbol",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGSymbolElement,
+TreeBuilder.OTHER);
+public static final ElementName ALTGLYPHITEM = new ElementName("altglyphitem", "altGlyphItem",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName ANIMATETRANSFORM = new ElementName("animatetransform", "animateTransform",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGAnimateTransformElement,
+TreeBuilder.OTHER);
+public static final ElementName ACRONYM = new ElementName("acronym", "acronym",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName EM = new ElementName("em", "em",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName FORM = new ElementName("form", "form",
+// CPPONLY: NS_NewHTMLFormElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.FORM | SPECIAL);
+public static final ElementName PARAM = new ElementName("param", "param",
+// CPPONLY: NS_NewHTMLSharedElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PARAM_OR_SOURCE_OR_TRACK | SPECIAL);
+public static final ElementName ANIMATEMOTION = new ElementName("animatemotion", "animateMotion",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGAnimateMotionElement,
+TreeBuilder.OTHER);
+public static final ElementName BUTTON = new ElementName("button", "button",
+// CPPONLY: NS_NewHTMLButtonElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.BUTTON | SPECIAL);
+public static final ElementName CAPTION = new ElementName("caption", "caption",
+// CPPONLY: NS_NewHTMLTableCaptionElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.CAPTION | SPECIAL | SCOPING);
+public static final ElementName FIGCAPTION = new ElementName("figcaption", "figcaption",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName MN = new ElementName("mn", "mn",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+public static final ElementName KEYGEN = new ElementName("keygen", "keygen",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.KEYGEN | SPECIAL);
+public static final ElementName MAIN = new ElementName("main", "main",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName OPTION = new ElementName("option", "option",
+// CPPONLY: NS_NewHTMLOptionElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OPTION | OPTIONAL_END_TAG);
+public static final ElementName POLYGON = new ElementName("polygon", "polygon",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGPolygonElement,
+TreeBuilder.OTHER);
+public static final ElementName PATTERN = new ElementName("pattern", "pattern",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGPatternElement,
+TreeBuilder.OTHER);
+public static final ElementName SPAN = new ElementName("span", "span",
+// CPPONLY: NS_NewHTMLSpanElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+public static final ElementName SECTION = new ElementName("section", "section",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName TSPAN = new ElementName("tspan", "tspan",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGTSpanElement,
+TreeBuilder.OTHER);
+public static final ElementName AUDIO = new ElementName("audio", "audio",
+// CPPONLY: NS_NewHTMLAudioElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName MO = new ElementName("mo", "mo",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+public static final ElementName VIDEO = new ElementName("video", "video",
+// CPPONLY: NS_NewHTMLVideoElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName COLGROUP = new ElementName("colgroup", "colgroup",
+// CPPONLY: NS_NewHTMLTableColElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.COLGROUP | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName FEDISPLACEMENTMAP = new ElementName("fedisplacementmap", "feDisplacementMap",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEDisplacementMapElement,
+TreeBuilder.OTHER);
+public static final ElementName HGROUP = new ElementName("hgroup", "hgroup",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName RP = new ElementName("rp", "rp",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
+public static final ElementName OPTGROUP = new ElementName("optgroup", "optgroup",
+// CPPONLY: NS_NewHTMLOptGroupElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OPTGROUP | OPTIONAL_END_TAG);
+public static final ElementName SAMP = new ElementName("samp", "samp",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName STOP = new ElementName("stop", "stop",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGStopElement,
+TreeBuilder.OTHER);
+public static final ElementName BR = new ElementName("br", "br",
+// CPPONLY: NS_NewHTMLBRElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.BR | SPECIAL);
+public static final ElementName ABBR = new ElementName("abbr", "abbr",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName ANIMATECOLOR = new ElementName("animatecolor", "animateColor",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName CENTER = new ElementName("center", "center",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+public static final ElementName HR = new ElementName("hr", "hr",
+// CPPONLY: NS_NewHTMLHRElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.HR | SPECIAL);
+public static final ElementName FEFUNCR = new ElementName("fefuncr", "feFuncR",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEFuncRElement,
+TreeBuilder.OTHER);
+public static final ElementName FECOMPONENTTRANSFER = new ElementName("fecomponenttransfer", "feComponentTransfer",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEComponentTransferElement,
+TreeBuilder.OTHER);
+public static final ElementName FILTER = new ElementName("filter", "filter",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFilterElement,
+TreeBuilder.OTHER);
+public static final ElementName FOOTER = new ElementName("footer", "footer",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName FEGAUSSIANBLUR = new ElementName("fegaussianblur", "feGaussianBlur",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEGaussianBlurElement,
+TreeBuilder.OTHER);
+public static final ElementName HEADER = new ElementName("header", "header",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName MARKER = new ElementName("marker", "marker",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGMarkerElement,
+TreeBuilder.OTHER);
+public static final ElementName METER = new ElementName("meter", "meter",
+// CPPONLY: NS_NewHTMLMeterElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName NOBR = new ElementName("nobr", "nobr",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.NOBR);
+public static final ElementName TR = new ElementName("tr", "tr",
+// CPPONLY: NS_NewHTMLTableRowElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TR | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+public static final ElementName ADDRESS = new ElementName("address", "address",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName CANVAS = new ElementName("canvas", "canvas",
+// CPPONLY: NS_NewHTMLCanvasElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName DEFS = new ElementName("defs", "defs",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGDefsElement,
+TreeBuilder.OTHER);
+public static final ElementName DETAILS = new ElementName("details", "details",
+// CPPONLY: NS_NewHTMLDetailsElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName MS = new ElementName("ms", "ms",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+public static final ElementName NOFRAMES = new ElementName("noframes", "noframes",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.NOFRAMES | SPECIAL);
+public static final ElementName PROGRESS = new ElementName("progress", "progress",
+// CPPONLY: NS_NewHTMLProgressElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName DT = new ElementName("dt", "dt",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DD_OR_DT | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName APPLET = new ElementName("applet", "applet",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MARQUEE_OR_APPLET | SPECIAL | SCOPING);
+public static final ElementName BASEFONT = new ElementName("basefont", "basefont",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.LINK_OR_BASEFONT_OR_BGSOUND | SPECIAL);
+public static final ElementName DATALIST = new ElementName("datalist", "datalist",
+// CPPONLY: NS_NewHTMLDataListElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName FOREIGNOBJECT = new ElementName("foreignobject", "foreignObject",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGForeignObjectElement,
+TreeBuilder.FOREIGNOBJECT_OR_DESC | SCOPING_AS_SVG);
+public static final ElementName FIELDSET = new ElementName("fieldset", "fieldset",
+// CPPONLY: NS_NewHTMLFieldSetElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.FIELDSET | SPECIAL);
+public static final ElementName FRAMESET = new ElementName("frameset", "frameset",
+// CPPONLY: NS_NewHTMLFrameSetElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.FRAMESET | SPECIAL);
+public static final ElementName FEOFFSET = new ElementName("feoffset", "feOffset",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEOffsetElement,
+TreeBuilder.OTHER);
+public static final ElementName FESPOTLIGHT = new ElementName("fespotlight", "feSpotLight",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFESpotLightElement,
+TreeBuilder.OTHER);
+public static final ElementName FEPOINTLIGHT = new ElementName("fepointlight", "fePointLight",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEPointLightElement,
+TreeBuilder.OTHER);
+public static final ElementName FEDISTANTLIGHT = new ElementName("fedistantlight", "feDistantLight",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEDistantLightElement,
+TreeBuilder.OTHER);
+public static final ElementName FONT = new ElementName("font", "font",
+// CPPONLY: NS_NewHTMLFontElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.FONT);
+public static final ElementName INPUT = new ElementName("input", "input",
+// CPPONLY: NS_NewHTMLInputElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.INPUT | SPECIAL);
+public static final ElementName LINEARGRADIENT = new ElementName("lineargradient", "linearGradient",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGLinearGradientElement,
+TreeBuilder.OTHER);
+public static final ElementName MTEXT = new ElementName("mtext", "mtext",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.MI_MO_MN_MS_MTEXT | SCOPING_AS_MATHML);
+public static final ElementName NOSCRIPT = new ElementName("noscript", "noscript",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.NOSCRIPT | SPECIAL);
+public static final ElementName RT = new ElementName("rt", "rt",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RT_OR_RP | OPTIONAL_END_TAG);
+public static final ElementName OBJECT = new ElementName("object", "object",
+// CPPONLY: NS_NewHTMLObjectElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OBJECT | SPECIAL | SCOPING);
+public static final ElementName OUTPUT = new ElementName("output", "output",
+// CPPONLY: NS_NewHTMLOutputElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OUTPUT);
+public static final ElementName PLAINTEXT = new ElementName("plaintext", "plaintext",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.PLAINTEXT | SPECIAL);
+public static final ElementName TT = new ElementName("tt", "tt",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
+public static final ElementName RECT = new ElementName("rect", "rect",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGRectElement,
+TreeBuilder.OTHER);
+public static final ElementName RADIALGRADIENT = new ElementName("radialgradient", "radialGradient",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGRadialGradientElement,
+TreeBuilder.OTHER);
+public static final ElementName SELECT = new ElementName("select", "select",
+// CPPONLY: NS_NewHTMLSelectElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.SELECT | SPECIAL);
+public static final ElementName SLOT = new ElementName("slot", "slot",
+// CPPONLY: NS_NewHTMLSlotElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.OTHER);
+public static final ElementName SCRIPT = new ElementName("script", "script",
+// CPPONLY: NS_NewHTMLScriptElement,
+// CPPONLY: NS_NewSVGScriptElement,
+TreeBuilder.SCRIPT | SPECIAL);
+public static final ElementName TFOOT = new ElementName("tfoot", "tfoot",
+// CPPONLY: NS_NewHTMLTableSectionElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+public static final ElementName TEXT = new ElementName("text", "text",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGTextElement,
+TreeBuilder.OTHER);
+public static final ElementName MENU = new ElementName("menu", "menu",
+// CPPONLY: NS_NewHTMLMenuElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU | SPECIAL);
+public static final ElementName FEDROPSHADOW = new ElementName("fedropshadow", "feDropShadow",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEDropShadowElement,
+TreeBuilder.OTHER);
+public static final ElementName VIEW = new ElementName("view", "view",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGViewElement,
+TreeBuilder.OTHER);
+public static final ElementName FECOLORMATRIX = new ElementName("fecolormatrix", "feColorMatrix",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEColorMatrixElement,
+TreeBuilder.OTHER);
+public static final ElementName FECONVOLVEMATRIX = new ElementName("feconvolvematrix", "feConvolveMatrix",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEConvolveMatrixElement,
+TreeBuilder.OTHER);
+public static final ElementName BODY = new ElementName("body", "body",
+// CPPONLY: NS_NewHTMLBodyElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.BODY | SPECIAL | OPTIONAL_END_TAG);
+public static final ElementName FEMORPHOLOGY = new ElementName("femorphology", "feMorphology",
+// CPPONLY: NS_NewHTMLUnknownElement,
+// CPPONLY: NS_NewSVGFEMorphologyElement,
+TreeBuilder.OTHER);
+public static final ElementName RUBY = new ElementName("ruby", "ruby",
+// CPPONLY: NS_NewHTMLElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR);
+public static final ElementName SUMMARY = new ElementName("summary", "summary",
+// CPPONLY: NS_NewHTMLSummaryElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY | SPECIAL);
+public static final ElementName TBODY = new ElementName("tbody", "tbody",
+// CPPONLY: NS_NewHTMLTableSectionElement,
+// CPPONLY: NS_NewSVGUnknownElement,
+TreeBuilder.TBODY_OR_THEAD_OR_TFOOT | SPECIAL | FOSTER_PARENTING | OPTIONAL_END_TAG);
+private final static @NoLength ElementName[] ELEMENT_NAMES = {
+FIGCAPTION,
+CITE,
+FRAMESET,
+H1,
+CLIPPATH,
+METER,
+RADIALGRADIENT,
+B,
+BGSOUND,
+SOURCE,
+DL,
+RP,
+NOFRAMES,
+MTEXT,
+VIEW,
+DIV,
+G,
+FEFUNCA,
+THEAD,
+FIGURE,
+GLYPHREF,
+TEXTPATH,
+ANIMATETRANSFORM,
+SECTION,
+HR,
+CANVAS,
+BASEFONT,
+FEDISTANTLIGHT,
+OUTPUT,
+TFOOT,
+FEMORPHOLOGY,
+COL,
+MAP,
+SUP,
+P,
+H5,
+FEFUNCB,
+HEAD,
+BASE,
+FEIMAGE,
+LINE,
+TITLE,
+FESPECULARLIGHTING,
+PATH,
+MARK,
+UL,
+PARAM,
+OPTION,
+VIDEO,
+BR,
+FOOTER,
+TR,
+DETAILS,
+DT,
+FOREIGNOBJECT,
+FESPOTLIGHT,
+INPUT,
+RT,
+TT,
+SLOT,
+MENU,
+FECONVOLVEMATRIX,
+SUMMARY,
+BDI,
+DFN,
+INS,
+PRE,
+SUB,
+USE,
+XMP,
+S,
+H3,
+AREA,
+META,
+DESC,
+FEBLEND,
+NOEMBED,
+ARTICLE,
+CODE,
+FETURBULENCE,
+FETILE,
+IMAGE,
+POLYLINE,
+STYLE,
+TEMPLATE,
+FEFUNCG,
+STRONG,
+MATH,
+SEARCH,
+MI,
+MASK,
+OL,
+SYMBOL,
+EM,
+BUTTON,
+KEYGEN,
+PATTERN,
+AUDIO,
+FEDISPLACEMENTMAP,
+SAMP,
+ANIMATECOLOR,
+FECOMPONENTTRANSFER,
+HEADER,
+NOBR,
+ADDRESS,
+DEFS,
+MS,
+PROGRESS,
+APPLET,
+DATALIST,
+FIELDSET,
+FEOFFSET,
+FEPOINTLIGHT,
+FONT,
+LINEARGRADIENT,
+NOSCRIPT,
+OBJECT,
+PLAINTEXT,
+RECT,
+SELECT,
+SCRIPT,
+TEXT,
+FEDROPSHADOW,
+FECOLORMATRIX,
+BODY,
+RUBY,
+TBODY,
+BIG,
+BDO,
+DEL,
+DIR,
+IMG,
+KBD,
+NAV,
+A,
+RTC,
+SVG,
+SET,
+VAR,
+WBR,
+I,
+Q,
+U,
+H2,
+H4,
+H6,
+DATA,
+METADATA,
+TEXTAREA,
+RB,
+DD,
+EMBED,
+FEFLOOD,
+LEGEND,
+TD,
+ASIDE,
+ANIMATE,
+BLOCKQUOTE,
+CIRCLE,
+ELLIPSE,
+FEMERGENODE,
+FEMERGE,
+FRAME,
+FECOMPOSITE,
+IFRAME,
+MARQUEE,
+PICTURE,
+STRIKE,
+TABLE,
+TIME,
+ALTGLYPHDEF,
+DIALOG,
+FEDIFFUSELIGHTING,
+LISTING,
+ALTGLYPH,
+MGLYPH,
+MPATH,
+TH,
+SWITCH,
+LI,
+LINK,
+MALIGNMARK,
+TRACK,
+HTML,
+LABEL,
+SMALL,
+ALTGLYPHITEM,
+ACRONYM,
+FORM,
+ANIMATEMOTION,
+CAPTION,
+MN,
+MAIN,
+POLYGON,
+SPAN,
+TSPAN,
+MO,
+COLGROUP,
+HGROUP,
+OPTGROUP,
+STOP,
+ABBR,
+CENTER,
+FEFUNCR,
+FILTER,
+FEGAUSSIANBLUR,
+MARKER,
+};
+private final static int[] ELEMENT_HASHES = {
+1900845386,
+1748359220,
+2001349720,
+876609538,
+1798686984,
+1971465813,
+2007781534,
+59768833,
+1730965751,
+1756474198,
+1864368130,
+1938817026,
+1988763672,
+2005324101,
+2060065124,
+52490899,
+62390273,
+1682547543,
+1740181637,
+1749905526,
+1766992520,
+1807599880,
+1881498736,
+1907661127,
+1967128578,
+1982935782,
+1999397992,
+2001392798,
+2006329158,
+2008851557,
+2085266636,
+51961587,
+57206291,
+60352339,
+67108865,
+943718402,
+1699324759,
+1733890180,
+1747814436,
+1749715159,
+1752979652,
+1757146773,
+1783388498,
+1805502724,
+1854228692,
+1873281026,
+1889085973,
+1905563974,
+1925844629,
+1963982850,
+1967795958,
+1973420034,
+1983633431,
+1998585858,
+2001309869,
+2001392795,
+2003183333,
+2005925890,
+2006974466,
+2008325940,
+2021937364,
+2068523856,
+2092255447,
+51435587,
+52486755,
+55110883,
+58773795,
+60345171,
+61395251,
+62973651,
+68681729,
+910163970,
+1679960596,
+1686491348,
+1715310660,
+1733054663,
+1737099991,
+1747176599,
+1748100148,
+1749656156,
+1749801286,
+1751288021,
+1755076808,
+1756625221,
+1757268168,
+1783210839,
+1790207270,
+1803929812,
+1806805526,
+1818755074,
+1854245076,
+1870135298,
+1874102998,
+1881669634,
+1898753862,
+1903302038,
+1906135367,
+1914900309,
+1934172497,
+1941178676,
+1965334268,
+1967788867,
+1968836118,
+1971938532,
+1982173479,
+1983533124,
+1986527234,
+1990037800,
+1998724870,
+2000525512,
+2001349704,
+2001349736,
+2001392796,
+2001495140,
+2004635806,
+2005719336,
+2006028454,
+2006896969,
+2007601444,
+2008125638,
+2008340774,
+2008994116,
+2051837468,
+2068523853,
+2083120164,
+2091479332,
+2092557349,
+51434643,
+51438659,
+52485715,
+52488851,
+55104723,
+56151587,
+57733651,
+59244545,
+59821379,
+60347747,
+60354131,
+61925907,
+62450211,
+63438849,
+67633153,
+69730305,
+893386754,
+926941186,
+960495618,
+1681770564,
+1686489160,
+1689922072,
+1703936002,
+1730150402,
+1732381397,
+1733076167,
+1736200310,
+1738539010,
+1747048757,
+1747306711,
+1747838298,
+1748225318,
+1749395095,
+1749673195,
+1749723735,
+1749813541,
+1749932347,
+1751386406,
+1753362711,
+1755148615,
+1756600614,
+1757137429,
+1757157700,
+1763839627,
+1782357526,
+1783388497,
+1786534215,
+1797585096,
+1803876550,
+1803929861,
+1805647874,
+1806806678,
+1818230786,
+1853642948,
+1854228698,
+1857653029,
+1868312196,
+1870268949,
+1874053333,
+1881288348,
+1881613047,
+1884120164,
+1898223949,
+1899272519,
+1902641154,
+1904412884,
+1906087319,
+1907435316,
+1907959605,
+1919418370,
+1932928296,
+1935549734,
+1939219752,
+1941221172,
+1965115924,
+1966223078,
+1967760215,
+1967795910,
+1968053806,
+1971461414,
+};
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,38 +1,38 @@
 /*
- * Copyright (c) 2009-2010 Mozilla Foundation
+ * Copyright (c) 2009-2017 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
+import java.util.HashMap;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
 import nu.validator.htmlparser.annotation.Inline;
 import nu.validator.htmlparser.annotation.NoLength;
 import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.common.TransitionHandler;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 
-import java.util.HashMap;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
 public class ErrorReportingTokenizer extends Tokenizer {
 
     /**
@@ -46,11 +46,6 @@ public class ErrorReportingTokenizer ext
     private XmlViolationPolicy contentNonXmlCharPolicy = XmlViolationPolicy.ALTER_INFOSET;
 
     /**
-     * Used together with <code>nonAsciiProhibited</code>.
-     */
-    private boolean alreadyComplainedAboutNonAscii;
-
-    /**
      * Keeps track of PUA warnings.
      */
     private boolean alreadyWarnedAboutPrivateUseCharacters;
@@ -121,7 +116,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Sets the contentNonXmlCharPolicy.
-     * 
+     *
      * @param contentNonXmlCharPolicy
      *            the contentNonXmlCharPolicy to set
      */
@@ -132,7 +127,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Sets the errorProfile.
-     * 
+     *
      * @param errorProfile
      */
     public void setErrorProfile(HashMap<String, String> errorProfileMap) {
@@ -140,8 +135,17 @@ public class ErrorReportingTokenizer ext
     }
 
     /**
+     * Gets the errorProfile.
+     *
+     * @param errorProfile
+     */
+    @Override public HashMap getErrorProfile() {
+        return errorProfileMap;
+    }
+
+    /**
      * Reports on an event based on profile selected.
-     * 
+     *
      * @param profile
      *            the profile this message belongs to
      * @param message
@@ -162,7 +166,6 @@ public class ErrorReportingTokenizer ext
     }
 
     protected void startErrorReporting() throws SAXException {
-        alreadyComplainedAboutNonAscii = false;
         line = linePrev = 0;
         col = colPrev = 1;
         nextCharOnNewLine = true;
@@ -182,7 +185,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Returns the line.
-     * 
+     *
      * @return the line
      */
     public int getLine() {
@@ -191,7 +194,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Returns the col.
-     * 
+     *
      * @return the col
      */
     public int getCol() {
@@ -200,43 +203,21 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Returns the nextCharOnNewLine.
-     * 
+     *
      * @return the nextCharOnNewLine
      */
     public boolean isNextCharOnNewLine() {
         return nextCharOnNewLine;
     }
 
-    private void complainAboutNonAscii() throws SAXException {
-        String encoding = null;
-        if (encodingDeclarationHandler != null) {
-            encoding = encodingDeclarationHandler.getCharacterEncoding();
-        }
-        if (encoding == null) {
-            err("The character encoding of the document was not explicit but the document contains non-ASCII.");
-        } else {
-            err("No explicit character encoding declaration has been seen yet (assumed \u201C"
-                    + encoding + "\u201D) but the document contains non-ASCII.");
-        }
-    }
-
-    /**
-     * Returns the alreadyComplainedAboutNonAscii.
-     * 
-     * @return the alreadyComplainedAboutNonAscii
-     */
-    public boolean isAlreadyComplainedAboutNonAscii() {
-        return alreadyComplainedAboutNonAscii;
-    }
-
     /**
      * Flushes coalesced character tokens.
-     * 
+     *
      * @param buf
      *            TODO
      * @param pos
      *            TODO
-     * 
+     *
      * @throws SAXException
      */
     @Override protected void flushChars(char[] buf, int pos)
@@ -266,10 +247,6 @@ public class ErrorReportingTokenizer ext
         }
 
         char c = buf[pos];
-        if (!confident && !alreadyComplainedAboutNonAscii && c > '\u007F') {
-            complainAboutNonAscii();
-            alreadyComplainedAboutNonAscii = true;
-        }
         switch (c) {
             case '\u0000':
                 err("Saw U+0000 in stream.");
@@ -359,7 +336,7 @@ public class ErrorReportingTokenizer ext
     /**
      * Emits a warning about private use characters if the warning has not been
      * emitted yet.
-     * 
+     *
      * @throws SAXException
      */
     private void warnAboutPrivateUseChar() throws SAXException {
@@ -371,7 +348,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Tells if the argument is a BMP PUA character.
-     * 
+     *
      * @param c
      *            the UTF-16 code unit to check
      * @return <code>true</code> if PUA character
@@ -382,7 +359,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Tells if the argument is an astral PUA character.
-     * 
+     *
      * @param c
      *            the code point to check
      * @return <code>true</code> if astral private use
@@ -401,28 +378,10 @@ public class ErrorReportingTokenizer ext
     }
 
     @Override protected void errWarnLtSlashInRcdata() throws SAXException {
-        if (html4) {
-            err((stateSave == Tokenizer.DATA ? "CDATA" : "RCDATA")
-                    + " element \u201C"
-                    + endTagExpectation
-                    + "\u201D contained the string \u201C</\u201D, but it was not the start of the end tag. (HTML4-only error)");
-        } else {
-            warn((stateSave == Tokenizer.DATA ? "CDATA" : "RCDATA")
-                    + " element \u201C"
-                    + endTagExpectation
-                    + "\u201D contained the string \u201C</\u201D, but this did not close the element.");
-        }
-    }
-
-    @Override protected void errHtml4LtSlashInRcdata(char folded)
-            throws SAXException {
-        if (html4 && (index > 0 || (folded >= 'a' && folded <= 'z'))
-                && ElementName.IFRAME != endTagExpectation) {
-            err((stateSave == Tokenizer.DATA ? "CDATA" : "RCDATA")
-                    + " element \u201C"
-                    + endTagExpectation.name
-                    + "\u201D contained the string \u201C</\u201D, but it was not the start of the end tag. (HTML4-only error)");
-        }
+        warn((stateSave == Tokenizer.DATA ? "CDATA" : "RCDATA")
+                + " element \u201C"
+                + endTagExpectation
+                + "\u201D contained the string \u201C</\u201D, but this did not close the element.");
     }
 
     @Override protected void errCharRefLacksSemicolon() throws SAXException {
@@ -445,8 +404,8 @@ public class ErrorReportingTokenizer ext
         err("Nameless doctype.");
     }
 
-    @Override protected void errConsecutiveHyphens() throws SAXException {
-        err("Consecutive hyphens did not terminate a comment. \u201C--\u201D is not permitted inside a comment, but e.g. \u201C- -\u201D is.");
+    @Override protected void errNestedComment() throws SAXException {
+        err("Saw \u201C<!--\u201D within a comment. Probable cause: Nested comment (not allowed).");
     }
 
     @Override protected void errPrematureEndOfComment() throws SAXException {
@@ -477,29 +436,13 @@ public class ErrorReportingTokenizer ext
     }
 
     @Override protected void errSlashNotFollowedByGt() throws SAXException {
-        err("A slash was not immediate followed by \u201C>\u201D.");
-    }
-
-    @Override protected void errHtml4XmlVoidSyntax() throws SAXException {
-        if (html4) {
-            err("The \u201C/>\u201D syntax on void elements is not allowed.  (This is an HTML4-only error.)");
-        }
+        err("A slash was not immediately followed by \u201C>\u201D.");
     }
 
     @Override protected void errNoSpaceBetweenAttributes() throws SAXException {
         err("No space between attributes.");
     }
 
-    @Override protected void errHtml4NonNameInUnquotedAttribute(char c)
-            throws SAXException {
-        if (html4
-                && !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
-                        || (c >= '0' && c <= '9') || c == '.' || c == '-'
-                        || c == '_' || c == ':')) {
-            err("Non-name character in an unquoted attribute value. (This is an HTML4-only error.)");
-        }
-    }
-
     @Override protected void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(
             char c) throws SAXException {
         switch (c) {
@@ -744,10 +687,6 @@ public class ErrorReportingTokenizer ext
         err("Missing space before doctype name.");
     }
 
-    @Override protected void errHyphenHyphenBang() throws SAXException {
-        err("\u201C--!\u201D found in comment.");
-    }
-
     @Override protected void errNcrControlChar() throws SAXException {
         err("Character reference expands to a control character ("
                 + toUPlusString((char) value) + ").");
@@ -782,7 +721,7 @@ public class ErrorReportingTokenizer ext
 
     /**
      * Sets the transitionHandler.
-     * 
+     *
      * @param transitionHandler
      *            the transitionHandler to set
      */
@@ -793,7 +732,7 @@ public class ErrorReportingTokenizer ext
     /**
      * Sets an offset to be added to the position reported to
      * <code>TransitionHandler</code>.
-     * 
+     *
      * @param offset
      *            the offset
      */
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/HotSpotWorkaround.txt 1.4+r20250916-1/src/nu/validator/htmlparser/impl/HotSpotWorkaround.txt
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/HotSpotWorkaround.txt	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/HotSpotWorkaround.txt	2025-09-16 08:29:41.000000000 +0000
@@ -20,6 +20,12 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+   /**
+    * compressed returnValue:
+    *   int     returnState     = returnValue >> 33
+    *   boolean breakOuterState = ((returnValue >> 32) & 0x1) != 0)
+    *   int     pos             = returnValue & 0xFFFFFFFF // same as (int)returnValue
+    */  
     @SuppressWarnings("unused") private long workAroundHotSpotHugeMethodLimit(
             int state, char c, int pos, @NoLength char[] buf,
             boolean reconsume, int returnState, int endPos) throws SAXException {
@@ -30,18 +36,20 @@
                     long returnStateAndPos = workAroundHotSpotHugeMethodLimit(
                             state, c, pos, buf, reconsume, returnState, endPos);
                     pos = (int)returnStateAndPos; // 5.1.3 in the Java spec
-                    returnState = (int)(returnStateAndPos >> 32);
+                    returnState = (int)(returnStateAndPos >> 33);
                     state = stateSave;
-                    if (pos == endPos) {
+                    if ( (pos == endPos) || ( (((int)(returnStateAndPos >> 32)) & 0x1) != 0) ) {
                         break stateloop;
                     }
                     continue stateloop;
                 // END HOTSPOT WORKAROUND
                 default:
-                    break stateloop;
+                    assert !reconsume : "Must not reconsume when returning from HotSpot workaround.";
+                    stateSave = state;
+                    return (((long)returnState) << 33) | pos;
             }
         }
         assert !reconsume : "Must not reconsume when returning from HotSpot workaround.";
         stateSave = state;
-        return (((long)returnState) << 32) | pos;
+        return (((long)returnState) << 33) | (1L << 32) | pos ;
     }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/HtmlAttributes.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/HtmlAttributes.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/HtmlAttributes.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/HtmlAttributes.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,29 +1,31 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2008-2011 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
-import nu.validator.htmlparser.annotation.Auto;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
 import nu.validator.htmlparser.annotation.IdType;
 import nu.validator.htmlparser.annotation.Local;
 import nu.validator.htmlparser.annotation.NsUri;
@@ -32,26 +34,19 @@ import nu.validator.htmlparser.annotatio
 import nu.validator.htmlparser.common.Interner;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
 /**
  * Be careful with this class. QName is the name in from HTML tokenization.
  * Otherwise, please refer to the interface doc.
- * 
+ *
  * @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
  * @author hsivonen
  */
 public final class HtmlAttributes implements Attributes {
 
-    // [NOCPP[
-
     private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
 
     private static final String[] EMPTY_STRINGS = new String[0];
 
-    // ]NOCPP]
-
     public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
             AttributeName.HTML);
 
@@ -59,11 +54,9 @@ public final class HtmlAttributes implem
 
     private int length;
 
-    private @Auto AttributeName[] names;
-
-    private @Auto String[] values; // XXX perhaps make this @NoLength?
+    private AttributeName[] names;
 
-    // [NOCPP[
+    private String[] values;
 
     private String idValue;
 
@@ -73,20 +66,16 @@ public final class HtmlAttributes implem
 
     private String[] xmlnsValues;
 
-    // ]NOCPP]
-
     public HtmlAttributes(int mode) {
         this.mode = mode;
         this.length = 0;
         /*
          * The length of 5 covers covers 98.3% of elements
-         * according to Hixie
+         * according to Hixie.
          */
         this.names = new AttributeName[5];
         this.values = new String[5];
 
-        // [NOCPP[
-
         this.idValue = null;
 
         this.xmlnsLength = 0;
@@ -95,30 +84,11 @@ public final class HtmlAttributes implem
 
         this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
 
-        // ]NOCPP]
-    }
-    /*
-    public HtmlAttributes(HtmlAttributes other) {
-        this.mode = other.mode;
-        this.length = other.length;
-        this.names = new AttributeName[other.length];
-        this.values = new String[other.length];
-        // [NOCPP[
-        this.idValue = other.idValue;
-        this.xmlnsLength = other.xmlnsLength;
-        this.xmlnsNames = new AttributeName[other.xmlnsLength];
-        this.xmlnsValues = new String[other.xmlnsLength];
-        // ]NOCPP]
     }
-    */
 
-    void destructor() {
-        clear(0);
-    }
-    
     /**
      * Only use with a static argument
-     * 
+     *
      * @param name
      * @return
      */
@@ -131,8 +101,87 @@ public final class HtmlAttributes implem
         return -1;
     }
 
-    // [NOCPP[
-    
+    /**
+     * Only use with static argument.
+     *
+     * @see org.xml.sax.Attributes#getValue(java.lang.String)
+     */
+    public String getValue(AttributeName name) {
+        int index = getIndex(name);
+        if (index == -1) {
+            return null;
+        } else {
+            return getValueNoBoundsCheck(index);
+        }
+    }
+
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Variant of <code>getLocalName(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the local name at index
+     */
+    public @Local String getLocalNameNoBoundsCheck(int index) {
+        return names[index].getLocal(mode);
+    }
+
+    /**
+     * Variant of <code>getURI(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the namespace URI at index
+     */
+    public @NsUri String getURINoBoundsCheck(int index) {
+        return names[index].getUri(mode);
+    }
+
+    /**
+     * Variant of <code>getPrefix(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the namespace prefix at index
+     */
+    public @Prefix String getPrefixNoBoundsCheck(int index) {
+        return names[index].getPrefix(mode);
+    }
+
+    /**
+     * Variant of <code>getValue(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the attribute value at index
+     */
+    public String getValueNoBoundsCheck(int index) {
+        return values[index];
+    }
+
+    /**
+     * Variant of <code>getAttributeName(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the attribute name at index
+     */
+    public AttributeName getAttributeNameNoBoundsCheck(int index) {
+        return names[index];
+    }
+
+    /**
+     * Variant of <code>getQName(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the QName at index
+     */
+    public @QName String getQNameNoBoundsCheck(int index) {
+        return names[index].getQName(mode);
+    }
+
+    /**
+     * Variant of <code>getType(int index)</code> without bounds check.
+     * @param index a valid attribute index
+     * @return the attribute type at index
+     */
+    public @IdType String getTypeNoBoundsCheck(int index) {
+        return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
+    }
+
     public int getIndex(String qName) {
         for (int i = 0; i < length; i++) {
             if (names[i].getQName(mode).equals(qName)) {
@@ -141,7 +190,7 @@ public final class HtmlAttributes implem
         }
         return -1;
     }
-    
+
     public int getIndex(String uri, String localName) {
         for (int i = 0; i < length; i++) {
             if (names[i].getLocal(mode).equals(localName)
@@ -169,7 +218,7 @@ public final class HtmlAttributes implem
             return getType(index);
         }
     }
-    
+
     public String getValue(String qName) {
         int index = getIndex(qName);
         if (index == -1) {
@@ -187,12 +236,6 @@ public final class HtmlAttributes implem
             return getValue(index);
         }
     }
-    
-    // ]NOCPP]
-    
-    public int getLength() {
-        return length;
-    }
 
     public @Local String getLocalName(int index) {
         if (index < length && index >= 0) {
@@ -202,8 +245,6 @@ public final class HtmlAttributes implem
         }
     }
 
-    // [NOCPP[
-    
     public @QName String getQName(int index) {
         if (index < length && index >= 0) {
             return names[index].getQName(mode);
@@ -220,8 +261,6 @@ public final class HtmlAttributes implem
         }
     }
 
-    // ]NOCPP]
-    
     public AttributeName getAttributeName(int index) {
         if (index < length && index >= 0) {
             return names[index];
@@ -254,22 +293,6 @@ public final class HtmlAttributes implem
         }
     }
 
-    /**
-     * Only use with static argument.
-     * 
-     * @see org.xml.sax.Attributes#getValue(java.lang.String)
-     */
-    public String getValue(AttributeName name) {
-        int index = getIndex(name);
-        if (index == -1) {
-            return null;
-        } else {
-            return getValue(index);
-        }
-    }
-    
-    // [NOCPP[
-
     public String getId() {
         return idValue;
     }
@@ -301,7 +324,7 @@ public final class HtmlAttributes implem
             return null;
         }
     }
-    
+
     public int getXmlnsIndex(AttributeName name) {
         for (int i = 0; i < xmlnsLength; i++) {
             if (xmlnsNames[i] == name) {
@@ -310,7 +333,7 @@ public final class HtmlAttributes implem
         }
         return -1;
     }
-    
+
     public String getXmlnsValue(AttributeName name) {
         int index = getXmlnsIndex(name);
         if (index == -1) {
@@ -319,7 +342,7 @@ public final class HtmlAttributes implem
             return getXmlnsValue(index);
         }
     }
-    
+
     public AttributeName getXmlnsAttributeName(int index) {
         if (index < xmlnsLength && index >= 0) {
             return xmlnsNames[index];
@@ -328,14 +351,9 @@ public final class HtmlAttributes implem
         }
     }
 
-    // ]NOCPP]
-
     void addAttribute(AttributeName name, String value
-            // [NOCPP[
             , XmlViolationPolicy xmlnsPolicy
-    // ]NOCPP]        
     ) throws SAXException {
-        // [NOCPP[
         if (name == AttributeName.ID) {
             idValue = value;
         }
@@ -364,8 +382,6 @@ public final class HtmlAttributes implem
             }
         }
 
-        // ]NOCPP]
-
         if (names.length == length) {
             int newLen = length << 1; // The first growth covers virtually
             // 100% of elements according to
@@ -384,41 +400,17 @@ public final class HtmlAttributes implem
 
     void clear(int m) {
         for (int i = 0; i < length; i++) {
-            names[i].release();
             names[i] = null;
-            Portability.releaseString(values[i]);
             values[i] = null;
         }
         length = 0;
         mode = m;
-        // [NOCPP[
         idValue = null;
         for (int i = 0; i < xmlnsLength; i++) {
             xmlnsNames[i] = null;
             xmlnsValues[i] = null;
         }
         xmlnsLength = 0;
-        // ]NOCPP]
-    }
-    
-    /**
-     * This is used in C++ to release special <code>isindex</code>
-     * attribute values whose ownership is not transferred.
-     */
-    void releaseValue(int i) {
-        Portability.releaseString(values[i]);        
-    }
-    
-    /**
-     * This is only used for <code>AttributeName</code> ownership transfer
-     * in the isindex case to avoid freeing custom names twice in C++.
-     */
-    void clearWithoutReleasingContents() {
-        for (int i = 0; i < length; i++) {
-            names[i] = null;
-            values[i] = null;
-        }
-        length = 0;
     }
 
     boolean contains(AttributeName name) {
@@ -427,13 +419,11 @@ public final class HtmlAttributes implem
                 return true;
             }
         }
-        // [NOCPP[
         for (int i = 0; i < xmlnsLength; i++) {
             if (name.equalsAnother(xmlnsNames[i])) {
                 return true;
             }
         }
-        // ]NOCPP]
         return false;
     }
 
@@ -445,25 +435,25 @@ public final class HtmlAttributes implem
         mode = AttributeName.SVG;
     }
 
-    public HtmlAttributes cloneAttributes(Interner interner) throws SAXException {
-        assert (length == 0 && xmlnsLength == 0) || mode == 0 || mode == 3;
+    public HtmlAttributes cloneAttributes() throws SAXException {
+        assert (length == 0
+                && xmlnsLength == 0
+                )
+                || mode == 0 || mode == 3;
         HtmlAttributes clone = new HtmlAttributes(0);
         for (int i = 0; i < length; i++) {
-            clone.addAttribute(names[i].cloneAttributeName(interner), Portability.newStringFromString(values[i])
-            // [NOCPP[
-                   , XmlViolationPolicy.ALLOW
-            // ]NOCPP]
+            clone.addAttribute(names[i],
+                    values[i]
+                    , XmlViolationPolicy.ALLOW
             );
         }
-        // [NOCPP[
         for (int i = 0; i < xmlnsLength; i++) {
-            clone.addAttribute(xmlnsNames[i],
-                    xmlnsValues[i], XmlViolationPolicy.ALLOW);
+            clone.addAttribute(xmlnsNames[i], xmlnsValues[i],
+                    XmlViolationPolicy.ALLOW);
         }
-        // ]NOCPP]
         return clone; // XXX!!!
     }
-    
+
     public boolean equalsAnother(HtmlAttributes other) {
         assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content.";
         int otherLength = other.getLength();
@@ -479,9 +469,10 @@ public final class HtmlAttributes implem
             for (int j = 0; j < otherLength; j++) {
                 if (ownLocal == other.names[j].getLocal(AttributeName.HTML)) {
                     found = true;
-                    if (!Portability.stringEqualsString(values[i], other.values[j])) {
+                    if (!values[i].equals(other.values[j])) {
                         return false;
                     }
+                    break;
                 }
             }
             if (!found) {
@@ -490,9 +481,7 @@ public final class HtmlAttributes implem
         }
         return true;
     }
-    
-    // [NOCPP[
-    
+
     void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
         for (int i = 0; i < length; i++) {
             AttributeName attName = names[i];
@@ -514,18 +503,14 @@ public final class HtmlAttributes implem
             }
         }
     }
-    
+
     public void merge(HtmlAttributes attributes) throws SAXException {
         int len = attributes.getLength();
         for (int i = 0; i < len; i++) {
-            AttributeName name = attributes.getAttributeName(i);
+            AttributeName name = attributes.getAttributeNameNoBoundsCheck(i);
             if (!contains(name)) {
-                addAttribute(name, attributes.getValue(i), XmlViolationPolicy.ALLOW);
+                addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW);
             }
         }
     }
-
-
-    // ]NOCPP]
-    
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/LocatorImpl.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/LocatorImpl.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/LocatorImpl.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/LocatorImpl.java	2025-09-16 08:29:41.000000000 +0000
@@ -24,22 +24,38 @@
 package nu.validator.htmlparser.impl;
 
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 
-public class LocatorImpl implements Locator {
+public class LocatorImpl implements Locator, Locator2 {
 
     private final String systemId;
 
     private final String publicId;
 
+    private final String encoding;
+
     private final int column;
 
     private final int line;
 
+    /**
+     * Create a new Locator with default values
+     */
+    public LocatorImpl() {
+        this.systemId = this.publicId = this.encoding = null;
+        this.column = this.line = 0;
+    }
+
     public LocatorImpl(Locator locator) {
         this.systemId = locator.getSystemId();
         this.publicId = locator.getPublicId();
         this.column = locator.getColumnNumber();
         this.line = locator.getLineNumber();
+        if (locator instanceof Locator2) {
+            this.encoding = ((Locator2)locator).getEncoding();
+        } else {
+            this.encoding = null;
+        }
     }
 
     public final int getColumnNumber() {
@@ -57,4 +73,12 @@ public class LocatorImpl implements Loca
     public final String getSystemId() {
         return systemId;
     }
+
+    public final String getXMLVersion() {
+        return "1.0";
+    }
+
+    public final String getEncoding() {
+        return encoding;
+    }
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/MetaScanner.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/MetaScanner.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/MetaScanner.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/MetaScanner.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2008-2010 Mozilla Foundation
+ * Copyright (c) 2008-2015 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
@@ -25,44 +25,46 @@ package nu.validator.htmlparser.impl;
 
 import java.io.IOException;
 
+import org.xml.sax.SAXException;
+
 import nu.validator.htmlparser.annotation.Auto;
 import nu.validator.htmlparser.annotation.Inline;
 import nu.validator.htmlparser.common.ByteReadable;
 
-import org.xml.sax.SAXException;
-
 public abstract class MetaScanner {
 
     /**
      * Constant for "charset".
      */
-    private static final char[] CHARSET = "harset".toCharArray();
-    
+    private static final char[] CHARSET = { 'h', 'a', 'r', 's', 'e', 't' };
+
     /**
      * Constant for "content".
      */
-    private static final char[] CONTENT = "ontent".toCharArray();
+    private static final char[] CONTENT = { 'o', 'n', 't', 'e', 'n', 't' };
 
     /**
      * Constant for "http-equiv".
      */
-    private static final char[] HTTP_EQUIV = "ttp-equiv".toCharArray();
+    private static final char[] HTTP_EQUIV = { 't', 't', 'p', '-', 'e', 'q',
+            'u', 'i', 'v' };
 
     /**
      * Constant for "content-type".
      */
-    private static final char[] CONTENT_TYPE = "content-type".toCharArray();
+    private static final char[] CONTENT_TYPE = { 'c', 'o', 'n', 't', 'e', 'n',
+            't', '-', 't', 'y', 'p', 'e' };
 
     private static final int NO = 0;
 
     private static final int M = 1;
-    
+
     private static final int E = 2;
-    
+
     private static final int T = 3;
 
     private static final int A = 4;
-    
+
     private static final int DATA = 0;
 
     private static final int TAG_OPEN = 1;
@@ -88,7 +90,7 @@ public abstract class MetaScanner {
     private static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
 
     private static final int MARKUP_DECLARATION_OPEN = 13;
-    
+
     private static final int MARKUP_DECLARATION_HYPHEN = 14;
 
     private static final int COMMENT_START = 15;
@@ -100,11 +102,11 @@ public abstract class MetaScanner {
     private static final int COMMENT_END_DASH = 18;
 
     private static final int COMMENT_END = 19;
-    
+
     private static final int SELF_CLOSING_START_TAG = 20;
-    
+
     private static final int HTTP_EQUIV_NOT_SEEN = 0;
-    
+
     private static final int HTTP_EQUIV_CONTENT_TYPE = 1;
 
     private static final int HTTP_EQUIV_OTHER = 2;
@@ -113,7 +115,7 @@ public abstract class MetaScanner {
      * The data source.
      */
     protected ByteReadable readable;
-    
+
     /**
      * The state of the state machine that recognizes the tag name "meta".
      */
@@ -123,7 +125,7 @@ public abstract class MetaScanner {
      * The current position in recognizing the attribute name "content".
      */
     private int contentIndex = Integer.MAX_VALUE;
-    
+
     /**
      * The current position in recognizing the attribute name "charset".
      */
@@ -153,14 +155,18 @@ public abstract class MetaScanner {
      * Accumulation buffer for attribute values.
      */
     private @Auto char[] strBuf;
-    
+
     private String content;
-    
+
     private String charset;
-    
+
     private int httpEquivState;
-    
-    public MetaScanner() {
+
+    // CPPONLY: private TreeBuilder treeBuilder;
+
+    public MetaScanner(
+        // CPPONLY: TreeBuilder tb
+    ) {
         this.readable = null;
         this.metaState = NO;
         this.contentIndex = Integer.MAX_VALUE;
@@ -173,18 +179,20 @@ public abstract class MetaScanner {
         this.content = null;
         this.charset = null;
         this.httpEquivState = HTTP_EQUIV_NOT_SEEN;
+        // CPPONLY: this.treeBuilder = tb;
+        // CPPONLY: this.mEncoding = null;
     }
-    
+
     @SuppressWarnings("unused") private void destructor() {
         Portability.releaseString(content);
         Portability.releaseString(charset);
     }
 
     // [NOCPP[
-    
+
     /**
      * Reads a byte from the data source.
-     * 
+     *
      * -1 means end.
      * @return
      * @throws IOException
@@ -224,7 +232,7 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case TAG_OPEN:
                     tagopenloop: for (;;) {
                         c = read();
@@ -236,7 +244,7 @@ public abstract class MetaScanner {
                                 metaState = M;
                                 state = MetaScanner.TAG_NAME;
                                 break tagopenloop;
-                                // continue stateloop;                                
+                                // continue stateloop;
                             case '!':
                                 state = MetaScanner.MARKUP_DECLARATION_OPEN;
                                 continue stateloop;
@@ -259,7 +267,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALL THROUGH DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case TAG_NAME:
                     tagnameloop: for (;;) {
                         c = read();
@@ -308,7 +316,7 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_ATTRIBUTE_NAME:
                     beforeattributenameloop: for (;;) {
                         if (reconsume) {
@@ -343,7 +351,7 @@ public abstract class MetaScanner {
                                 httpEquivIndex = Integer.MAX_VALUE;
                                 contentTypeIndex = Integer.MAX_VALUE;
                                 state = MetaScanner.ATTRIBUTE_NAME;
-                                break beforeattributenameloop;                                
+                                break beforeattributenameloop;
                             case 'h':
                             case 'H':
                                 contentIndex = Integer.MAX_VALUE;
@@ -351,7 +359,7 @@ public abstract class MetaScanner {
                                 httpEquivIndex = 0;
                                 contentTypeIndex = Integer.MAX_VALUE;
                                 state = MetaScanner.ATTRIBUTE_NAME;
-                                break beforeattributenameloop;                                
+                                break beforeattributenameloop;
                             default:
                                 contentIndex = Integer.MAX_VALUE;
                                 charsetIndex = Integer.MAX_VALUE;
@@ -362,7 +370,7 @@ public abstract class MetaScanner {
                             // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case ATTRIBUTE_NAME:
                     attributenameloop: for (;;) {
                         c = read();
@@ -409,12 +417,12 @@ public abstract class MetaScanner {
                                         ++httpEquivIndex;
                                     } else {
                                         httpEquivIndex = Integer.MAX_VALUE;
-                                    }                                    
+                                    }
                                 }
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_ATTRIBUTE_VALUE:
                     beforeattributevalueloop: for (;;) {
                         c = read();
@@ -445,7 +453,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
                     attributevaluedoublequotedloop: for (;;) {
                         if (reconsume) {
@@ -466,7 +474,7 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_ATTRIBUTE_VALUE_QUOTED:
                     afterattributevaluequotedloop: for (;;) {
                         c = read();
@@ -495,7 +503,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SELF_CLOSING_START_TAG:
                     c = read();
                     switch (c) {
@@ -512,7 +520,6 @@ public abstract class MetaScanner {
                             reconsume = true;
                             continue stateloop;
                     }
-                    // XXX reorder point
                 case ATTRIBUTE_VALUE_UNQUOTED:
                     for (;;) {
                         if (reconsume) {
@@ -543,7 +550,6 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // XXX reorder point
                 case AFTER_ATTRIBUTE_NAME:
                     for (;;) {
                         c = read();
@@ -578,13 +584,12 @@ public abstract class MetaScanner {
                                 state = MetaScanner.ATTRIBUTE_NAME;
                                 continue stateloop;
                             default:
-                                contentIndex = -1;
-                                charsetIndex = -1;
+                                contentIndex = Integer.MAX_VALUE;
+                                charsetIndex = Integer.MAX_VALUE;
                                 state = MetaScanner.ATTRIBUTE_NAME;
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
                 case MARKUP_DECLARATION_OPEN:
                     markupdeclarationopenloop: for (;;) {
                         c = read();
@@ -601,7 +606,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case MARKUP_DECLARATION_HYPHEN:
                     markupdeclarationhyphenloop: for (;;) {
                         c = read();
@@ -618,7 +623,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_START:
                     commentstartloop: for (;;) {
                         c = read();
@@ -637,7 +642,7 @@ public abstract class MetaScanner {
                             // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT:
                     commentloop: for (;;) {
                         c = read();
@@ -652,7 +657,7 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_END_DASH:
                     commentenddashloop: for (;;) {
                         c = read();
@@ -668,7 +673,7 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_END:
                     for (;;) {
                         c = read();
@@ -685,7 +690,6 @@ public abstract class MetaScanner {
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
                 case COMMENT_START_DASH:
                     c = read();
                     switch (c) {
@@ -701,7 +705,6 @@ public abstract class MetaScanner {
                             state = MetaScanner.COMMENT;
                             continue stateloop;
                     }
-                    // XXX reorder point
                 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
                     for (;;) {
                         if (reconsume) {
@@ -721,7 +724,6 @@ public abstract class MetaScanner {
                                 continue;
                         }
                     }
-                    // XXX reorder point
                 case SCAN_UNTIL_GT:
                     for (;;) {
                         if (reconsume) {
@@ -744,7 +746,7 @@ public abstract class MetaScanner {
         stateSave  = state;
     }
 
-    private void handleCharInAttributeValue(int c) {
+    private void handleCharInAttributeValue(int c) throws SAXException {
         if (metaState == A) {
             if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
                 addToBuffer(c);
@@ -768,10 +770,11 @@ public abstract class MetaScanner {
     /**
      * Adds a character to the accumulation buffer.
      * @param c the character to add
+     * @throws SAXException
      */
-    private void addToBuffer(int c) {
+    private void addToBuffer(int c) throws SAXException {
         if (strBufLen == strBuf.length) {
-            char[] newBuf = new char[strBuf.length + (strBuf.length << 1)];
+            char[] newBuf = new char[Portability.checkedAdd(strBuf.length, (strBuf.length << 1))];
             System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
             strBuf = newBuf;
         }
@@ -788,11 +791,15 @@ public abstract class MetaScanner {
             return;
         }
         if (contentIndex == CONTENT.length && content == null) {
-            content = Portability.newStringFromBuffer(strBuf, 0, strBufLen);
+            content = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+                 // CPPONLY: , treeBuilder, false
+            );
             return;
         }
         if (charsetIndex == CHARSET.length && charset == null) {
-            charset = Portability.newStringFromBuffer(strBuf, 0, strBufLen);            
+            charset = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+                 // CPPONLY: , treeBuilder, false
+            );
             return;
         }
         if (httpEquivIndex == HTTP_EQUIV.length
@@ -812,13 +819,15 @@ public abstract class MetaScanner {
         httpEquivState = HTTP_EQUIV_NOT_SEEN;
         return stop;
     }
-    
+
     private boolean handleTagInner() throws SAXException {
         if (charset != null && tryCharset(charset)) {
                 return true;
         }
         if (content != null && httpEquivState == HTTP_EQUIV_CONTENT_TYPE) {
-            String extract = TreeBuilder.extractCharsetFromContent(content);
+            String extract = TreeBuilder.extractCharsetFromContent(content
+                // CPPONLY: , treeBuilder
+            );
             if (extract == null) {
                 return false;
             }
@@ -831,11 +840,11 @@ public abstract class MetaScanner {
 
     /**
      * Tries to switch to an encoding.
-     * 
+     *
      * @param encoding
      * @return <code>true</code> if successful
      * @throws SAXException
      */
     protected abstract boolean tryCharset(String encoding) throws SAXException;
-    
+
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/Portability.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/Portability.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/Portability.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/Portability.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,27 +1,29 @@
 /*
- * Copyright (c) 2008-2009 Mozilla Foundation
+ * Copyright (c) 2008-2015 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.impl;
 
+import org.xml.sax.SAXException;
+
 import nu.validator.htmlparser.annotation.Literal;
 import nu.validator.htmlparser.annotation.Local;
 import nu.validator.htmlparser.annotation.NoLength;
@@ -29,17 +31,30 @@ import nu.validator.htmlparser.common.In
 
 public final class Portability {
 
+    public static int checkedAdd(int a, int b) throws SAXException {
+        // This can't be translated code, because in C++ signed integer overflow is UB, so the below code would be wrong.
+        assert a >= 0;
+        assert b >= 0;
+        int sum = a + b;
+        if (sum < a || sum < b) {
+            throw new SAXException("Integer overflow");
+        }
+        return sum;
+    }
+
     // Allocating methods
 
     /**
-     * Allocates a new local name object. In C++, the refcount must be set up in such a way that 
+     * Allocates a new local name object. In C++, the refcount must be set up in such a way that
      * calling <code>releaseLocal</code> on the return value balances the refcount set by this method.
      */
-    public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
-        return new String(buf, offset, length).intern();
+    public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int length, Interner interner) {
+        return new String(buf, 0, length).intern();
     }
 
-    public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length) {
+    public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length
+        // CPPONLY: , TreeBuilder treeBuilder, boolean maybeAtomize
+    ) {
         return new String(buf, offset, length);
     }
 
@@ -50,11 +65,11 @@ public final class Portability {
     public static String newStringFromLiteral(@Literal String literal) {
         return literal;
     }
-    
+
     public static String newStringFromString(String string) {
         return string;
     }
-    
+
     // XXX get rid of this
     public static char[] newCharArrayFromLocal(@Local String local) {
         return local.toCharArray();
@@ -63,25 +78,21 @@ public final class Portability {
     public static char[] newCharArrayFromString(String string) {
         return string.toCharArray();
     }
-    
-    public static @Local String newLocalFromLocal(@Local String local, Interner interner) {
-        return local;
-    }
-    
+
     // Deallocation methods
-    
+
     public static void releaseString(String str) {
         // No-op in Java
     }
-    
+
     // Comparison methods
-    
-    public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int offset, int length) {
+
+    public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int length) {
         if (local.length() != length) {
             return false;
         }
         for (int i = 0; i < length; i++) {
-            if (local.charAt(i) != buf[offset + i]) {
+            if (local.charAt(i) != buf[i]) {
                 return false;
             }
         }
@@ -108,7 +119,7 @@ public final class Portability {
         }
         return true;
     }
-    
+
     public static boolean lowerCaseLiteralEqualsIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
             String string) {
         if (string == null) {
@@ -129,7 +140,7 @@ public final class Portability {
         }
         return true;
     }
-    
+
     public static boolean literalEqualsString(@Literal String literal, String string) {
         return literal.equals(string);
     }
@@ -137,12 +148,12 @@ public final class Portability {
     public static boolean stringEqualsString(String one, String other) {
         return one.equals(other);
     }
-    
+
     public static void delete(Object o) {
-        
+
     }
 
     public static void deleteArray(Object o) {
-        
+
     }
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/StackNode.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/StackNode.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/StackNode.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/StackNode.java	2025-09-16 08:29:41.000000000 +0000
@@ -2,22 +2,22 @@
  * Copyright (c) 2007 Henri Sivonen
  * Copyright (c) 2007-2011 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
@@ -28,25 +28,35 @@ import nu.validator.htmlparser.annotatio
 import nu.validator.htmlparser.annotation.NsUri;
 
 final class StackNode<T> {
-    final int flags;
+    // Index where this stack node is stored in the tree builder's list of stack nodes.
+    // A value of -1 indicates that the stack node is not owned by a tree builder and
+    // must delete itself when its refcount reaches 0.
+    final int idxInTreeBuilder;
 
-    final @Local String name;
+    int flags;
 
-    final @Local String popName;
+    @Local String name;
 
-    final @NsUri String ns;
+    @Local String popName;
 
-    final T node;
+    @NsUri String ns;
+
+    T node;
 
     // Only used on the list of formatting elements
     HtmlAttributes attributes;
 
-    private int refcount = 1;
+    private int refcount = 0;
+
+    /*
+     *  Only valid for formatting elements
+     */
+    // CPPONLY: private @HtmlCreator Object htmlCreator;
 
     // [NOCPP[
 
-    private final TaintableLocatorImpl locator;
-    
+    private TaintableLocatorImpl locator;
+
     public TaintableLocatorImpl getLocator() {
         return locator;
     }
@@ -78,18 +88,34 @@ final class StackNode<T> {
     }
 
     // [NOCPP[
-    
+
     public boolean isOptionalEndTag() {
         return (flags & ElementName.OPTIONAL_END_TAG) != 0;
     }
-    
+
     // ]NOCPP]
 
+    StackNode(int idxInTreeBuilder) {
+        this.idxInTreeBuilder = idxInTreeBuilder;
+        this.flags = 0;
+        this.name = null;
+        this.popName = null;
+        // CPPONLY: this.ns = 0;
+        this.node = null;
+        this.attributes = null;
+        this.refcount = 0;
+        // CPPONLY: this.htmlCreator = null;
+    }
+
+    // CPPONLY: public @HtmlCreator Object getHtmlCreator() {
+    // CPPONLY:     return htmlCreator;
+    // CPPONLY: }
+
     /**
-     * Constructor for copying. This doesn't take another <code>StackNode</code>
-     * because in C++ the caller is reponsible for reobtaining the local names
+     * Setter for copying. This doesn't take another <code>StackNode</code>
+     * because in C++ the caller is responsible for reobtaining the local names
      * from another interner.
-     * 
+     *
      * @param flags
      * @param ns
      * @param name
@@ -97,12 +123,14 @@ final class StackNode<T> {
      * @param popName
      * @param attributes
      */
-    StackNode(int flags, @NsUri String ns, @Local String name, T node,
-            @Local String popName, HtmlAttributes attributes
+    void setValues(int flags, @NsUri String ns, @Local String name, T node,
+            @Local String popName, HtmlAttributes attributes,
+            // CPPONLY: @HtmlCreator Object htmlCreator
             // [NOCPP[
-            , TaintableLocatorImpl locator
-    // ]NOCPP]
+            TaintableLocatorImpl locator
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = flags;
         this.name = name;
         this.popName = popName;
@@ -110,6 +138,10 @@ final class StackNode<T> {
         this.node = node;
         this.attributes = attributes;
         this.refcount = 1;
+        /*
+         * Need to track creator for formatting elements when copying.
+         */
+        // CPPONLY: this.htmlCreator = htmlCreator;
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
@@ -117,126 +149,152 @@ final class StackNode<T> {
 
     /**
      * Short hand for well-known HTML elements.
-     * 
+     *
      * @param elementName
      * @param node
      */
-    StackNode(ElementName elementName, T node
-    // [NOCPP[
+    void setValues(ElementName elementName, T node
+            // [NOCPP[
             , TaintableLocatorImpl locator
-    // ]NOCPP]
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = elementName.getFlags();
-        this.name = elementName.name;
-        this.popName = elementName.name;
+        this.name = elementName.getName();
+        this.popName = elementName.getName();
         this.ns = "http://www.w3.org/1999/xhtml";
         this.node = node;
         this.attributes = null;
         this.refcount = 1;
-        assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
+        assert elementName.isInterned() : "Don't use this constructor for custom elements.";
+        /*
+         * Not used for formatting elements, so no need to track creator.
+         */
+        // CPPONLY: this.htmlCreator = null;
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
     }
 
     /**
-     * Constructor for HTML formatting elements.
-     * 
+     * Setter for HTML formatting elements.
+     *
      * @param elementName
      * @param node
      * @param attributes
      */
-    StackNode(ElementName elementName, T node, HtmlAttributes attributes
-    // [NOCPP[
+    void setValues(ElementName elementName, T node, HtmlAttributes attributes
+            // [NOCPP[
             , TaintableLocatorImpl locator
-    // ]NOCPP]
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = elementName.getFlags();
-        this.name = elementName.name;
-        this.popName = elementName.name;
+        this.name = elementName.getName();
+        this.popName = elementName.getName();
         this.ns = "http://www.w3.org/1999/xhtml";
         this.node = node;
         this.attributes = attributes;
         this.refcount = 1;
-        assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
+        assert elementName.isInterned() : "Don't use this constructor for custom elements.";
+        /*
+         * Need to track creator for formatting elements in order to be able
+         * to clone them.
+         */
+        // CPPONLY: this.htmlCreator = elementName.getHtmlCreator();
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
     }
 
     /**
-     * The common-case HTML constructor.
-     * 
+     * The common-case HTML setter.
+     *
      * @param elementName
      * @param node
      * @param popName
      */
-    StackNode(ElementName elementName, T node, @Local String popName
-    // [NOCPP[
+    void setValues(ElementName elementName, T node, @Local String popName
+            // [NOCPP[
             , TaintableLocatorImpl locator
-    // ]NOCPP]
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = elementName.getFlags();
-        this.name = elementName.name;
+        this.name = elementName.getName();
         this.popName = popName;
         this.ns = "http://www.w3.org/1999/xhtml";
         this.node = node;
         this.attributes = null;
         this.refcount = 1;
+        /*
+         * Not used for formatting elements, so no need to track creator.
+         */
+        // CPPONLY: this.htmlCreator = null;
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
     }
 
     /**
-     * Constructor for SVG elements. Note that the order of the arguments is
-     * what distinguishes this from the HTML constructor. This is ugly, but
+     * Setter for SVG elements. Note that the order of the arguments is
+     * what distinguishes this from the HTML setter. This is ugly, but
      * AFAICT the least disruptive way to make this work with Java's generics
      * and without unnecessary branches. :-(
-     * 
+     *
      * @param elementName
      * @param popName
      * @param node
      */
-    StackNode(ElementName elementName, @Local String popName, T node
-    // [NOCPP[
+    void setValues(ElementName elementName, @Local String popName, T node
+            // [NOCPP[
             , TaintableLocatorImpl locator
-    // ]NOCPP]
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = prepareSvgFlags(elementName.getFlags());
-        this.name = elementName.name;
+        this.name = elementName.getName();
         this.popName = popName;
         this.ns = "http://www.w3.org/2000/svg";
         this.node = node;
         this.attributes = null;
         this.refcount = 1;
+        /*
+         * Not used for formatting elements, so no need to track creator.
+         */
+        // CPPONLY: this.htmlCreator = null;
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
     }
 
     /**
-     * Constructor for MathML.
-     * 
+     * Setter for MathML.
+     *
      * @param elementName
      * @param node
      * @param popName
      * @param markAsIntegrationPoint
      */
-    StackNode(ElementName elementName, T node, @Local String popName,
+    void setValues(ElementName elementName, T node, @Local String popName,
             boolean markAsIntegrationPoint
             // [NOCPP[
             , TaintableLocatorImpl locator
-    // ]NOCPP]
+            // ]NOCPP]
     ) {
+        assert isUnused();
         this.flags = prepareMathFlags(elementName.getFlags(),
                 markAsIntegrationPoint);
-        this.name = elementName.name;
+        this.name = elementName.getName();
         this.popName = popName;
         this.ns = "http://www.w3.org/1998/Math/MathML";
         this.node = node;
         this.attributes = null;
         this.refcount = 1;
+        /*
+         * Not used for formatting elements, so no need to track creator.
+         */
+        // CPPONLY: this.htmlCreator = null;
         // [NOCPP[
         this.locator = locator;
         // ]NOCPP]
@@ -265,7 +323,7 @@ final class StackNode<T> {
     }
 
     @SuppressWarnings("unused") private void destructor() {
-        Portability.delete(attributes);
+        // The translator adds refcount debug code here.
     }
 
     public void dropAttributes() {
@@ -286,10 +344,21 @@ final class StackNode<T> {
         refcount++;
     }
 
-    public void release() {
+    public void release(TreeBuilder<T> owningTreeBuilder) {
         refcount--;
+        assert refcount >= 0;
         if (refcount == 0) {
-            Portability.delete(this);
+            Portability.delete(attributes);
+            if (idxInTreeBuilder >= 0) {
+                owningTreeBuilder.notifyUnusedStackNode(idxInTreeBuilder);
+            } else {
+                assert owningTreeBuilder == null;
+                Portability.delete(this);
+            }
         }
     }
+
+    boolean isUnused() {
+        return refcount == 0;
+    }
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/StateSnapshot.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/StateSnapshot.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/StateSnapshot.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/StateSnapshot.java	2025-09-16 08:29:41.000000000 +0000
@@ -31,12 +31,12 @@ public class StateSnapshot<T> implements
 
     private final @Auto StackNode<T>[] listOfActiveFormattingElements;
 
+    private final @Auto int[] templateModeStack;
+
     private final T formPointer;
 
     private final T headPointer;
 
-    private final T deepTreeSurrogateParent;
-
     private final int mode;
 
     private final int originalMode;
@@ -50,20 +50,25 @@ public class StateSnapshot<T> implements
     /**
      * @param stack
      * @param listOfActiveFormattingElements
+     * @param templateModeStack
      * @param formPointer
-     * @param quirks 
-     * @param needToDropLF 
-     * @param foreignFlag 
-     * @param originalMode 
-     * @param mode 
+     * @param headPointer
+     * @param deepTreeSurrogateParent
+     * @param mode
+     * @param originalMode
+     * @param framesetOk
+     * @param needToDropLF
+     * @param quirks
      */
     StateSnapshot(StackNode<T>[] stack,
-            StackNode<T>[] listOfActiveFormattingElements, T formPointer, T headPointer, T deepTreeSurrogateParent, int mode, int originalMode, boolean framesetOk, boolean needToDropLF, boolean quirks) {
+            StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
+            T headPointer, int mode, int originalMode,
+            boolean framesetOk, boolean needToDropLF, boolean quirks) {
         this.stack = stack;
         this.listOfActiveFormattingElements = listOfActiveFormattingElements;
+        this.templateModeStack = templateModeStack;
         this.formPointer = formPointer;
         this.headPointer = headPointer;
-        this.deepTreeSurrogateParent = deepTreeSurrogateParent;
         this.mode = mode;
         this.originalMode = originalMode;
         this.framesetOk = framesetOk;
@@ -74,13 +79,23 @@ public class StateSnapshot<T> implements
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
      */
+    @Override
     public StackNode<T>[] getStack() {
         return stack;
     }
 
     /**
+     * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
+     */
+    @Override
+    public int[] getTemplateModeStack() {
+        return templateModeStack;
+    }
+
+    /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
      */
+    @Override
     public StackNode<T>[] getListOfActiveFormattingElements() {
         return listOfActiveFormattingElements;
     }
@@ -88,6 +103,7 @@ public class StateSnapshot<T> implements
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
      */
+    @Override
     public T getFormPointer() {
         return formPointer;
     }
@@ -97,24 +113,17 @@ public class StateSnapshot<T> implements
      * 
      * @return the headPointer
      */
+    @Override
     public T getHeadPointer() {
         return headPointer;
     }
 
     /**
-     * Returns the deepTreeSurrogateParent.
-     * 
-     * @return the deepTreeSurrogateParent
-     */
-    public T getDeepTreeSurrogateParent() {
-        return deepTreeSurrogateParent;
-    }
-    
-    /**
      * Returns the mode.
      * 
      * @return the mode
      */
+    @Override
     public int getMode() {
         return mode;
     }
@@ -124,6 +133,7 @@ public class StateSnapshot<T> implements
      * 
      * @return the originalMode
      */
+    @Override
     public int getOriginalMode() {
         return originalMode;
     }
@@ -133,6 +143,7 @@ public class StateSnapshot<T> implements
      * 
      * @return the framesetOk
      */
+    @Override
     public boolean isFramesetOk() {
         return framesetOk;
     }
@@ -142,6 +153,7 @@ public class StateSnapshot<T> implements
      * 
      * @return the needToDropLF
      */
+    @Override
     public boolean isNeedToDropLF() {
         return needToDropLF;
     }
@@ -151,6 +163,7 @@ public class StateSnapshot<T> implements
      * 
      * @return the quirks
      */
+    @Override
     public boolean isQuirks() {
         return quirks;
     }
@@ -158,6 +171,7 @@ public class StateSnapshot<T> implements
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
      */
+    @Override
     public int getListOfActiveFormattingElementsLength() {
         return listOfActiveFormattingElements.length;
     }
@@ -165,17 +179,26 @@ public class StateSnapshot<T> implements
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
      */
+    @Override
     public int getStackLength() {
         return stack.length;
     }
 
+    /**
+     * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
+     */
+    @Override
+    public int getTemplateModeStackLength() {
+        return templateModeStack.length;
+    }
+
     @SuppressWarnings("unused") private void destructor() {
         for (int i = 0; i < stack.length; i++) {
-            stack[i].release();
+            stack[i].release(null);
         }
         for (int i = 0; i < listOfActiveFormattingElements.length; i++) {
             if (listOfActiveFormattingElements[i] != null) {
-                listOfActiveFormattingElements[i].release();                
+                listOfActiveFormattingElements[i].release(null);
             }
         }
     }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/Tokenizer.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/Tokenizer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/Tokenizer.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/Tokenizer.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,40 +1,48 @@
 /*
  * Copyright (c) 2005-2007 Henri Sivonen
- * Copyright (c) 2007-2010 Mozilla Foundation
- * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla 
+ * Copyright (c) 2007-2017 Mozilla Foundation
+ * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
  * Foundation, and Opera Software ASA.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 /*
- * The comments following this one that use the same comment syntax as this 
- * comment are quotes from the WHATWG HTML 5 spec as of 2 June 2007 
+ * The comments following this one that use the same comment syntax as this
+ * comment are quotes from the WHATWG HTML 5 spec as of 2 June 2007
  * amended as of June 18 2008 and May 31 2010.
  * That document came with this statement:
- * "© Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and 
- * Opera Software ASA. You are granted a license to use, reproduce and 
+ * "© Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce and
  * create derivative works of this document."
  */
 
 package nu.validator.htmlparser.impl;
 
+import java.util.HashMap;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
 import nu.validator.htmlparser.annotation.Auto;
 import nu.validator.htmlparser.annotation.CharacterName;
 import nu.validator.htmlparser.annotation.Const;
@@ -46,27 +54,22 @@ import nu.validator.htmlparser.common.In
 import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
 /**
  * An implementation of
- * http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
- * 
+ * https://html.spec.whatwg.org/multipage/syntax.html#tokenization
+ *
  * This class implements the <code>Locator</code> interface. This is not an
  * incidental implementation detail: Users of this class are encouraged to make
  * use of the <code>Locator</code> nature.
- * 
+ *
  * By default, the tokenizer may report data that XML 1.0 bans. The tokenizer
  * can be configured to treat these conditions as fatal or to coerce the infoset
  * to something that XML 1.0 allows.
- * 
+ *
  * @version $Id$
  * @author hsivonen
  */
-public class Tokenizer implements Locator {
+public class Tokenizer implements Locator, Locator2 {
 
     private static final int DATA_AND_RCDATA_MASK = ~1;
 
@@ -216,6 +219,18 @@ public class Tokenizer implements Locato
 
     public static final int SCRIPT_DATA_DOUBLE_ESCAPE_END = 72;
 
+    public static final int PROCESSING_INSTRUCTION = 73;
+
+    public static final int PROCESSING_INSTRUCTION_QUESTION_MARK = 74;
+
+    public static final int COMMENT_LESSTHAN = 76;
+
+    public static final int COMMENT_LESSTHAN_BANG = 77;
+
+    public static final int COMMENT_LESSTHAN_BANG_DASH = 78;
+
+    public static final int COMMENT_LESSTHAN_BANG_DASH_DASH = 79;
+
     /**
      * Magic value for UTF-16 operations.
      */
@@ -259,29 +274,26 @@ public class Tokenizer implements Locato
     private static final @NoLength char[] LF = { '\n' };
 
     /**
-     * Buffer growth parameter.
-     */
-    private static final int BUFFER_GROW_BY = 1024;
-
-    /**
      * "CDATA[" as <code>char[]</code>
      */
-    private static final @NoLength char[] CDATA_LSQB = "CDATA[".toCharArray();
+    private static final @NoLength char[] CDATA_LSQB = { 'C', 'D', 'A', 'T',
+            'A', '[' };
 
     /**
      * "octype" as <code>char[]</code>
      */
-    private static final @NoLength char[] OCTYPE = "octype".toCharArray();
+    private static final @NoLength char[] OCTYPE = { 'o', 'c', 't', 'y', 'p',
+            'e' };
 
     /**
      * "ublic" as <code>char[]</code>
      */
-    private static final @NoLength char[] UBLIC = "ublic".toCharArray();
+    private static final @NoLength char[] UBLIC = { 'u', 'b', 'l', 'i', 'c' };
 
     /**
      * "ystem" as <code>char[]</code>
      */
-    private static final @NoLength char[] YSTEM = "ystem".toCharArray();
+    private static final @NoLength char[] YSTEM = { 'y', 's', 't', 'e', 'm' };
 
     private static final char[] TITLE_ARR = { 't', 'i', 't', 'l', 'e' };
 
@@ -349,14 +361,14 @@ public class Tokenizer implements Locato
 
     private int candidate;
 
-    private int strBufMark;
-
-    private int prevValue;
+    private int charRefBufMark;
 
     protected int value;
 
     private boolean seenDigits;
 
+    private boolean suspendAfterCurrentNonTextToken;
+
     protected int cstart;
 
     /**
@@ -372,7 +384,8 @@ public class Tokenizer implements Locato
     private String systemId;
 
     /**
-     * Buffer for short identifiers.
+     * Buffer for bufferable things other than those that fit the description
+     * of <code>charRefBuf</code>.
      */
     private @Auto char[] strBuf;
 
@@ -382,25 +395,15 @@ public class Tokenizer implements Locato
     private int strBufLen;
 
     /**
-     * <code>-1</code> to indicate that <code>strBuf</code> is used or otherwise
-     * an offset to the main buffer.
-     */
-    // private int strBufOffset = -1;
-    /**
-     * Buffer for long strings.
+     * Buffer for characters that might form a character reference but may
+     * end up not forming one.
      */
-    private @Auto char[] longStrBuf;
+    private final @Auto char[] charRefBuf;
 
     /**
-     * Number of significant <code>char</code>s in <code>longStrBuf</code>.
+     * Number of significant <code>char</code>s in <code>charRefBuf</code>.
      */
-    private int longStrBufLen;
-
-    /**
-     * <code>-1</code> to indicate that <code>longStrBuf</code> is used or
-     * otherwise an offset to the main buffer.
-     */
-    // private int longStrBufOffset = -1;
+    private int charRefBufLen;
 
     /**
      * Buffer for expanding NCRs falling into the Basic Multilingual Plane.
@@ -425,15 +428,31 @@ public class Tokenizer implements Locato
     protected boolean endTag;
 
     /**
-     * The current tag token name.
+     * <code>true</code> iff the current element/attribute name contains
+     * a hyphen.
+     */
+    private boolean containsHyphen;
+
+    /**
+     * The current tag token name. One of
+     * 1) null,
+     * 2) non-owning reference to nonInternedTagName
+     * 3) non-owning reference to a pre-interned ElementName
      */
     private ElementName tagName = null;
 
     /**
+     * The recycled ElementName instance for the non-pre-interned cases.
+     */
+    private ElementName nonInternedTagName = null;
+
+    /**
      * The current attribute name.
      */
     protected AttributeName attributeName = null;
 
+    // CPPONLY: private AttributeName nonInternedAttributeName = null;
+
     // [NOCPP[
 
     /**
@@ -442,12 +461,7 @@ public class Tokenizer implements Locato
     private boolean wantsComments = false;
 
     /**
-     * <code>true</code> when HTML4-specific additional errors are requested.
-     */
-    protected boolean html4;
-
-    /**
-     * Whether the stream is past the first 512 bytes.
+     * Whether the stream is past the first 1024 bytes.
      */
     private boolean metaBoundaryPassed;
 
@@ -489,22 +503,31 @@ public class Tokenizer implements Locato
 
     private XmlViolationPolicy namePolicy = XmlViolationPolicy.ALTER_INFOSET;
 
-    private boolean html4ModeCompatibleWithXhtml1Schemata;
-
-    private final boolean newAttributesEachTime;
+    private int mappingLangToXmlLang;
 
     // ]NOCPP]
 
-    private int mappingLangToXmlLang;
+    private final boolean newAttributesEachTime;
 
     private boolean shouldSuspend;
 
+    private boolean keepBuffer;
+
     protected boolean confident;
 
     private int line;
 
+    /*
+     * The line number of the current attribute. First set to the line of the
+     * attribute name and if there is a value, set to the line the value
+     * started on.
+     */
+    // CPPONLY: private int attributeLine;
+
     private Interner interner;
 
+    // CPPONLY: private boolean viewingXmlSource;
+
     // [NOCPP[
 
     protected LocatorImpl ampersandLocation;
@@ -512,39 +535,112 @@ public class Tokenizer implements Locato
     public Tokenizer(TokenHandler tokenHandler, boolean newAttributesEachTime) {
         this.tokenHandler = tokenHandler;
         this.encodingDeclarationHandler = null;
+        this.lastCR = false;
+        this.stateSave = 0;
+        this.returnStateSave = 0;
+        this.index = 0;
+        this.forceQuirks = false;
+        this.additional = '\u0000';
+        this.entCol = 0;
+        this.firstCharKey = 0;
+        this.lo = 0;
+        this.hi = 0;
+        this.candidate = 0;
+        this.charRefBufMark = 0;
+        this.value = 0;
+        this.seenDigits = false;
+        this.suspendAfterCurrentNonTextToken = false;
+        this.cstart = 0;
+        this.strBufLen = 0;
         this.newAttributesEachTime = newAttributesEachTime;
+        // &CounterClockwiseContourIntegral; is the longest valid char ref and
+        // the semicolon never gets appended to the buffer.
+        this.charRefBuf = new char[32];
+        this.charRefBufLen = 0;
         this.bmpChar = new char[1];
         this.astralChar = new char[2];
+        this.endTagExpectation = null;
+        this.endTagExpectationAsArray = null;
+        this.endTag = false;
+        this.containsHyphen = false;
         this.tagName = null;
+        this.nonInternedTagName = new ElementName();
         this.attributeName = null;
+        // CPPONLY: this.nonInternedAttributeName = new AttributeName();
         this.doctypeName = null;
         this.publicIdentifier = null;
         this.systemIdentifier = null;
         this.attributes = null;
+        this.shouldSuspend = false;
+        this.keepBuffer = false;
+        this.confident = false;
+        this.line = 0;
+        // CPPONLY: this.attributeLine = 0;
+        this.interner = null;
     }
 
     // ]NOCPP]
 
     /**
      * The constructor.
-     * 
+     *
      * @param tokenHandler
      *            the handler for receiving tokens
      */
-    public Tokenizer(TokenHandler tokenHandler) {
+    public Tokenizer(TokenHandler tokenHandler
+    // CPPONLY: , boolean viewingXmlSource
+    ) {
         this.tokenHandler = tokenHandler;
         this.encodingDeclarationHandler = null;
         // [NOCPP[
         this.newAttributesEachTime = false;
         // ]NOCPP]
+        this.lastCR = false;
+        this.stateSave = 0;
+        this.returnStateSave = 0;
+        this.index = 0;
+        this.forceQuirks = false;
+        this.additional = '\u0000';
+        this.entCol = 0;
+        this.firstCharKey = 0;
+        this.lo = 0;
+        this.hi = 0;
+        this.candidate = 0;
+        this.charRefBufMark = 0;
+        this.value = 0;
+        this.seenDigits = false;
+        this.suspendAfterCurrentNonTextToken = false;
+        this.cstart = 0;
+        this.strBufLen = 0;
+        // &CounterClockwiseContourIntegral; is the longest valid char ref and
+        // the semicolon never gets appended to the buffer.
+        this.charRefBuf = new char[32];
+        this.charRefBufLen = 0;
         this.bmpChar = new char[1];
         this.astralChar = new char[2];
+        this.endTagExpectation = null;
+        this.endTagExpectationAsArray = null;
+        this.endTag = false;
+        this.containsHyphen = false;
         this.tagName = null;
+        this.nonInternedTagName = new ElementName();
         this.attributeName = null;
+        // CPPONLY: this.nonInternedAttributeName = new AttributeName();
         this.doctypeName = null;
         this.publicIdentifier = null;
         this.systemIdentifier = null;
+        // [NOCPP[
         this.attributes = null;
+        // ]NOCPP]
+        // CPPONLY: this.attributes = tokenHandler.HasBuilder() ? new HtmlAttributes(mappingLangToXmlLang) : null;
+        // CPPONLY: this.newAttributesEachTime = !tokenHandler.HasBuilder();
+        this.shouldSuspend = false;
+        this.keepBuffer = false;
+        this.confident = false;
+        this.line = 0;
+        // CPPONLY: this.attributeLine = 0;
+        this.interner = null;
+        // CPPONLY: this.viewingXmlSource = viewingXmlSource;
     }
 
     public void setInterner(Interner interner) {
@@ -557,11 +653,27 @@ public class Tokenizer implements Locato
 
     }
 
+    // CPPONLY: boolean isViewingXmlSource() {
+    // CPPONLY: return viewingXmlSource;
+    // CPPONLY: }
+
+    public void setKeepBuffer(boolean keepBuffer) {
+        this.keepBuffer = keepBuffer;
+    }
+
+    public boolean dropBufferIfLongerThan(int length) {
+        if (strBuf.length > length) {
+            strBuf = null;
+            return true;
+        }
+        return false;
+    }
+
     // [NOCPP[
 
     /**
      * Returns the mappingLangToXmlLang.
-     * 
+     *
      * @return the mappingLangToXmlLang
      */
     public boolean isMappingLangToXmlLang() {
@@ -570,7 +682,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the mappingLangToXmlLang.
-     * 
+     *
      * @param mappingLangToXmlLang
      *            the mappingLangToXmlLang to set
      */
@@ -581,7 +693,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the error handler.
-     * 
+     *
      * @see org.xml.sax.XMLReader#setErrorHandler(org.xml.sax.ErrorHandler)
      */
     public void setErrorHandler(ErrorHandler eh) {
@@ -593,8 +705,17 @@ public class Tokenizer implements Locato
     }
 
     /**
+     * Gets the errorProfile.
+     *
+     * @param errorProfile
+     */
+    public HashMap getErrorProfile() {
+        return null;
+    }
+
+    /**
      * Sets the commentPolicy.
-     * 
+     *
      * @param commentPolicy
      *            the commentPolicy to set
      */
@@ -604,7 +725,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the contentNonXmlCharPolicy.
-     * 
+     *
      * @param contentNonXmlCharPolicy
      *            the contentNonXmlCharPolicy to set
      */
@@ -618,7 +739,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the contentSpacePolicy.
-     * 
+     *
      * @param contentSpacePolicy
      *            the contentSpacePolicy to set
      */
@@ -628,7 +749,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the xmlnsPolicy.
-     * 
+     *
      * @param xmlnsPolicy
      *            the xmlnsPolicy to set
      */
@@ -643,25 +764,31 @@ public class Tokenizer implements Locato
         this.namePolicy = namePolicy;
     }
 
-    /**
-     * Sets the html4ModeCompatibleWithXhtml1Schemata.
-     * 
-     * @param html4ModeCompatibleWithXhtml1Schemata
-     *            the html4ModeCompatibleWithXhtml1Schemata to set
-     */
-    public void setHtml4ModeCompatibleWithXhtml1Schemata(
-            boolean html4ModeCompatibleWithXhtml1Schemata) {
-        this.html4ModeCompatibleWithXhtml1Schemata = html4ModeCompatibleWithXhtml1Schemata;
-    }
-
     // ]NOCPP]
 
     // For the token handler to call
+
     /**
-     * Sets the tokenizer state and the associated element name. This should 
+     * Sets the tokenizer state and the associated element name. This should
      * only ever used to put the tokenizer into one of the states that have
      * a special end tag expectation.
-     * 
+     *
+     * @param specialTokenizerState
+     *            the tokenizer state to set
+     */
+    public void setState(int specialTokenizerState) {
+        this.stateSave = specialTokenizerState;
+        this.endTagExpectation = null;
+        this.endTagExpectationAsArray = null;
+    }
+
+    // [NOCPP[
+
+    /**
+     * Sets the tokenizer state and the associated element name. This should
+     * only ever used to put the tokenizer into one of the states that have
+     * a special end tag expectation. For use from the tokenizer test harness.
+     *
      * @param specialTokenizerState
      *            the tokenizer state to set
      * @param endTagExpectation
@@ -674,16 +801,19 @@ public class Tokenizer implements Locato
             return;
         }
         @Auto char[] asArray = Portability.newCharArrayFromLocal(endTagExpectation);
-        this.endTagExpectation = ElementName.elementNameByBuffer(asArray, 0,
-                asArray.length, interner);
+        this.endTagExpectation = ElementName.elementNameByBuffer(asArray,
+                asArray.length);
+        assert this.endTagExpectation != null;
         endTagExpectationToArray();
     }
 
+    // ]NOCPP]
+
     /**
-     * Sets the tokenizer state and the associated element name. This should 
+     * Sets the tokenizer state and the associated element name. This should
      * only ever used to put the tokenizer into one of the states that have
      * a special end tag expectation.
-     * 
+     *
      * @param specialTokenizerState
      *            the tokenizer state to set
      * @param endTagExpectation
@@ -738,6 +868,7 @@ public class Tokenizer implements Locato
      * For C++ use only.
      */
     public void setLineNumber(int line) {
+        // CPPONLY: this.attributeLine = line; // XXX is this needed?
         this.line = line;
     }
 
@@ -773,6 +904,24 @@ public class Tokenizer implements Locato
         return systemId;
     }
 
+    /**
+     * @see org.xml.sax.ext.Locator2#getXMLVersion()
+     */
+    public String getXMLVersion() {
+        return "1.0";
+    }
+
+    /**
+     * @see org.xml.sax.ext.Locator2#getXMLVersion()
+     */
+    public String getEncoding() {
+        try {
+            return encodingDeclarationHandler == null ? null : encodingDeclarationHandler.getCharacterEncoding();
+        } catch (SAXException e) {
+            return null;
+        }
+    }
+
     // end Locator impl
 
     // end public API
@@ -781,10 +930,6 @@ public class Tokenizer implements Locato
         metaBoundaryPassed = true;
     }
 
-    void turnOnAdditionalHtml4Errors() {
-        html4 = true;
-    }
-
     // ]NOCPP]
 
     HtmlAttributes emptyAttributes() {
@@ -799,100 +944,104 @@ public class Tokenizer implements Locato
         // ]NOCPP]
     }
 
-    @Inline private void clearStrBufAndAppend(char c) {
-        strBuf[0] = c;
-        strBufLen = 1;
+    @Inline private void appendCharRefBuf(char c) {
+        // CPPONLY: assert charRefBufLen < charRefBuf.length:
+        // CPPONLY:     "RELEASE: Attempted to overrun charRefBuf!";
+        charRefBuf[charRefBufLen++] = c;
     }
 
-    @Inline private void clearStrBuf() {
+    private void emitOrAppendCharRefBuf(int returnState) throws SAXException {
+        if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
+            appendCharRefBufToStrBuf();
+        } else {
+            if (charRefBufLen > 0) {
+                tokenHandler.characters(charRefBuf, 0, charRefBufLen);
+                charRefBufLen = 0;
+            }
+        }
+    }
+
+    @Inline private void clearStrBufAfterUse() {
+        strBufLen = 0;
+    }
+
+    @Inline private void clearStrBufBeforeUse() {
+        assert strBufLen == 0: "strBufLen not reset after previous use!";
+        strBufLen = 0; // no-op in the absence of bugs
+    }
+
+    @Inline private void clearStrBufAfterOneHyphen() {
+        assert strBufLen == 1: "strBufLen length not one!";
+        assert strBuf[0] == '-': "strBuf does not start with a hyphen!";
         strBufLen = 0;
     }
 
     /**
-     * Appends to the smaller buffer.
-     * 
+     * Appends to the buffer.
+     *
      * @param c
      *            the UTF-16 code unit to append
      */
-    private void appendStrBuf(char c) {
-        if (strBufLen == strBuf.length) {
-            char[] newBuf = new char[strBuf.length + Tokenizer.BUFFER_GROW_BY];
-            System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
-            strBuf = newBuf;
-        }
+    @Inline private void appendStrBuf(char c) {
+        // CPPONLY: assert strBufLen < strBuf.length: "Previous buffer length insufficient.";
+        // CPPONLY: if (strBufLen == strBuf.length) {
+        // CPPONLY:     if (!EnsureBufferSpace(1)) {
+        // CPPONLY:         assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+        // CPPONLY:     } // TODO: Add telemetry when outer if fires but inner does not
+        // CPPONLY: }
         strBuf[strBufLen++] = c;
     }
 
     /**
-     * The smaller buffer as a String. Currently only used for error reporting.
-     * 
+     * The buffer as a String. Currently only used for error reporting.
+     *
      * <p>
      * C++ memory note: The return value must be released.
-     * 
-     * @return the smaller buffer as a string
+     *
+     * @return the buffer as a string
      */
     protected String strBufToString() {
-        return Portability.newStringFromBuffer(strBuf, 0, strBufLen);
+        String str = Portability.newStringFromBuffer(strBuf, 0, strBufLen
+            // CPPONLY: , tokenHandler, !newAttributesEachTime && attributeName == AttributeName.CLASS
+        );
+        clearStrBufAfterUse();
+        return str;
     }
 
     /**
-     * Returns the short buffer as a local name. The return value is released in
+     * Returns the buffer as a local name. The return value is released in
      * emitDoctypeToken().
-     * 
-     * @return the smaller buffer as local name
+     *
+     * @return the buffer as local name
      */
     private void strBufToDoctypeName() {
-        doctypeName = Portability.newLocalNameFromBuffer(strBuf, 0, strBufLen,
-                interner);
+        doctypeName = Portability.newLocalNameFromBuffer(strBuf, strBufLen, interner);
+        clearStrBufAfterUse();
     }
 
     /**
-     * Emits the smaller buffer as character tokens.
-     * 
+     * Emits the buffer as character tokens.
+     *
      * @throws SAXException
      *             if the token handler threw
      */
     private void emitStrBuf() throws SAXException {
         if (strBufLen > 0) {
             tokenHandler.characters(strBuf, 0, strBufLen);
+            clearStrBufAfterUse();
         }
     }
 
-    @Inline private void clearLongStrBuf() {
-        longStrBufLen = 0;
-    }
-
-    @Inline private void clearLongStrBufAndAppend(char c) {
-        longStrBuf[0] = c;
-        longStrBufLen = 1;
-    }
-
-    /**
-     * Appends to the larger buffer.
-     * 
-     * @param c
-     *            the UTF-16 code unit to append
-     */
-    private void appendLongStrBuf(char c) {
-        if (longStrBufLen == longStrBuf.length) {
-            char[] newBuf = new char[longStrBufLen + (longStrBufLen >> 1)];
-            System.arraycopy(longStrBuf, 0, newBuf, 0, longStrBuf.length);
-            longStrBuf = newBuf;
-        }
-        longStrBuf[longStrBufLen++] = c;
-    }
-
     @Inline private void appendSecondHyphenToBogusComment() throws SAXException {
         // [NOCPP[
         switch (commentPolicy) {
             case ALTER_INFOSET:
-                // detachLongStrBuf();
-                appendLongStrBuf(' ');
-                // FALLTHROUGH
+                appendStrBuf(' ');
+                // CPPONLY: MOZ_FALLTHROUGH;
             case ALLOW:
                 warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
                 // ]NOCPP]
-                appendLongStrBuf('-');
+                appendStrBuf('-');
                 // [NOCPP[
                 break;
             case FATAL:
@@ -906,9 +1055,8 @@ public class Tokenizer implements Locato
     private void maybeAppendSpaceToBogusComment() throws SAXException {
         switch (commentPolicy) {
             case ALTER_INFOSET:
-                // detachLongStrBuf();
-                appendLongStrBuf(' ');
-                // FALLTHROUGH
+                appendStrBuf(' ');
+                // CPPONLY: MOZ_FALLTHROUGH;
             case ALLOW:
                 warn("The document is not mappable to XML 1.0 due to a trailing hyphen in a comment.");
                 break;
@@ -920,21 +1068,23 @@ public class Tokenizer implements Locato
 
     // ]NOCPP]
 
-    @Inline private void adjustDoubleHyphenAndAppendToLongStrBufAndErr(char c)
+    @Inline private void adjustDoubleHyphenAndAppendToStrBufAndErr(char c, boolean reportedConsecutiveHyphens)
             throws SAXException {
-        errConsecutiveHyphens();
         // [NOCPP[
         switch (commentPolicy) {
             case ALTER_INFOSET:
-                // detachLongStrBuf();
-                longStrBufLen--;
-                appendLongStrBuf(' ');
-                appendLongStrBuf('-');
-                // FALLTHROUGH
+                strBufLen--;
+                // WARNING!!! This expands the worst case of the buffer length
+                // given the length of input!
+                appendStrBuf(' ');
+                appendStrBuf('-');
+                // CPPONLY: MOZ_FALLTHROUGH;
             case ALLOW:
-                warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+                if (!reportedConsecutiveHyphens) {
+                    warn("The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.");
+                }
                 // ]NOCPP]
-                appendLongStrBuf(c);
+                appendStrBuf(c);
                 // [NOCPP[
                 break;
             case FATAL:
@@ -944,70 +1094,68 @@ public class Tokenizer implements Locato
         // ]NOCPP]
     }
 
-    private void appendLongStrBuf(@NoLength char[] buffer, int offset, int length) {
-        int reqLen = longStrBufLen + length;
-        if (longStrBuf.length < reqLen) {
-            char[] newBuf = new char[reqLen + (reqLen >> 1)];
-            System.arraycopy(longStrBuf, 0, newBuf, 0, longStrBuf.length);
-            longStrBuf = newBuf;
-        }
-        System.arraycopy(buffer, offset, longStrBuf, longStrBufLen, length);
-        longStrBufLen = reqLen;
+    private void appendStrBuf(@NoLength char[] buffer, int offset, int length) throws SAXException {
+        int newLen = Portability.checkedAdd(strBufLen, length);
+        // CPPONLY: assert newLen <= strBuf.length: "Previous buffer length insufficient.";
+        // CPPONLY: if (strBuf.length < newLen) {
+        // CPPONLY:     if (!EnsureBufferSpace(length)) {
+        // CPPONLY:         assert false: "RELEASE: Unable to recover from buffer reallocation failure";
+        // CPPONLY:     } // TODO: Add telemetry when outer if fires but inner does not
+        // CPPONLY: }
+        System.arraycopy(buffer, offset, strBuf, strBufLen, length);
+        strBufLen = newLen;
     }
 
     /**
-     * Append the contents of the smaller buffer to the larger one.
-     */
-    @Inline private void appendStrBufToLongStrBuf() {
-        appendLongStrBuf(strBuf, 0, strBufLen);
-    }
-
-    /**
-     * The larger buffer as a string.
-     * 
-     * <p>
-     * C++ memory note: The return value must be released.
-     * 
-     * @return the larger buffer as a string
-     */
-    private String longStrBufToString() {
-        return Portability.newStringFromBuffer(longStrBuf, 0, longStrBufLen);
+     * Append the contents of the char reference buffer to the main one.
+     */
+    @Inline private void appendCharRefBufToStrBuf() throws SAXException {
+        appendStrBuf(charRefBuf, 0, charRefBufLen);
+        charRefBufLen = 0;
     }
 
     /**
      * Emits the current comment token.
-     * 
+     *
+     * NOTE: The method may set <code>shouldSuspend</code>, so the caller
+     * must have this pattern after the state's <code>transition</code> call:
+     *
+     * <pre>
+     * if (shouldSuspend) {
+     *     break stateloop;
+     * }
+     * continue stateloop;
+     * </pre>
+     *
      * @param pos
      *            TODO
-     * 
+     *
      * @throws SAXException
      */
     private void emitComment(int provisionalHyphens, int pos)
             throws SAXException {
+        // CPPONLY: RememberGt(pos);
         // [NOCPP[
         if (wantsComments) {
             // ]NOCPP]
-            // if (longStrBufOffset != -1) {
-            // tokenHandler.comment(buf, longStrBufOffset, longStrBufLen
-            // - provisionalHyphens);
-            // } else {
-            tokenHandler.comment(longStrBuf, 0, longStrBufLen
+            tokenHandler.comment(strBuf, 0, strBufLen
                     - provisionalHyphens);
-            // }
             // [NOCPP[
         }
         // ]NOCPP]
+        clearStrBufAfterUse();
         cstart = pos + 1;
+        suspendIfRequestedAfterCurrentNonTextToken();
     }
 
     /**
      * Flushes coalesced character tokens.
-     * 
+     *
      * @param buf
      *            TODO
      * @param pos
      *            TODO
-     * 
+     *
      * @throws SAXException
      */
     protected void flushChars(@NoLength char[] buf, int pos)
@@ -1021,7 +1169,7 @@ public class Tokenizer implements Locato
     /**
      * Reports an condition that would make the infoset incompatible with XML
      * 1.0 as fatal.
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -1037,7 +1185,7 @@ public class Tokenizer implements Locato
 
     /**
      * Reports a Parse Error.
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -1068,7 +1216,7 @@ public class Tokenizer implements Locato
 
     /**
      * Reports a warning
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -1081,32 +1229,53 @@ public class Tokenizer implements Locato
         errorHandler.warning(spe);
     }
 
-    /**
-     * 
-     */
-    private void resetAttributes() {
-        // [NOCPP[
-        if (newAttributesEachTime) {
-            // ]NOCPP]
-            attributes = null;
-            // [NOCPP[
+    private void strBufToElementNameString() {
+        if (containsHyphen) {
+            // We've got a custom element or annotation-xml.
+            @Local String annotationName = ElementName.ANNOTATION_XML.getName();
+            if (Portability.localEqualsBuffer(annotationName, strBuf, strBufLen)) {
+                tagName = ElementName.ANNOTATION_XML;
+            } else {
+                nonInternedTagName.setNameForNonInterned(Portability.newLocalNameFromBuffer(strBuf, strBufLen,
+                        interner)
+                        // CPPONLY: , true
+                        );
+                tagName = nonInternedTagName;
+            }
         } else {
-            attributes.clear(mappingLangToXmlLang);
+            tagName = ElementName.elementNameByBuffer(strBuf, strBufLen);
+            if (tagName == null) {
+                nonInternedTagName.setNameForNonInterned(Portability.newLocalNameFromBuffer(strBuf, strBufLen,
+                    interner)
+                        // CPPONLY: , false
+                        );
+                tagName = nonInternedTagName;
+            }
         }
-        // ]NOCPP]
-    }
-
-    private void strBufToElementNameString() {
-        // if (strBufOffset != -1) {
-        // return ElementName.elementNameByBuffer(buf, strBufOffset, strBufLen);
-        // } else {
-        tagName = ElementName.elementNameByBuffer(strBuf, 0, strBufLen,
-                interner);
-        // }
+        containsHyphen = false;
+        clearStrBufAfterUse();
     }
 
+    /**
+     * Emits a tag token.
+     *
+     * NOTE: The method may set <code>shouldSuspend</code>, so the caller
+     * must have this pattern after the state's <code>transition</code> call:
+     * <pre>
+     * if (shouldSuspend) {
+     *     break stateloop;
+     * }
+     * continue stateloop;
+     * </pre>
+     *
+     * @param selfClosing
+     * @param pos
+     * @return
+     * @throws SAXException
+     */
     private int emitCurrentTagToken(boolean selfClosing, int pos)
             throws SAXException {
+        // CPPONLY: RememberGt(pos);
         cstart = pos + 1;
         maybeErrSlashInEndTag(selfClosing);
         stateSave = Tokenizer.DATA;
@@ -1118,32 +1287,49 @@ public class Tokenizer implements Locato
              * switched to the PCDATA state.
              */
             maybeErrAttributesOnEndTag(attrs);
+            // CPPONLY: if (!viewingXmlSource) {
             tokenHandler.endTag(tagName);
-            Portability.delete(attributes);
+            // CPPONLY: }
+            // CPPONLY: if (newAttributesEachTime) {
+            // CPPONLY:   Portability.delete(attributes);
+            // CPPONLY:   attributes = null;
+            // CPPONLY: }
         } else {
+            // CPPONLY: if (viewingXmlSource) {
+            // CPPONLY:   assert newAttributesEachTime;
+            // CPPONLY:   Portability.delete(attributes);
+            // CPPONLY:   attributes = null;
+            // CPPONLY: } else {
             tokenHandler.startTag(tagName, attrs, selfClosing);
+            // CPPONLY: }
         }
-        tagName.release();
         tagName = null;
-        resetAttributes();
+        if (newAttributesEachTime) {
+            attributes = null;
+        } else {
+            attributes.clear(mappingLangToXmlLang);
+        }
         /*
          * The token handler may have called setStateAndEndTagExpectation
          * and changed stateSave since the start of this method.
          */
+        suspendIfRequestedAfterCurrentNonTextToken();
         return stateSave;
     }
 
     private void attributeNameComplete() throws SAXException {
-        // if (strBufOffset != -1) {
-        // attributeName = AttributeName.nameByBuffer(buf, strBufOffset,
-        // strBufLen, namePolicy != XmlViolationPolicy.ALLOW);
-        // } else {
-        attributeName = AttributeName.nameByBuffer(strBuf, 0, strBufLen
-        // [NOCPP[
-                , namePolicy != XmlViolationPolicy.ALLOW
-                // ]NOCPP]
-                , interner);
-        // }
+        attributeName = AttributeName.nameByBuffer(strBuf, strBufLen, interner);
+        if (attributeName == null) {
+            // [NOCPP[
+            attributeName = AttributeName.createAttributeName(
+                    Portability.newLocalNameFromBuffer(strBuf, strBufLen,
+                            interner),
+                    namePolicy != XmlViolationPolicy.ALLOW);
+            // ]NOCPP]
+            // CPPONLY:     nonInternedAttributeName.setNameForNonInterned(Portability.newLocalNameFromBuffer(strBuf, strBufLen, interner));
+            // CPPONLY:     attributeName = nonInternedAttributeName;
+        }
+        clearStrBufAfterUse();
 
         if (attributes == null) {
             attributes = new HtmlAttributes(mappingLangToXmlLang);
@@ -1159,7 +1345,6 @@ public class Tokenizer implements Locato
          */
         if (attributes.contains(attributeName)) {
             errDuplicateAttribute();
-            attributeName.release();
             attributeName = null;
         }
     }
@@ -1170,43 +1355,28 @@ public class Tokenizer implements Locato
         // [NOCPP[
         if (metaBoundaryPassed && AttributeName.CHARSET == attributeName
                 && ElementName.META == tagName) {
-            err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes.");
+            err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 1024 bytes.");
         }
         // ]NOCPP]
         if (attributeName != null) {
             // [NOCPP[
-            if (html4) {
-                if (attributeName.isBoolean()) {
-                    if (html4ModeCompatibleWithXhtml1Schemata) {
-                        attributes.addAttribute(attributeName,
-                                attributeName.getLocal(AttributeName.HTML),
-                                xmlnsPolicy);
-                    } else {
-                        attributes.addAttribute(attributeName, "", xmlnsPolicy);
-                    }
-                } else {
-                    err("Attribute value omitted for a non-boolean attribute. (HTML4-only error.)");
-                    attributes.addAttribute(attributeName, "", xmlnsPolicy);
-                }
-            } else {
-                if (AttributeName.SRC == attributeName
-                        || AttributeName.HREF == attributeName) {
-                    warn("Attribute \u201C"
-                            + attributeName.getLocal(AttributeName.HTML)
-                            + "\u201D without an explicit value seen. The attribute may be dropped by IE7.");
-                }
-                // ]NOCPP]
-                attributes.addAttribute(attributeName,
-                        Portability.newEmptyString()
-                        // [NOCPP[
-                        , xmlnsPolicy
-                // ]NOCPP]
-                );
-                // [NOCPP[
+            if (AttributeName.SRC == attributeName
+                    || AttributeName.HREF == attributeName) {
+                warn("Attribute \u201C"
+                        + attributeName.getLocal(AttributeName.HTML)
+                        + "\u201D without an explicit value seen. The attribute may be dropped by IE7.");
             }
             // ]NOCPP]
-            attributeName = null; // attributeName has been adopted by the
-            // |attributes| object
+            attributes.addAttribute(attributeName,
+                    Portability.newEmptyString()
+                    // [NOCPP[
+                    , xmlnsPolicy
+            // ]NOCPP]
+            // CPPONLY: , attributeLine
+            );
+            attributeName = null;
+        } else {
+            clearStrBufAfterUse();
         }
     }
 
@@ -1214,54 +1384,52 @@ public class Tokenizer implements Locato
         // [NOCPP[
         if (metaBoundaryPassed && ElementName.META == tagName
                 && AttributeName.CHARSET == attributeName) {
-            err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 512 bytes.");
+            err("A \u201Ccharset\u201D attribute on a \u201Cmeta\u201D element found after the first 1024 bytes.");
         }
         // ]NOCPP]
         if (attributeName != null) {
-            String val = longStrBufToString(); // Ownership transferred to
+            String val = strBufToString(); // Ownership transferred to
             // HtmlAttributes
-            // [NOCPP[
-            if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata
-                    && attributeName.isCaseFolded()) {
-                val = newAsciiLowerCaseStringFromString(val);
-            }
-            // ]NOCPP]
+            // CPPONLY: if (mViewSource) {
+            // CPPONLY:   mViewSource.MaybeLinkifyAttributeValue(attributeName, val);
+            // CPPONLY: }
             attributes.addAttribute(attributeName, val
             // [NOCPP[
                     , xmlnsPolicy
             // ]NOCPP]
+            // CPPONLY: , attributeLine
             );
-            attributeName = null; // attributeName has been adopted by the
-            // |attributes| object
+            attributeName = null;
+        } else {
+            // We have a duplicate attribute. Explicitly discard its value.
+            clearStrBufAfterUse();
         }
     }
 
     // [NOCPP[
 
-    private static String newAsciiLowerCaseStringFromString(String str) {
-        if (str == null) {
-            return null;
-        }
-        char[] buf = new char[str.length()];
-        for (int i = 0; i < str.length(); i++) {
-            char c = str.charAt(i);
-            if (c >= 'A' && c <= 'Z') {
-                c += 0x20;
-            }
-            buf[i] = c;
-        }
-        return new String(buf);
-    }
-
     protected void startErrorReporting() throws SAXException {
 
     }
 
     // ]NOCPP]
-    
+
     public void start() throws SAXException {
         initializeWithoutStarting();
         tokenHandler.startTokenization(this);
+        // CPPONLY: if (mViewSource) {
+        // CPPONLY:   line = 1;
+        // CPPONLY:   col = -1;
+        // CPPONLY:   nextCharOnNewLine = false;
+        // CPPONLY: } else if (tokenHandler.WantsLineAndColumn()) {
+        // CPPONLY:   line = 0;
+        // CPPONLY:   col = 1;
+        // CPPONLY:   nextCharOnNewLine = true;
+        // CPPONLY: } else {
+        // CPPONLY:   line = -1;
+        // CPPONLY:   col = -1;
+        // CPPONLY:   nextCharOnNewLine = false;
+        // CPPONLY: }
         // [NOCPP[
         startErrorReporting();
         // ]NOCPP]
@@ -1275,6 +1443,13 @@ public class Tokenizer implements Locato
         lastCR = false;
 
         int start = buffer.getStart();
+        int end = buffer.getEnd();
+
+        // In C++, the caller of tokenizeBuffer needs to do this explicitly.
+        // [NOCPP[
+        ensureBufferSpace(end - start);
+        // ]NOCPP]
+
         /**
          * The index of the last <code>char</code> read from <code>buf</code>.
          */
@@ -1316,9 +1491,20 @@ public class Tokenizer implements Locato
          * meaning. (The rest of the array is garbage and should not be
          * examined.)
          */
+        // CPPONLY: if (mViewSource) {
+        // CPPONLY:   mViewSource.SetBuffer(buffer);
+        // CPPONLY:   pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+        // CPPONLY:   mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1);
+        // CPPONLY: } else if (tokenHandler.WantsLineAndColumn()) {
+        // CPPONLY:   pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+        // CPPONLY: } else {
+        // CPPONLY:   pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
+        // CPPONLY: }
+        // [NOCPP[
         pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState,
-                buffer.getEnd());
-        if (pos == buffer.getEnd()) {
+                end);
+        // ]NOCPP]
+        if (pos == end) {
             // exiting due to end of buffer
             buffer.setStart(pos);
         } else {
@@ -1327,71 +1513,106 @@ public class Tokenizer implements Locato
         return lastCR;
     }
 
+    // [NOCPP[
+    private void ensureBufferSpace(int inputLength) throws SAXException {
+        // Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
+        // Adding to the general worst case instead of only the
+        // TreeBuilder-exposed worst case to avoid re-introducing a bug when
+        // unifying the tokenizer and tree builder buffers in the future.
+        int worstCase = strBufLen + inputLength + charRefBufLen + 2;
+        tokenHandler.ensureBufferSpace(worstCase);
+        if (commentPolicy == XmlViolationPolicy.ALTER_INFOSET) {
+            // When altering infoset, if the comment contents are consecutive
+            // hyphens, each hyphen generates a space, too. These buffer
+            // contents never get emitted as characters() to the tokenHandler,
+            // which is why this calculation happens after the call to
+            // ensureBufferSpace on tokenHandler.
+            worstCase *= 2;
+        }
+        if (strBuf == null) {
+            // Add an arbitrary small value to avoid immediate reallocation
+            // once there are a few characters in the buffer.
+            strBuf = new char[worstCase + 128];
+        } else if (worstCase > strBuf.length) {
+            // HotSpot reportedly allocates memory with 8-byte accuracy, so
+            // there's no point in trying to do math here to avoid slop.
+            // Maybe we should add some small constant to worstCase here
+            // but not doing that without profiling. In C++ with jemalloc,
+            // the corresponding method should do math to round up here
+            // to avoid slop.
+            char[] newBuf = new char[Math.max(worstCase, (strBuf.length*5)/4)];
+            System.arraycopy(strBuf, 0, newBuf, 0, strBufLen);
+            strBuf = newBuf;
+        }
+    }
+    // ]NOCPP]
+
     @SuppressWarnings("unused") private int stateLoop(int state, char c,
             int pos, @NoLength char[] buf, boolean reconsume, int returnState,
             int endPos) throws SAXException {
+        boolean reportedConsecutiveHyphens = false;
         /*
          * Idioms used in this code:
-         * 
-         * 
+         *
+         *
          * Consuming the next input character
-         * 
+         *
          * To consume the next input character, the code does this: if (++pos ==
          * endPos) { break stateloop; } c = checkChar(buf, pos);
-         * 
-         * 
+         *
+         *
          * Staying in a state
-         * 
+         *
          * When there's a state that the tokenizer may stay in over multiple
          * input characters, the state has a wrapper |for(;;)| loop and staying
          * in the state continues the loop.
-         * 
-         * 
+         *
+         *
          * Switching to another state
-         * 
+         *
          * To switch to another state, the code sets the state variable to the
          * magic number of the new state. Then it either continues stateloop or
          * breaks out of the state's own wrapper loop if the target state is
          * right after the current state in source order. (This is a partial
          * workaround for Java's lack of goto.)
-         * 
-         * 
+         *
+         *
          * Reconsume support
-         * 
+         *
          * The spec sometimes says that an input character is reconsumed in
          * another state. If a state can ever be entered so that an input
          * character can be reconsumed in it, the state's code starts with an
          * |if (reconsume)| that sets reconsume to false and skips over the
          * normal code for consuming a new character.
-         * 
+         *
          * To reconsume the current character in another state, the code sets
          * |reconsume| to true and then switches to the other state.
-         * 
-         * 
+         *
+         *
          * Emitting character tokens
-         * 
+         *
          * This method emits character tokens lazily. Whenever a new range of
          * character tokens starts, the field cstart must be set to the start
          * index of the range. The flushChars() method must be called at the end
          * of a range to flush it.
-         * 
-         * 
+         *
+         *
          * U+0000 handling
-         * 
+         *
          * The various states have to handle the replacement of U+0000 with
          * U+FFFD. However, if U+0000 would be reconsumed in another state, the
          * replacement doesn't need to happen, because it's handled by the
          * reconsuming state.
-         * 
-         * 
+         *
+         *
          * LF handling
-         * 
+         *
          * Every state needs to increment the line number upon LF unless the LF
          * gets reconsumed by another state which increments the line number.
-         * 
-         * 
+         *
+         *
          * CR handling
-         * 
+         *
          * Every state needs to handle CR unless the CR gets reconsumed and is
          * handled by the reconsuming state. The CR needs to be handled as if it
          * were and LF, the lastCR field must be set to true and then this
@@ -1417,7 +1638,8 @@ public class Tokenizer implements Locato
                                  * reference in data state.
                                  */
                                 flushChars(buf, pos);
-                                clearStrBufAndAppend(c);
+                                assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+                                appendCharRefBuf(c);
                                 setAdditionalAndRememberAmpersandLocation('\u0000');
                                 returnState = state;
                                 state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
@@ -1430,27 +1652,28 @@ public class Tokenizer implements Locato
                                 flushChars(buf, pos);
 
                                 state = transition(state, Tokenizer.TAG_OPEN, reconsume, pos);
-                                break dataloop; // FALL THROUGH continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break dataloop;
                             case '\u0000':
-                                emitReplacementCharacter(buf, pos);
+                                maybeEmitReplacementCharacter(buf, pos);
                                 continue;
                             case '\r':
                                 emitCarriageReturn(buf, pos);
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the input character as a
                                  * character token.
-                                 * 
+                                 *
                                  * Stay in the data state.
                                  */
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case TAG_OPEN:
                     tagopenloop: for (;;) {
                         /*
@@ -1477,15 +1700,17 @@ public class Tokenizer implements Locato
                              * input character (add 0x0020 to the character's
                              * code point),
                              */
-                            clearStrBufAndAppend((char) (c + 0x20));
+                            clearStrBufBeforeUse();
+                            appendStrBuf((char) (c + 0x20));
+                            containsHyphen = false;
                             /* then switch to the tag name state. */
                             state = transition(state, Tokenizer.TAG_NAME, reconsume, pos);
                             /*
                              * (Don't emit the token yet; further details will
                              * be filled in before it is emitted.)
                              */
+                            // `break` optimizes; `continue stateloop;` would be valid
                             break tagopenloop;
-                            // continue stateloop;
                         } else if (c >= 'a' && c <= 'z') {
                             /*
                              * U+0061 LATIN SMALL LETTER A through to U+007A
@@ -1496,15 +1721,17 @@ public class Tokenizer implements Locato
                             /*
                              * set its tag name to the input character,
                              */
-                            clearStrBufAndAppend(c);
+                            clearStrBufBeforeUse();
+                            appendStrBuf(c);
+                            containsHyphen = false;
                             /* then switch to the tag name state. */
                             state = transition(state, Tokenizer.TAG_NAME, reconsume, pos);
                             /*
                              * (Don't emit the token yet; further details will
                              * be filled in before it is emitted.)
                              */
+                            // `break` optimizes; `continue stateloop;` would be valid
                             break tagopenloop;
-                            // continue stateloop;
                         }
                         switch (c) {
                             case '!':
@@ -1522,6 +1749,13 @@ public class Tokenizer implements Locato
                                 state = transition(state, Tokenizer.CLOSE_TAG_OPEN, reconsume, pos);
                                 continue stateloop;
                             case '?':
+                                // CPPONLY: if (viewingXmlSource) {
+                                // CPPONLY: state = transition(state,
+                                // CPPONLY: Tokenizer.PROCESSING_INSTRUCTION,
+                                // CPPONLY: reconsume,
+                                // CPPONLY: pos);
+                                // CPPONLY: continue stateloop;
+                                // CPPONLY: }
                                 /*
                                  * U+003F QUESTION MARK (?) Parse error.
                                  */
@@ -1529,7 +1763,8 @@ public class Tokenizer implements Locato
                                 /*
                                  * Switch to the bogus comment state.
                                  */
-                                clearLongStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                             case '>':
@@ -1561,12 +1796,12 @@ public class Tokenizer implements Locato
                                  * the data state.
                                  */
                                 cstart = pos;
-                                state = transition(state, Tokenizer.DATA, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.DATA, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // FALL THROUGH DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case TAG_NAME:
                     tagnameloop: for (;;) {
                         if (++pos == endPos) {
@@ -1584,6 +1819,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -1594,8 +1830,8 @@ public class Tokenizer implements Locato
                                  */
                                 strBufToElementNameString();
                                 state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break tagnameloop;
-                            // continue stateloop;
                             case '/':
                                 /*
                                  * U+002F SOLIDUS (/) Switch to the self-closing
@@ -1620,7 +1856,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 if (c >= 'A' && c <= 'Z') {
                                     /*
@@ -1632,6 +1868,8 @@ public class Tokenizer implements Locato
                                      * tag name.
                                      */
                                     c += 0x20;
+                                } else if (c == '-') {
+                                    containsHyphen = true;
                                 }
                                 /*
                                  * Anything else Append the current input
@@ -1645,7 +1883,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_ATTRIBUTE_NAME:
                     beforeattributenameloop: for (;;) {
                         if (reconsume) {
@@ -1665,7 +1903,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -1697,7 +1935,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case '\"':
                             case '\'':
                             case '<':
@@ -1712,6 +1950,7 @@ public class Tokenizer implements Locato
                                  * Treat it as per the "anything else" entry
                                  * below.
                                  */
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Start a new attribute in the
@@ -1727,11 +1966,13 @@ public class Tokenizer implements Locato
                                      */
                                     c += 0x20;
                                 }
+                                // CPPONLY: attributeLine = line;
                                 /*
                                  * Set that attribute's name to the current
                                  * input character,
                                  */
-                                clearStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 /*
                                  * and its value to the empty string.
                                  */
@@ -1740,11 +1981,11 @@ public class Tokenizer implements Locato
                                  * Switch to the attribute name state.
                                  */
                                 state = transition(state, Tokenizer.ATTRIBUTE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break beforeattributenameloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case ATTRIBUTE_NAME:
                     attributenameloop: for (;;) {
                         if (++pos == endPos) {
@@ -1762,7 +2003,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -1790,8 +2031,8 @@ public class Tokenizer implements Locato
                                  */
                                 attributeNameComplete();
                                 state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_VALUE, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break attributenameloop;
-                            // continue stateloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Emit the current
@@ -1809,7 +2050,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case '\"':
                             case '\'':
                             case '<':
@@ -1822,6 +2063,7 @@ public class Tokenizer implements Locato
                                  * Treat it as per the "anything else" entry
                                  * below.
                                  */
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 if (c >= 'A' && c <= 'Z') {
                                     /*
@@ -1845,7 +2087,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_ATTRIBUTE_VALUE:
                     beforeattributevalueloop: for (;;) {
                         if (++pos == endPos) {
@@ -1861,7 +2103,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -1876,27 +2118,30 @@ public class Tokenizer implements Locato
                                  * U+0022 QUOTATION MARK (") Switch to the
                                  * attribute value (double-quoted) state.
                                  */
-                                clearLongStrBuf();
+                                // CPPONLY: attributeLine = line;
+                                clearStrBufBeforeUse();
                                 state = transition(state, Tokenizer.ATTRIBUTE_VALUE_DOUBLE_QUOTED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break beforeattributevalueloop;
-                            // continue stateloop;
                             case '&':
                                 /*
                                  * U+0026 AMPERSAND (&) Switch to the attribute
                                  * value (unquoted) state and reconsume this
                                  * input character.
                                  */
-                                clearLongStrBuf();
+                                // CPPONLY: attributeLine = line;
+                                clearStrBufBeforeUse();
+                                reconsume = true;
                                 state = transition(state, Tokenizer.ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
                                 noteUnquotedAttributeValue();
-                                reconsume = true;
                                 continue stateloop;
                             case '\'':
                                 /*
                                  * U+0027 APOSTROPHE (') Switch to the attribute
                                  * value (single-quoted) state.
                                  */
-                                clearLongStrBuf();
+                                // CPPONLY: attributeLine = line;
+                                clearStrBufBeforeUse();
                                 state = transition(state, Tokenizer.ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume, pos);
                                 continue stateloop;
                             case '>':
@@ -1918,7 +2163,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case '<':
                             case '=':
                             case '`':
@@ -1931,15 +2176,15 @@ public class Tokenizer implements Locato
                                  * Treat it as per the "anything else" entry
                                  * below.
                                  */
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
-                                // [NOCPP[
-                                errHtml4NonNameInUnquotedAttribute(c);
-                                // ]NOCPP]
                                 /*
                                  * Anything else Append the current input
                                  * character to the current attribute's value.
                                  */
-                                clearLongStrBufAndAppend(c);
+                                // CPPONLY: attributeLine = line;
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the attribute value (unquoted)
                                  * state.
@@ -1950,7 +2195,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
                     attributevaluedoublequotedloop: for (;;) {
                         if (reconsume) {
@@ -1973,8 +2218,8 @@ public class Tokenizer implements Locato
                                 addAttributeWithValue();
 
                                 state = transition(state, Tokenizer.AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break attributevaluedoublequotedloop;
-                            // continue stateloop;
                             case '&':
                                 /*
                                  * U+0026 AMPERSAND (&) Switch to the character
@@ -1982,26 +2227,27 @@ public class Tokenizer implements Locato
                                  * additional allowed character being U+0022
                                  * QUOTATION MARK (").
                                  */
-                                clearStrBufAndAppend(c);
+                                assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+                                appendCharRefBuf(c);
                                 setAdditionalAndRememberAmpersandLocation('\"');
                                 returnState = state;
                                 state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current attribute's value.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the attribute value (double-quoted)
                                  * state.
@@ -2009,7 +2255,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_ATTRIBUTE_VALUE_QUOTED:
                     afterattributevaluequotedloop: for (;;) {
                         if (++pos == endPos) {
@@ -2026,7 +2272,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -2043,8 +2289,8 @@ public class Tokenizer implements Locato
                                  * start tag state.
                                  */
                                 state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterattributevaluequotedloop;
-                            // continue stateloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Emit the current
@@ -2067,12 +2313,12 @@ public class Tokenizer implements Locato
                                  * Reconsume the character in the before
                                  * attribute name state.
                                  */
-                                state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SELF_CLOSING_START_TAG:
                     if (++pos == endPos) {
                         break stateloop;
@@ -2088,9 +2334,6 @@ public class Tokenizer implements Locato
                              * flag of the current tag token. Emit the current
                              * tag token.
                              */
-                            // [NOCPP[
-                            errHtml4XmlVoidSyntax();
-                            // ]NOCPP]
                             state = transition(state, emitCurrentTagToken(true, pos), reconsume, pos);
                             if (shouldSuspend) {
                                 break stateloop;
@@ -2106,11 +2349,11 @@ public class Tokenizer implements Locato
                              * Reconsume the character in the before attribute
                              * name state.
                              */
-                            state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                             continue stateloop;
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case ATTRIBUTE_VALUE_UNQUOTED:
                     for (;;) {
                         if (reconsume) {
@@ -2132,7 +2375,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -2151,7 +2394,8 @@ public class Tokenizer implements Locato
                                  * additional allowed character being U+003E
                                  * GREATER-THAN SIGN (>)
                                  */
-                                clearStrBufAndAppend(c);
+                                assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+                                appendCharRefBuf(c);
                                 setAdditionalAndRememberAmpersandLocation('>');
                                 returnState = state;
                                 state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
@@ -2172,7 +2416,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case '<':
                             case '\"':
                             case '\'':
@@ -2188,24 +2432,21 @@ public class Tokenizer implements Locato
                                  * Treat it as per the "anything else" entry
                                  * below.
                                  */
-                                // fall through
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
-                                // [NOCPP]
-                                errHtml4NonNameInUnquotedAttribute(c);
-                                // ]NOCPP]
                                 /*
                                  * Anything else Append the current input
                                  * character to the current attribute's value.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the attribute value (unquoted) state.
                                  */
                                 continue;
                         }
                     }
-                    // XXX reorder point
-                case AFTER_ATTRIBUTE_NAME:
+                    // no fallthrough, reordering opportunity
+               case AFTER_ATTRIBUTE_NAME:
                     for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
@@ -2220,7 +2461,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -2261,7 +2502,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case '\"':
                             case '\'':
                             case '<':
@@ -2270,6 +2511,7 @@ public class Tokenizer implements Locato
                                  * Treat it as per the "anything else" entry
                                  * below.
                                  */
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 addAttributeWithoutValue();
                                 /*
@@ -2290,7 +2532,8 @@ public class Tokenizer implements Locato
                                  * Set that attribute's name to the current
                                  * input character,
                                  */
-                                clearStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 /*
                                  * and its value to the empty string.
                                  */
@@ -2302,7 +2545,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case MARKUP_DECLARATION_OPEN:
                     markupdeclarationopenloop: for (;;) {
                         if (++pos == endPos) {
@@ -2314,12 +2557,12 @@ public class Tokenizer implements Locato
                          * HYPHEN-MINUS characters (-), consume those two
                          * characters, create a comment token whose data is the
                          * empty string, and switch to the comment start state.
-                         * 
+                         *
                          * Otherwise, if the next seven characters are an ASCII
                          * case-insensitive match for the word "DOCTYPE", then
                          * consume those characters and switch to the DOCTYPE
                          * state.
-                         * 
+                         *
                          * Otherwise, if the insertion mode is
                          * "in foreign content" and the current node is not an
                          * element in the HTML namespace and the next seven
@@ -2328,7 +2571,7 @@ public class Tokenizer implements Locato
                          * U+005B LEFT SQUARE BRACKET character before and
                          * after), then consume those characters and switch to
                          * the CDATA section state.
-                         * 
+                         *
                          * Otherwise, is is a parse error. Switch to the bogus
                          * comment state. The next character that is consumed,
                          * if any, is the first character that will be in the
@@ -2336,33 +2579,36 @@ public class Tokenizer implements Locato
                          */
                         switch (c) {
                             case '-':
-                                clearLongStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.MARKUP_DECLARATION_HYPHEN, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break markupdeclarationopenloop;
-                            // continue stateloop;
                             case 'd':
                             case 'D':
-                                clearLongStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 index = 0;
                                 state = transition(state, Tokenizer.MARKUP_DECLARATION_OCTYPE, reconsume, pos);
                                 continue stateloop;
                             case '[':
                                 if (tokenHandler.cdataSectionAllowed()) {
-                                    clearLongStrBufAndAppend(c);
+                                    clearStrBufBeforeUse();
+                                    appendStrBuf(c);
                                     index = 0;
                                     state = transition(state, Tokenizer.CDATA_START, reconsume, pos);
                                     continue stateloop;
                                 }
-                                // else fall through
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 errBogusComment();
-                                clearLongStrBuf();
-                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
+                                clearStrBufBeforeUse();
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case MARKUP_DECLARATION_HYPHEN:
                     markupdeclarationhyphenloop: for (;;) {
                         if (++pos == endPos) {
@@ -2370,22 +2616,21 @@ public class Tokenizer implements Locato
                         }
                         c = checkChar(buf, pos);
                         switch (c) {
-                            case '\u0000':
-                                break stateloop;
                             case '-':
-                                clearLongStrBuf();
+                                clearStrBufAfterOneHyphen();
                                 state = transition(state, Tokenizer.COMMENT_START, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break markupdeclarationhyphenloop;
-                            // continue stateloop;
                             default:
                                 errBogusComment();
-                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_START:
+                    reportedConsecutiveHyphens = false;
                     commentstartloop: for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
@@ -2393,8 +2638,8 @@ public class Tokenizer implements Locato
                         c = checkChar(buf, pos);
                         /*
                          * Comment start state
-                         * 
-                         * 
+                         *
+                         *
                          * Consume the next input character:
                          */
                         switch (c) {
@@ -2403,7 +2648,7 @@ public class Tokenizer implements Locato
                                  * U+002D HYPHEN-MINUS (-) Switch to the comment
                                  * start dash state.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.COMMENT_START_DASH, reconsume, pos);
                                 continue stateloop;
                             case '>':
@@ -2417,33 +2662,40 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
+                                continue stateloop;
+                            case '<':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 break commentstartloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the input character to
                                  * the comment token's data.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the comment state.
                                  */
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break commentstartloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT:
                     commentloop: for (;;) {
                         if (++pos == endPos) {
@@ -2459,32 +2711,36 @@ public class Tokenizer implements Locato
                                  * U+002D HYPHEN-MINUS (-) Switch to the comment
                                  * end dash state
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break commentloop;
-                            // continue stateloop;
+                            case '<':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
+                                continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the input character to
                                  * the comment token's data.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the comment state.
                                  */
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_END_DASH:
                     commentenddashloop: for (;;) {
                         if (++pos == endPos) {
@@ -2501,28 +2757,32 @@ public class Tokenizer implements Locato
                                  * U+002D HYPHEN-MINUS (-) Switch to the comment
                                  * end state
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.COMMENT_END, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break commentenddashloop;
-                            // continue stateloop;
+                            case '<':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
+                                continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append a U+002D HYPHEN-MINUS
                                  * (-) character and the input character to the
                                  * comment token's data.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the comment state.
                                  */
@@ -2530,7 +2790,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_END:
                     commentendloop: for (;;) {
                         if (++pos == endPos) {
@@ -2552,6 +2812,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '-':
                                 /* U+002D HYPHEN-MINUS (-) Parse error. */
@@ -2559,34 +2822,40 @@ public class Tokenizer implements Locato
                                  * Append a U+002D HYPHEN-MINUS (-) character to
                                  * the comment token's data.
                                  */
-                                adjustDoubleHyphenAndAppendToLongStrBufAndErr(c);
+                                adjustDoubleHyphenAndAppendToStrBufAndErr(c, reportedConsecutiveHyphens);
+                                reportedConsecutiveHyphens = true;
                                 /*
                                  * Stay in the comment end state.
                                  */
                                 continue;
+                            case '<':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
+                                continue stateloop;
                             case '\r':
-                                adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn();
+                                adjustDoubleHyphenAndAppendToStrBufCarriageReturn();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 break stateloop;
                             case '\n':
-                                adjustDoubleHyphenAndAppendToLongStrBufLineFeed();
+                                adjustDoubleHyphenAndAppendToStrBufLineFeed();
                                 state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 continue stateloop;
                             case '!':
-                                errHyphenHyphenBang();
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.COMMENT_END_BANG, reconsume, pos);
-                                continue stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break commentendloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Append two U+002D HYPHEN-MINUS (-) characters
                                  * and the input character to the comment
                                  * token's data.
                                  */
-                                adjustDoubleHyphenAndAppendToLongStrBufAndErr(c);
+                                adjustDoubleHyphenAndAppendToStrBufAndErr(c, reportedConsecutiveHyphens);
+                                reportedConsecutiveHyphens = true;
                                 /*
                                  * Switch to the comment state.
                                  */
@@ -2594,7 +2863,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case COMMENT_END_BANG:
                     for (;;) {
                         if (++pos == endPos) {
@@ -2603,7 +2872,7 @@ public class Tokenizer implements Locato
                         c = checkChar(buf, pos);
                         /*
                          * Comment end bang state
-                         * 
+                         *
                          * Consume the next input character:
                          */
                         switch (c) {
@@ -2617,6 +2886,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '-':
                                 /*
@@ -2624,21 +2896,23 @@ public class Tokenizer implements Locato
                                  * and a U+0021 EXCLAMATION MARK (!) character
                                  * to the comment token's data.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the comment end dash state.
                                  */
                                 state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos);
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
-                                continue;
+                                appendStrBufLineFeed();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append two U+002D HYPHEN-MINUS
@@ -2647,7 +2921,7 @@ public class Tokenizer implements Locato
                                  * comment token's data. Switch to the comment
                                  * state.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the comment state.
                                  */
@@ -2655,7 +2929,179 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
+                case COMMENT_LESSTHAN:
+                    commentlessthanloop: for (;;) {
+                        if (++pos == endPos) {
+                            break stateloop;
+                        }
+                        c = checkChar(buf, pos);
+                        switch (c) {
+                            case '!':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN_BANG, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break commentlessthanloop;
+                            case '<':
+                                appendStrBuf(c);
+                                continue;
+                            case '-':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_END_DASH, reconsume, pos);
+                                continue stateloop;
+                            case '\r':
+                                appendStrBufCarriageReturn();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                break stateloop;
+                            case '\n':
+                                appendStrBufLineFeed();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                continue stateloop;
+                            case '\u0000':
+                                c = '\uFFFD';
+                                // CPPONLY: MOZ_FALLTHROUGH;
+                            default:
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                continue stateloop;
+                        }
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case COMMENT_LESSTHAN_BANG:
+                    commentlessthanbangloop: for (;;) {
+                        if (++pos == endPos) {
+                            break stateloop;
+                        }
+                        c = checkChar(buf, pos);
+                        switch (c) {
+                            case '-':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break commentlessthanbangloop;
+                            case '<':
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
+                                continue stateloop;
+                            case '\r':
+                                appendStrBufCarriageReturn();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                break stateloop;
+                            case '\n':
+                                appendStrBufLineFeed();
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                continue stateloop;
+                            case '\u0000':
+                                c = '\uFFFD';
+                                // CPPONLY: MOZ_FALLTHROUGH;
+                            default:
+                                appendStrBuf(c);
+                                state = transition(state, Tokenizer.COMMENT, reconsume, pos);
+                                continue stateloop;
+                        }
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case COMMENT_LESSTHAN_BANG_DASH:
+                    if (++pos == endPos) {
+                        break stateloop;
+                    }
+                    c = checkChar(buf, pos);
+                    switch (c) {
+                        case '-':
+                            appendStrBuf(c);
+                            state = transition(state,
+                                    Tokenizer.COMMENT_LESSTHAN_BANG_DASH_DASH,
+                                    reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
+                            break;
+                        case '<':
+                            appendStrBuf(c);
+                            state = transition(state,
+                                    Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
+                            continue stateloop;
+                        case '\r':
+                            appendStrBufCarriageReturn();
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            break stateloop;
+                        case '\n':
+                            appendStrBufLineFeed();
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            continue stateloop;
+                        case '\u0000':
+                            c = '\uFFFD';
+                            // CPPONLY: MOZ_FALLTHROUGH;
+                        default:
+                            appendStrBuf(c);
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            continue stateloop;
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case COMMENT_LESSTHAN_BANG_DASH_DASH:
+                    if (++pos == endPos) {
+                        break stateloop;
+                    }
+                    c = checkChar(buf, pos);
+                    switch (c) {
+                        case '>':
+                            appendStrBuf(c);
+                            emitComment(3, pos);
+                            state = transition(state, Tokenizer.DATA, reconsume,
+                                    pos);
+                            if (shouldSuspend) {
+                                break stateloop;
+                            }
+                            continue stateloop;
+                        case '-':
+                            errNestedComment();
+                            adjustDoubleHyphenAndAppendToStrBufAndErr(c,
+                                    reportedConsecutiveHyphens);
+                            reportedConsecutiveHyphens = true;
+                            state = transition(state, Tokenizer.COMMENT_END,
+                                    reconsume, pos);
+                            continue stateloop;
+                        case '\r':
+                            c = '\n';
+                            silentCarriageReturn();
+                            errNestedComment();
+                            adjustDoubleHyphenAndAppendToStrBufAndErr(c,
+                                    reportedConsecutiveHyphens);
+                            reportedConsecutiveHyphens = true;
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            break stateloop;
+                        case '\n':
+                            silentLineFeed();
+                            errNestedComment();
+                            adjustDoubleHyphenAndAppendToStrBufAndErr(c,
+                                    reportedConsecutiveHyphens);
+                            reportedConsecutiveHyphens = true;
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            continue stateloop;
+                        case '!':
+                            errNestedComment();
+                            adjustDoubleHyphenAndAppendToStrBufAndErr(c,
+                                    reportedConsecutiveHyphens);
+                            reportedConsecutiveHyphens = true;
+                            state = transition(state,
+                                    Tokenizer.COMMENT_END_BANG, reconsume, pos);
+                            continue stateloop;
+                        case '\u0000':
+                            c = '\uFFFD';
+                            // CPPONLY: MOZ_FALLTHROUGH;
+                        default:
+                            errNestedComment();
+                            adjustDoubleHyphenAndAppendToStrBufAndErr(c,
+                                    reportedConsecutiveHyphens);
+                            reportedConsecutiveHyphens = true;
+                            state = transition(state, Tokenizer.COMMENT,
+                                    reconsume, pos);
+                            continue stateloop;
+                    }
+                    // no fallthrough, reordering opportunity
                 case COMMENT_START_DASH:
                     if (++pos == endPos) {
                         break stateloop;
@@ -2663,7 +3109,7 @@ public class Tokenizer implements Locato
                     c = checkChar(buf, pos);
                     /*
                      * Comment start dash state
-                     * 
+                     *
                      * Consume the next input character:
                      */
                     switch (c) {
@@ -2672,7 +3118,7 @@ public class Tokenizer implements Locato
                              * U+002D HYPHEN-MINUS (-) Switch to the comment end
                              * state
                              */
-                            appendLongStrBuf(c);
+                            appendStrBuf(c);
                             state = transition(state, Tokenizer.COMMENT_END, reconsume, pos);
                             continue stateloop;
                         case '>':
@@ -2683,32 +3129,39 @@ public class Tokenizer implements Locato
                              * Switch to the data state.
                              */
                             state = transition(state, Tokenizer.DATA, reconsume, pos);
+                            if (shouldSuspend) {
+                                break stateloop;
+                            }
+                            continue stateloop;
+                        case '<':
+                            appendStrBuf(c);
+                            state = transition(state, Tokenizer.COMMENT_LESSTHAN, reconsume, pos);
                             continue stateloop;
                         case '\r':
-                            appendLongStrBufCarriageReturn();
+                            appendStrBufCarriageReturn();
                             state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                             break stateloop;
                         case '\n':
-                            appendLongStrBufLineFeed();
+                            appendStrBufLineFeed();
                             state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                             continue stateloop;
                         case '\u0000':
                             c = '\uFFFD';
-                            // fall thru
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         default:
                             /*
                              * Append a U+002D HYPHEN-MINUS character (-) and
                              * the current input character to the comment
                              * token's data.
                              */
-                            appendLongStrBuf(c);
+                            appendStrBuf(c);
                             /*
                              * Switch to the comment state.
                              */
                             state = transition(state, Tokenizer.COMMENT, reconsume, pos);
                             continue stateloop;
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case CDATA_START:
                     for (;;) {
                         if (++pos == endPos) {
@@ -2717,23 +3170,25 @@ public class Tokenizer implements Locato
                         c = checkChar(buf, pos);
                         if (index < 6) { // CDATA_LSQB.length
                             if (c == Tokenizer.CDATA_LSQB[index]) {
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                             } else {
                                 errBogusComment();
-                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                             }
                             index++;
                             continue;
                         } else {
+                            clearStrBufAfterUse();
                             cstart = pos; // start coalescing
-                            state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
                             reconsume = true;
-                            break; // FALL THROUGH continue stateloop;
+                            state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
+                            break;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case CDATA_SECTION:
                     cdatasectionloop: for (;;) {
                         if (reconsume) {
@@ -2748,60 +3203,79 @@ public class Tokenizer implements Locato
                             case ']':
                                 flushChars(buf, pos);
                                 state = transition(state, Tokenizer.CDATA_RSQB, reconsume, pos);
-                                break cdatasectionloop; // FALL THROUGH
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break cdatasectionloop;
                             case '\u0000':
-                                emitReplacementCharacter(buf, pos);
+                                maybeEmitReplacementCharacter(buf, pos);
                                 continue;
                             case '\r':
                                 emitCarriageReturn(buf, pos);
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case CDATA_RSQB:
-                    cdatarsqb: for (;;) {
+                    if (++pos == endPos) {
+                        break stateloop;
+                    }
+                    c = checkChar(buf, pos);
+                    switch (c) {
+                        case ']':
+                            state = transition(state, Tokenizer.CDATA_RSQB_RSQB,
+                                    reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
+                            break;
+                        default:
+                            tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1);
+                            cstart = pos;
+                            reconsume = true;
+                            state = transition(state, Tokenizer.CDATA_SECTION,
+                                    reconsume, pos);
+                            continue stateloop;
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case CDATA_RSQB_RSQB:
+                    cdatarsqbrsqb: for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
                         switch (c) {
                             case ']':
-                                state = transition(state, Tokenizer.CDATA_RSQB_RSQB, reconsume, pos);
-                                break cdatarsqb;
+                                // Saw a third ]. Emit one ] (logically the
+                                // first one) and stay in this state to
+                                // remember that the last two characters seen
+                                // have been ]].
+                                tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 1);
+                                continue;
+                            case '>':
+                                cstart = pos + 1;
+                                state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                // Since a CDATA section starts with a less-than sign, it
+                                // participates in the suspension-after-current-token
+                                // behavior. (The suspension can be requested when the
+                                // less-than sign has been seen but we don't yet know the
+                                // resulting token type.) Therefore, we need to deal with
+                                // a potential request here.
+                                suspendIfRequestedAfterCurrentNonTextToken();
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
+                                continue stateloop;
                             default:
-                                tokenHandler.characters(Tokenizer.RSQB_RSQB, 0,
-                                        1);
+                                tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2);
                                 cstart = pos;
-                                state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
-                case CDATA_RSQB_RSQB:
-                    if (++pos == endPos) {
-                        break stateloop;
-                    }
-                    c = checkChar(buf, pos);
-                    switch (c) {
-                        case '>':
-                            cstart = pos + 1;
-                            state = transition(state, Tokenizer.DATA, reconsume, pos);
-                            continue stateloop;
-                        default:
-                            tokenHandler.characters(Tokenizer.RSQB_RSQB, 0, 2);
-                            cstart = pos;
-                            state = transition(state, Tokenizer.CDATA_SECTION, reconsume, pos);
-                            reconsume = true;
-                            continue stateloop;
-
-                    }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
                     attributevaluesinglequotedloop: for (;;) {
                         if (reconsume) {
@@ -2832,27 +3306,28 @@ public class Tokenizer implements Locato
                                  * + additional allowed character being U+0027
                                  * APOSTROPHE (').
                                  */
-                                clearStrBufAndAppend(c);
+                                assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+                                appendCharRefBuf(c);
                                 setAdditionalAndRememberAmpersandLocation('\'');
                                 returnState = state;
                                 state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break attributevaluesinglequotedloop;
-                            // continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current attribute's value.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the attribute value (double-quoted)
                                  * state.
@@ -2860,15 +3335,12 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case CONSUME_CHARACTER_REFERENCE:
                     if (++pos == endPos) {
                         break stateloop;
                     }
                     c = checkChar(buf, pos);
-                    if (c == '\u0000') {
-                        break stateloop;
-                    }
                     /*
                      * Unlike the definition is the spec, this state does not
                      * return a value and never requires the caller to
@@ -2881,7 +3353,7 @@ public class Tokenizer implements Locato
                      * This section defines how to consume a character
                      * reference. This definition is used when parsing character
                      * references in text and in attributes.
-                     * 
+                     *
                      * The behavior depends on the identity of the next
                      * character (the one immediately after the U+0026 AMPERSAND
                      * character):
@@ -2894,26 +3366,28 @@ public class Tokenizer implements Locato
                         case '\u000C':
                         case '<':
                         case '&':
-                            emitOrAppendStrBuf(returnState);
+                        case '\u0000':
+                        case ';':
+                            emitOrAppendCharRefBuf(returnState);
                             if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                 cstart = pos;
                             }
-                            state = transition(state, returnState, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, returnState, reconsume, pos);
                             continue stateloop;
                         case '#':
                             /*
                              * U+0023 NUMBER SIGN (#) Consume the U+0023 NUMBER
                              * SIGN.
                              */
-                            appendStrBuf('#');
+                            appendCharRefBuf('#');
                             state = transition(state, Tokenizer.CONSUME_NCR, reconsume, pos);
                             continue stateloop;
                         default:
                             if (c == additional) {
-                                emitOrAppendStrBuf(returnState);
-                                state = transition(state, returnState, reconsume, pos);
+                                emitOrAppendCharRefBuf(returnState);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                             }
                             if (c >= 'a' && c <= 'z') {
@@ -2922,37 +3396,33 @@ public class Tokenizer implements Locato
                                 firstCharKey = c - 'A';
                             } else {
                                 // No match
-                                /*
-                                 * If no match can be made, then this is a parse
-                                 * error.
-                                 */
-                                errNoNamedCharacterMatch();
-                                emitOrAppendStrBuf(returnState);
+                                if (c == ';') {
+                                    errNoNamedCharacterMatch();
+                                }
+                                emitOrAppendCharRefBuf(returnState);
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos;
                                 }
-                                state = transition(state, returnState, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                             }
                             // Didn't fail yet
-                            appendStrBuf(c);
+                            appendCharRefBuf(c);
                             state = transition(state, Tokenizer.CHARACTER_REFERENCE_HILO_LOOKUP, reconsume, pos);
-                            // FALL THROUGH continue stateloop;
+                            // `break` optimizes; `continue stateloop;` would be valid
+                            break;
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case CHARACTER_REFERENCE_HILO_LOOKUP:
                     {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
-                        if (c == '\u0000') {
-                            break stateloop;
-                        }
                         /*
                          * The data structure is as follows:
-                         * 
+                         *
                          * HILO_ACCEL is a two-dimensional int array whose major
                          * index corresponds to the second character of the
                          * character reference (code point as index) and the
@@ -2963,7 +3433,7 @@ public class Tokenizer implements Locato
                          * to omit parts of it: The second dimension of the
                          * table is null when no character reference starts with
                          * the character corresponding to that row.
-                         * 
+                         *
                          * The int value HILO_ACCEL (by these indeces) is zero
                          * if there exists no character reference starting with
                          * that two-letter prefix. Otherwise, the value is an
@@ -2975,14 +3445,14 @@ public class Tokenizer implements Locato
                          * first two character reference names share their
                          * prefix so the packed int cannot be 0 by packing the
                          * two shorts.)
-                         * 
+                         *
                          * NAMES is an array of byte arrays where each byte
                          * array encodes the name of a character references as
                          * ASCII. The names omit the first two letters of the
                          * name. (Since storing the first two letters would be
                          * redundant with the data contained in HILO_ACCEL.) The
                          * entries are lexically sorted.
-                         * 
+                         *
                          * For a given index in NAMES, the same index in VALUES
                          * contains the corresponding expansion as an array of
                          * two UTF-16 code units (either the character and
@@ -2996,38 +3466,34 @@ public class Tokenizer implements Locato
                             }
                         }
                         if (hilo == 0) {
-                            /*
-                             * If no match can be made, then this is a parse
-                             * error.
-                             */
-                            errNoNamedCharacterMatch();
-                            emitOrAppendStrBuf(returnState);
+                            if (c == ';') {
+                                errNoNamedCharacterMatch();
+                            }
+                            emitOrAppendCharRefBuf(returnState);
                             if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                 cstart = pos;
                             }
-                            state = transition(state, returnState, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, returnState, reconsume, pos);
                             continue stateloop;
                         }
                         // Didn't fail yet
-                        appendStrBuf(c);
+                        appendCharRefBuf(c);
                         lo = hilo & 0xFFFF;
                         hi = hilo >> 16;
                         entCol = -1;
                         candidate = -1;
-                        strBufMark = 0;
+                        charRefBufMark = 0;
                         state = transition(state, Tokenizer.CHARACTER_REFERENCE_TAIL, reconsume, pos);
-                        // FALL THROUGH continue stateloop;
+                        // fallthrough optimizes; `continue stateloop;` would also be valid
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case CHARACTER_REFERENCE_TAIL:
                     outer: for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
-                        if (c == '\u0000') {
-                            break stateloop;
-                        }
                         entCol++;
                         /*
                          * Consume the maximum number of characters possible,
@@ -3042,7 +3508,7 @@ public class Tokenizer implements Locato
                             }
                             if (entCol == NamedCharacters.NAMES[lo].length()) {
                                 candidate = lo;
-                                strBufMark = strBufLen;
+                                charRefBufMark = charRefBufLen;
                                 lo++;
                             } else if (entCol > NamedCharacters.NAMES[lo].length()) {
                                 break outer;
@@ -3069,25 +3535,37 @@ public class Tokenizer implements Locato
                             }
                         }
 
+                        if (c == ';') {
+                            // If we see a semicolon, there cannot be a
+                            // longer match. Break the loop. However, before
+                            // breaking, take the longest match so far as the
+                            // candidate, if we are just about to complete a
+                            // match.
+                            if (entCol + 1 == NamedCharacters.NAMES[lo].length()) {
+                                candidate = lo;
+                                charRefBufMark = charRefBufLen;
+                            }
+                            break outer;
+                        }
+
                         if (hi < lo) {
                             break outer;
                         }
-                        appendStrBuf(c);
+                        appendCharRefBuf(c);
                         continue;
                     }
 
                     if (candidate == -1) {
                         // reconsume deals with CR, LF or nul
-                        /*
-                         * If no match can be made, then this is a parse error.
-                         */
-                        errNoNamedCharacterMatch();
-                        emitOrAppendStrBuf(returnState);
+                        if (c == ';') {
+                            errNoNamedCharacterMatch();
+                        }
+                        emitOrAppendCharRefBuf(returnState);
                         if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                             cstart = pos;
                         }
-                        state = transition(state, returnState, reconsume, pos);
                         reconsume = true;
+                        state = transition(state, returnState, reconsume, pos);
                         continue stateloop;
                     } else {
                         // c can't be CR, LF or nul if we got here
@@ -3105,14 +3583,10 @@ public class Tokenizer implements Locato
                                  * not a U+003B SEMICOLON (;),
                                  */
                                 char ch;
-                                if (strBufMark == strBufLen) {
+                                if (charRefBufMark == charRefBufLen) {
                                     ch = c;
                                 } else {
-                                    // if (strBufOffset != -1) {
-                                    // ch = buf[strBufOffset + strBufMark];
-                                    // } else {
-                                    ch = strBuf[strBufMark];
-                                    // }
+                                    ch = charRefBuf[charRefBufMark];
                                 }
                                 if (ch == '=' || (ch >= '0' && ch <= '9')
                                         || (ch >= 'A' && ch <= 'Z')
@@ -3129,10 +3603,12 @@ public class Tokenizer implements Locato
                                      * after the U+0026 AMPERSAND (&) must be
                                      * unconsumed, and nothing is returned.
                                      */
-                                    errNoNamedCharacterMatch();
-                                    appendStrBufToLongStrBuf();
-                                    state = transition(state, returnState, reconsume, pos);
+                                    if (c == ';') {
+                                        errNoNamedCharacterMatch();
+                                    }
+                                    appendCharRefBufToStrBuf();
                                     reconsume = true;
+                                    state = transition(state, returnState, reconsume, pos);
                                     continue stateloop;
                                 }
                             }
@@ -3149,6 +3625,7 @@ public class Tokenizer implements Locato
                          * second column of the named character references
                          * table).
                          */
+                        // CPPONLY: completedNamedCharacterReference();
                         @Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
                         if (
                         // [NOCPP[
@@ -3161,33 +3638,30 @@ public class Tokenizer implements Locato
                             emitOrAppendTwo(val, returnState);
                         }
                         // this is so complicated!
-                        if (strBufMark < strBufLen) {
-                            // if (strBufOffset != -1) {
-                            // if ((returnState & (~1)) != 0) {
-                            // for (int i = strBufMark; i < strBufLen; i++) {
-                            // appendLongStrBuf(buf[strBufOffset + i]);
-                            // }
-                            // } else {
-                            // tokenHandler.characters(buf, strBufOffset
-                            // + strBufMark, strBufLen
-                            // - strBufMark);
-                            // }
-                            // } else {
+                        if (charRefBufMark < charRefBufLen) {
                             if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
-                                for (int i = strBufMark; i < strBufLen; i++) {
-                                    appendLongStrBuf(strBuf[i]);
-                                }
+                                appendStrBuf(charRefBuf, charRefBufMark,
+                                        charRefBufLen - charRefBufMark);
                             } else {
-                                tokenHandler.characters(strBuf, strBufMark,
-                                        strBufLen - strBufMark);
+                                tokenHandler.characters(charRefBuf, charRefBufMark,
+                                        charRefBufLen - charRefBufMark);
                             }
-                            // }
                         }
+                        // charRefBufLen will be zeroed below!
+
+                        // Check if we broke out early with c being the last
+                        // character that matched as opposed to being the
+                        // first one that didn't match. In the case of an
+                        // early break, the next run on text should start
+                        // *after* the current character and the current
+                        // character shouldn't be reconsumed.
+                        boolean earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
+                        charRefBufLen = 0;
                         if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
-                            cstart = pos;
+                            cstart = earlyBreak ? pos + 1 : pos;
                         }
+                        reconsume = !earlyBreak;
                         state = transition(state, returnState, reconsume, pos);
-                        reconsume = true;
                         continue stateloop;
                         /*
                          * If the markup contains I'm &notit; I tell you, the
@@ -3197,13 +3671,12 @@ public class Tokenizer implements Locato
                          * I'm ∉ I tell you.
                          */
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case CONSUME_NCR:
                     if (++pos == endPos) {
                         break stateloop;
                     }
                     c = checkChar(buf, pos);
-                    prevValue = -1;
                     value = 0;
                     seenDigits = false;
                     /*
@@ -3217,18 +3690,18 @@ public class Tokenizer implements Locato
                             /*
                              * U+0078 LATIN SMALL LETTER X U+0058 LATIN CAPITAL
                              * LETTER X Consume the X.
-                             * 
+                             *
                              * Follow the steps below, but using the range of
                              * characters U+0030 DIGIT ZERO through to U+0039
                              * DIGIT NINE, U+0061 LATIN SMALL LETTER A through
                              * to U+0066 LATIN SMALL LETTER F, and U+0041 LATIN
                              * CAPITAL LETTER A, through to U+0046 LATIN CAPITAL
                              * LETTER F (in other words, 0-9, A-F, a-f).
-                             * 
+                             *
                              * When it comes to interpreting the number,
                              * interpret it as a hexadecimal number.
                              */
-                            appendStrBuf(c);
+                            appendCharRefBuf(c);
                             state = transition(state, Tokenizer.HEX_NCR_LOOP, reconsume, pos);
                             continue stateloop;
                         default:
@@ -3236,15 +3709,16 @@ public class Tokenizer implements Locato
                              * Anything else Follow the steps below, but using
                              * the range of characters U+0030 DIGIT ZERO through
                              * to U+0039 DIGIT NINE (i.e. just 0-9).
-                             * 
+                             *
                              * When it comes to interpreting the number,
                              * interpret it as a decimal number.
                              */
-                            state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos);
                             reconsume = true;
-                            // FALL THROUGH continue stateloop;
+                            state = transition(state, Tokenizer.DECIMAL_NRC_LOOP, reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
+                            break;
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DECIMAL_NRC_LOOP:
                     decimalloop: for (;;) {
                         if (reconsume) {
@@ -3255,21 +3729,18 @@ public class Tokenizer implements Locato
                             }
                             c = checkChar(buf, pos);
                         }
-                        // Deal with overflow gracefully
-                        if (value < prevValue) {
-                            value = 0x110000; // Value above Unicode range but
-                            // within int
-                            // range
-                        }
-                        prevValue = value;
                         /*
                          * Consume as many characters as match the range of
                          * characters given above.
                          */
+                        assert value >= 0: "value must not become negative.";
                         if (c >= '0' && c <= '9') {
                             seenDigits = true;
-                            value *= 10;
-                            value += c - '0';
+                            // Avoid overflow
+                            if (value <= 0x10FFFF) {
+                                value *= 10;
+                                value += c - '0';
+                            }
                             continue;
                         } else if (c == ';') {
                             if (seenDigits) {
@@ -3277,12 +3748,12 @@ public class Tokenizer implements Locato
                                     cstart = pos + 1;
                                 }
                                 state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
-                                // FALL THROUGH continue stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break decimalloop;
                             } else {
                                 errNoDigitsInNCR();
-                                appendStrBuf(';');
-                                emitOrAppendStrBuf(returnState);
+                                appendCharRefBuf(';');
+                                emitOrAppendCharRefBuf(returnState);
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos + 1;
                                 }
@@ -3296,71 +3767,76 @@ public class Tokenizer implements Locato
                              * NUMBER SIGN character and, if appropriate, the X
                              * character). This is a parse error; nothing is
                              * returned.
-                             * 
+                             *
                              * Otherwise, if the next character is a U+003B
                              * SEMICOLON, consume that too. If it isn't, there
                              * is a parse error.
                              */
                             if (!seenDigits) {
                                 errNoDigitsInNCR();
-                                emitOrAppendStrBuf(returnState);
+                                emitOrAppendCharRefBuf(returnState);
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos;
                                 }
-                                state = transition(state, returnState, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                             } else {
                                 errCharRefLacksSemicolon();
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos;
                                 }
-                                state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
                                 reconsume = true;
-                                // FALL THROUGH continue stateloop;
+                                state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break decimalloop;
                             }
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case HANDLE_NCR_VALUE:
                     // WARNING previous state sets reconsume
+                    // We are not going to emit the contents of charRefBuf.
+                    charRefBufLen = 0;
                     // XXX inline this case if the method size can take it
                     handleNcrValue(returnState);
                     state = transition(state, returnState, reconsume, pos);
                     continue stateloop;
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case HEX_NCR_LOOP:
                     for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
-                        // Deal with overflow gracefully
-                        if (value < prevValue) {
-                            value = 0x110000; // Value above Unicode range but
-                            // within int
-                            // range
-                        }
-                        prevValue = value;
                         /*
                          * Consume as many characters as match the range of
                          * characters given above.
                          */
+                        assert value >= 0: "value must not become negative.";
                         if (c >= '0' && c <= '9') {
                             seenDigits = true;
-                            value *= 16;
-                            value += c - '0';
+                            // Avoid overflow
+                            if (value <= 0x10FFFF) {
+                                value *= 16;
+                                value += c - '0';
+                            }
                             continue;
                         } else if (c >= 'A' && c <= 'F') {
                             seenDigits = true;
-                            value *= 16;
-                            value += c - 'A' + 10;
+                            // Avoid overflow
+                            if (value <= 0x10FFFF) {
+                                value *= 16;
+                                value += c - 'A' + 10;
+                            }
                             continue;
                         } else if (c >= 'a' && c <= 'f') {
                             seenDigits = true;
-                            value *= 16;
-                            value += c - 'a' + 10;
+                            // Avoid overflow
+                            if (value <= 0x10FFFF) {
+                                value *= 16;
+                                value += c - 'a' + 10;
+                            }
                             continue;
                         } else if (c == ';') {
                             if (seenDigits) {
@@ -3371,8 +3847,8 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                             } else {
                                 errNoDigitsInNCR();
-                                appendStrBuf(';');
-                                emitOrAppendStrBuf(returnState);
+                                appendCharRefBuf(';');
+                                emitOrAppendCharRefBuf(returnState);
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos + 1;
                                 }
@@ -3386,32 +3862,32 @@ public class Tokenizer implements Locato
                              * NUMBER SIGN character and, if appropriate, the X
                              * character). This is a parse error; nothing is
                              * returned.
-                             * 
+                             *
                              * Otherwise, if the next character is a U+003B
                              * SEMICOLON, consume that too. If it isn't, there
                              * is a parse error.
                              */
                             if (!seenDigits) {
                                 errNoDigitsInNCR();
-                                emitOrAppendStrBuf(returnState);
+                                emitOrAppendCharRefBuf(returnState);
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos;
                                 }
-                                state = transition(state, returnState, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                             } else {
                                 errCharRefLacksSemicolon();
                                 if ((returnState & DATA_AND_RCDATA_MASK) == 0) {
                                     cstart = pos;
                                 }
-                                state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.HANDLE_NCR_VALUE, reconsume, pos);
                                 continue stateloop;
                             }
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case PLAINTEXT:
                     plaintextloop: for (;;) {
                         if (reconsume) {
@@ -3431,6 +3907,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -3440,7 +3917,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case CLOSE_TAG_OPEN:
                     if (++pos == endPos) {
                         break stateloop;
@@ -3468,7 +3945,8 @@ public class Tokenizer implements Locato
                             /*
                              * Switch to the bogus comment state.
                              */
-                            clearLongStrBufAndAppend('\n');
+                            clearStrBufBeforeUse();
+                            appendStrBuf('\n');
                             state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                             break stateloop;
                         case '\n':
@@ -3478,12 +3956,13 @@ public class Tokenizer implements Locato
                             /*
                              * Switch to the bogus comment state.
                              */
-                            clearLongStrBufAndAppend('\n');
+                            clearStrBufBeforeUse();
+                            appendStrBuf(c);
                             state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                             continue stateloop;
                         case '\u0000':
                             c = '\uFFFD';
-                            // fall thru
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         default:
                             if (c >= 'A' && c <= 'Z') {
                                 c += 0x20;
@@ -3498,7 +3977,9 @@ public class Tokenizer implements Locato
                                 /*
                                  * set its tag name to the input character,
                                  */
-                                clearStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
+                                containsHyphen = false;
                                 /*
                                  * then switch to the tag name state. (Don't
                                  * emit the token yet; further details will be
@@ -3512,12 +3993,13 @@ public class Tokenizer implements Locato
                                 /*
                                  * Switch to the bogus comment state.
                                  */
-                                clearLongStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                             }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case RCDATA:
                     rcdataloop: for (;;) {
                         if (reconsume) {
@@ -3535,8 +4017,9 @@ public class Tokenizer implements Locato
                                  * reference in RCDATA state.
                                  */
                                 flushChars(buf, pos);
-                                clearStrBufAndAppend(c);
-                                additional = '\u0000';
+                                assert charRefBufLen == 0: "charRefBufLen not reset after previous use!";
+                                appendCharRefBuf(c);
+                                setAdditionalAndRememberAmpersandLocation('\u0000');
                                 returnState = state;
                                 state = transition(state, Tokenizer.CONSUME_CHARACTER_REFERENCE, reconsume, pos);
                                 continue stateloop;
@@ -3558,6 +4041,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Emit the current input character as a
@@ -3566,7 +4050,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case RAWTEXT:
                     rawtextloop: for (;;) {
                         if (reconsume) {
@@ -3587,8 +4071,8 @@ public class Tokenizer implements Locato
 
                                 returnState = state;
                                 state = transition(state, Tokenizer.RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break rawtextloop;
-                            // FALL THRU continue stateloop;
                             case '\u0000':
                                 emitReplacementCharacter(buf, pos);
                                 continue;
@@ -3597,6 +4081,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Emit the current input character as a
@@ -3605,7 +4090,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // XXX fallthru don't reorder
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case RAWTEXT_RCDATA_LESS_THAN_SIGN:
                     rawtextrcdatalessthansignloop: for (;;) {
                         if (++pos == endPos) {
@@ -3620,10 +4105,10 @@ public class Tokenizer implements Locato
                                  * data end tag open state.
                                  */
                                 index = 0;
-                                clearStrBuf();
+                                clearStrBufBeforeUse();
                                 state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break rawtextrcdatalessthansignloop;
-                            // FALL THRU continue stateloop;
                             default:
                                 /*
                                  * Otherwise, emit a U+003C LESS-THAN SIGN
@@ -3635,12 +4120,12 @@ public class Tokenizer implements Locato
                                  * the data state.
                                  */
                                 cstart = pos;
-                                state = transition(state, returnState, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // XXX fall thru. don't reorder.
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case NON_DATA_END_TAG_NAME:
                     for (;;) {
                         if (++pos == endPos) {
@@ -3649,11 +4134,17 @@ public class Tokenizer implements Locato
                         c = checkChar(buf, pos);
                         /*
                          * ASSERT! when entering this state, set index to 0 and
-                         * call clearStrBuf() assert (contentModelElement !=
-                         * null); Let's implement the above without lookahead.
-                         * strBuf is the 'temporary buffer'.
+                         * call clearStrBufBeforeUse(); Let's implement the above
+                         * without lookahead. strBuf is the 'temporary buffer'.
                          */
-                        if (index < endTagExpectationAsArray.length) {
+                        if (endTagExpectationAsArray == null) {
+                            tokenHandler.characters(Tokenizer.LT_SOLIDUS,
+                                    0, 2);
+                            cstart = pos;
+                            reconsume = true;
+                            state = transition(state, returnState, reconsume, pos);
+                            continue stateloop;
+                        } else if (index < endTagExpectationAsArray.length) {
                             char e = endTagExpectationAsArray[index];
                             char folded = c;
                             if (c >= 'A' && c <= 'Z') {
@@ -3667,8 +4158,8 @@ public class Tokenizer implements Locato
                                         0, 2);
                                 emitStrBuf();
                                 cstart = pos;
-                                state = transition(state, returnState, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, returnState, reconsume, pos);
                                 continue stateloop;
                             }
                             appendStrBuf(c);
@@ -3682,11 +4173,12 @@ public class Tokenizer implements Locato
                             switch (c) {
                                 case '\r':
                                     silentCarriageReturn();
+                                    clearStrBufAfterUse(); // strBuf not used
                                     state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                                     break stateloop;
                                 case '\n':
                                     silentLineFeed();
-                                    // fall thru
+                                    // CPPONLY: MOZ_FALLTHROUGH;
                                 case ' ':
                                 case '\t':
                                 case '\u000C':
@@ -3697,6 +4189,7 @@ public class Tokenizer implements Locato
                                      * appropriate end tag token, then switch to
                                      * the before attribute name state.
                                      */
+                                    clearStrBufAfterUse(); // strBuf not used
                                     state = transition(state, Tokenizer.BEFORE_ATTRIBUTE_NAME, reconsume, pos);
                                     continue stateloop;
                                 case '/':
@@ -3706,6 +4199,7 @@ public class Tokenizer implements Locato
                                      * then switch to the self-closing start tag
                                      * state.
                                      */
+                                    clearStrBufAfterUse(); // strBuf not used
                                     state = transition(state, Tokenizer.SELF_CLOSING_START_TAG, reconsume, pos);
                                     continue stateloop;
                                 case '>':
@@ -3715,6 +4209,7 @@ public class Tokenizer implements Locato
                                      * end tag token, then emit the current tag
                                      * token and switch to the data state.
                                      */
+                                    clearStrBufAfterUse(); // strBuf not used
                                     state = transition(state, emitCurrentTagToken(false, pos), reconsume, pos);
                                     if (shouldSuspend) {
                                         break stateloop;
@@ -3736,18 +4231,15 @@ public class Tokenizer implements Locato
                                     tokenHandler.characters(
                                             Tokenizer.LT_SOLIDUS, 0, 2);
                                     emitStrBuf();
-                                    if (c == '\u0000') {
-                                        emitReplacementCharacter(buf, pos);
-                                    } else {
-                                        cstart = pos; // don't drop the
-                                        // character
-                                    }
+                                    cstart = pos; // don't drop the
+                                                  // character
+                                    reconsume = true;
                                     state = transition(state, returnState, reconsume, pos);
                                     continue stateloop;
                             }
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                     // BEGIN HOTSPOT WORKAROUND
                 case BOGUS_COMMENT:
                     boguscommentloop: for (;;) {
@@ -3771,9 +4263,9 @@ public class Tokenizer implements Locato
                          * character (i.e. up to the character just before the
                          * U+003E or EOF character). (If the comment was started
                          * by the end of the file (EOF), the token is empty.)
-                         * 
+                         *
                          * Switch to the data state.
-                         * 
+                         *
                          * If the end of the file was reached, reconsume the EOF
                          * character.
                          */
@@ -3781,26 +4273,30 @@ public class Tokenizer implements Locato
                             case '>':
                                 emitComment(0, pos);
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '-':
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.BOGUS_COMMENT_HYPHEN, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break boguscommentloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BOGUS_COMMENT_HYPHEN:
                     boguscommenthyphenloop: for (;;) {
                         if (++pos == endPos) {
@@ -3814,28 +4310,31 @@ public class Tokenizer implements Locato
                                 // ]NOCPP]
                                 emitComment(0, pos);
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '-':
                                 appendSecondHyphenToBogusComment();
                                 continue boguscommenthyphenloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case SCRIPT_DATA:
                     scriptdataloop: for (;;) {
                         if (reconsume) {
@@ -3855,8 +4354,8 @@ public class Tokenizer implements Locato
                                 flushChars(buf, pos);
                                 returnState = state;
                                 state = transition(state, Tokenizer.SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
-                                break scriptdataloop; // FALL THRU continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break scriptdataloop;
                             case '\u0000':
                                 emitReplacementCharacter(buf, pos);
                                 continue;
@@ -3865,6 +4364,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -3874,7 +4374,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_LESS_THAN_SIGN:
                     scriptdatalessthansignloop: for (;;) {
                         if (++pos == endPos) {
@@ -3889,16 +4389,15 @@ public class Tokenizer implements Locato
                                  * data end tag open state.
                                  */
                                 index = 0;
-                                clearStrBuf();
+                                clearStrBufBeforeUse();
                                 state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
                                 continue stateloop;
                             case '!':
                                 tokenHandler.characters(Tokenizer.LT_GT, 0, 1);
                                 cstart = pos;
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START, reconsume, pos);
-                                break scriptdatalessthansignloop; // FALL THRU
-                            // continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break scriptdatalessthansignloop;
                             default:
                                 /*
                                  * Otherwise, emit a U+003C LESS-THAN SIGN
@@ -3910,12 +4409,12 @@ public class Tokenizer implements Locato
                                  * the data state.
                                  */
                                 cstart = pos;
-                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPE_START:
                     scriptdataescapestartloop: for (;;) {
                         if (++pos == endPos) {
@@ -3933,20 +4432,19 @@ public class Tokenizer implements Locato
                                  * script data escape start dash state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPE_START_DASH, reconsume, pos);
-                                break scriptdataescapestartloop; // FALL THRU
-                            // continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break scriptdataescapestartloop;
                             default:
                                 /*
                                  * Anything else Reconsume the current input
                                  * character in the script data state.
                                  */
-                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPE_START_DASH:
                     scriptdataescapestartdashloop: for (;;) {
                         if (++pos == endPos) {
@@ -3964,19 +4462,19 @@ public class Tokenizer implements Locato
                                  * script data escaped dash dash state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdataescapestartdashloop;
-                            // continue stateloop;
                             default:
                                 /*
                                  * Anything else Reconsume the current input
                                  * character in the script data state.
                                  */
-                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.SCRIPT_DATA, reconsume, pos);
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPED_DASH_DASH:
                     scriptdataescapeddashdashloop: for (;;) {
                         if (++pos == endPos) {
@@ -4020,6 +4518,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4027,11 +4526,11 @@ public class Tokenizer implements Locato
                                  * script data escaped state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdataescapeddashdashloop;
-                            // continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPED:
                     scriptdataescapedloop: for (;;) {
                         if (reconsume) {
@@ -4053,9 +4552,8 @@ public class Tokenizer implements Locato
                                  * script data escaped dash state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_DASH, reconsume, pos);
-                                break scriptdataescapedloop; // FALL THRU
-                            // continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break scriptdataescapedloop;
                             case '<':
                                 /*
                                  * U+003C LESS-THAN SIGN (<) Switch to the
@@ -4072,6 +4570,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4081,7 +4580,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPED_DASH:
                     scriptdataescapeddashloop: for (;;) {
                         if (++pos == endPos) {
@@ -4107,8 +4606,8 @@ public class Tokenizer implements Locato
                                  */
                                 flushChars(buf, pos);
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdataescapeddashloop;
-                            // continue stateloop;
                             case '\u0000':
                                 emitReplacementCharacter(buf, pos);
                                 state = transition(state, Tokenizer.SCRIPT_DATA_ESCAPED, reconsume, pos);
@@ -4119,6 +4618,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4129,7 +4629,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
                     scriptdataescapedlessthanloop: for (;;) {
                         if (++pos == endPos) {
@@ -4147,7 +4647,7 @@ public class Tokenizer implements Locato
                                  * data escaped end tag open state.
                                  */
                                 index = 0;
-                                clearStrBuf();
+                                clearStrBufBeforeUse();
                                 returnState = Tokenizer.SCRIPT_DATA_ESCAPED;
                                 state = transition(state, Tokenizer.NON_DATA_END_TAG_NAME, reconsume, pos);
                                 continue stateloop;
@@ -4171,8 +4671,8 @@ public class Tokenizer implements Locato
                                  * escape start state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdataescapedlessthanloop;
-                            // continue stateloop;
                             default:
                                 /*
                                  * Anything else Emit a U+003C LESS-THAN SIGN
@@ -4187,14 +4687,14 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
                     scriptdatadoubleescapestartloop: for (;;) {
                         if (++pos == endPos) {
                             break stateloop;
                         }
                         c = checkChar(buf, pos);
-                        assert (index > 0);
+                        assert index > 0;
                         if (index < 6) { // SCRIPT_ARR.length
                             char folded = c;
                             if (c >= 'A' && c <= 'Z') {
@@ -4215,6 +4715,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4230,8 +4731,8 @@ public class Tokenizer implements Locato
                                  * script data double escaped state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdatadoubleescapestartloop;
-                            // continue stateloop;
                             default:
                                 /*
                                  * Anything else Reconsume the current input
@@ -4242,7 +4743,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPED:
                     scriptdatadoubleescapedloop: for (;;) {
                         if (reconsume) {
@@ -4264,9 +4765,8 @@ public class Tokenizer implements Locato
                                  * script data double escaped dash state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume, pos);
-                                break scriptdatadoubleescapedloop; // FALL THRU
-                            // continue
-                            // stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break scriptdatadoubleescapedloop;
                             case '<':
                                 /*
                                  * U+003C LESS-THAN SIGN (<) Emit a U+003C
@@ -4284,6 +4784,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4293,7 +4794,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
                     scriptdatadoubleescapeddashloop: for (;;) {
                         if (++pos == endPos) {
@@ -4311,8 +4812,8 @@ public class Tokenizer implements Locato
                                  * script data double escaped dash dash state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdatadoubleescapeddashloop;
-                            // continue stateloop;
                             case '<':
                                 /*
                                  * U+003C LESS-THAN SIGN (<) Emit a U+003C
@@ -4332,6 +4833,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4342,7 +4844,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
                     scriptdatadoubleescapeddashdashloop: for (;;) {
                         if (++pos == endPos) {
@@ -4368,6 +4870,7 @@ public class Tokenizer implements Locato
                                  * state.
                                  */
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdatadoubleescapeddashdashloop;
                             case '>':
                                 /*
@@ -4387,6 +4890,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Emit the current input
@@ -4397,7 +4901,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
                     scriptdatadoubleescapedlessthanloop: for (;;) {
                         if (++pos == endPos) {
@@ -4417,6 +4921,7 @@ public class Tokenizer implements Locato
                                  */
                                 index = 0;
                                 state = transition(state, Tokenizer.SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break scriptdatadoubleescapedlessthanloop;
                             default:
                                 /*
@@ -4429,7 +4934,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case SCRIPT_DATA_DOUBLE_ESCAPE_END:
                     scriptdatadoubleescapeendloop: for (;;) {
                         if (++pos == endPos) {
@@ -4456,6 +4961,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4482,7 +4988,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case MARKUP_DECLARATION_OCTYPE:
                     markupdeclarationdoctypeloop: for (;;) {
                         if (++pos == endPos) {
@@ -4495,23 +5001,23 @@ public class Tokenizer implements Locato
                                 folded += 0x20;
                             }
                             if (folded == Tokenizer.OCTYPE[index]) {
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                             } else {
                                 errBogusComment();
-                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_COMMENT, reconsume, pos);
                                 continue stateloop;
                             }
                             index++;
                             continue;
                         } else {
-                            state = transition(state, Tokenizer.DOCTYPE, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, Tokenizer.DOCTYPE, reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
                             break markupdeclarationdoctypeloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE:
                     doctypeloop: for (;;) {
                         if (reconsume) {
@@ -4533,7 +5039,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4543,8 +5049,8 @@ public class Tokenizer implements Locato
                                  * Switch to the before DOCTYPE name state.
                                  */
                                 state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break doctypeloop;
-                            // continue stateloop;
                             default:
                                 /*
                                  * Anything else Parse error.
@@ -4554,13 +5060,13 @@ public class Tokenizer implements Locato
                                  * Reconsume the current character in the before
                                  * DOCTYPE name state.
                                  */
-                                state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BEFORE_DOCTYPE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break doctypeloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_DOCTYPE_NAME:
                     beforedoctypenameloop: for (;;) {
                         if (reconsume) {
@@ -4580,7 +5086,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4608,10 +5114,13 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 if (c >= 'A' && c <= 'Z') {
                                     /*
@@ -4629,16 +5138,17 @@ public class Tokenizer implements Locato
                                  * Set the token's name name to the current
                                  * input character.
                                  */
-                                clearStrBufAndAppend(c);
+                                clearStrBufBeforeUse();
+                                appendStrBuf(c);
                                 /*
                                  * Switch to the DOCTYPE name state.
                                  */
                                 state = transition(state, Tokenizer.DOCTYPE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break beforedoctypenameloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE_NAME:
                     doctypenameloop: for (;;) {
                         if (++pos == endPos) {
@@ -4656,7 +5166,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4667,8 +5177,8 @@ public class Tokenizer implements Locato
                                  */
                                 strBufToDoctypeName();
                                 state = transition(state, Tokenizer.AFTER_DOCTYPE_NAME, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break doctypenameloop;
-                            // continue stateloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Emit the current
@@ -4680,10 +5190,13 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * U+0041 LATIN CAPITAL LETTER A through to
@@ -4707,7 +5220,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_DOCTYPE_NAME:
                     afterdoctypenameloop: for (;;) {
                         if (++pos == endPos) {
@@ -4723,7 +5236,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4743,13 +5256,16 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case 'p':
                             case 'P':
                                 index = 0;
                                 state = transition(state, Tokenizer.DOCTYPE_UBLIC, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterdoctypenameloop;
-                            // continue stateloop;
                             case 's':
                             case 'S':
                                 index = 0;
@@ -4773,7 +5289,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE_UBLIC:
                     doctypeublicloop: for (;;) {
                         if (++pos == endPos) {
@@ -4794,20 +5310,20 @@ public class Tokenizer implements Locato
                             if (folded != Tokenizer.UBLIC[index]) {
                                 bogusDoctype();
                                 // forceQuirks = true;
-                                state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
                                 continue stateloop;
                             }
                             index++;
                             continue;
                         } else {
-                            state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
                             break doctypeublicloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
                     afterdoctypepublickeywordloop: for (;;) {
                         if (reconsume) {
@@ -4828,7 +5344,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4839,8 +5355,8 @@ public class Tokenizer implements Locato
                                  * identifier state.
                                  */
                                 state = transition(state, Tokenizer.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterdoctypepublickeywordloop;
-                            // FALL THROUGH continue stateloop
                             case '"':
                                 /*
                                  * U+0022 QUOTATION MARK (") Parse Error.
@@ -4850,7 +5366,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's public identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (double-quoted) state.
@@ -4866,7 +5382,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's public identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (single-quoted) state.
@@ -4889,6 +5405,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             default:
                                 bogusDoctype();
@@ -4904,7 +5423,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
                     beforedoctypepublicidentifierloop: for (;;) {
                         if (++pos == endPos) {
@@ -4920,7 +5439,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -4937,21 +5456,21 @@ public class Tokenizer implements Locato
                                  * token's public identifier to the empty string
                                  * (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (double-quoted) state.
                                  */
                                 state = transition(state, Tokenizer.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break beforedoctypepublicidentifierloop;
-                            // continue stateloop;
                             case '\'':
                                 /*
                                  * U+0027 APOSTROPHE (') Set the DOCTYPE token's
                                  * public identifier to the empty string (not
                                  * missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (single-quoted) state.
@@ -4974,6 +5493,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             default:
                                 bogusDoctype();
@@ -4989,7 +5511,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
                     doctypepublicidentifierdoublequotedloop: for (;;) {
                         if (++pos == endPos) {
@@ -5005,10 +5527,10 @@ public class Tokenizer implements Locato
                                  * U+0022 QUOTATION MARK (") Switch to the after
                                  * DOCTYPE public identifier state.
                                  */
-                                publicIdentifier = longStrBufToString();
+                                publicIdentifier = strBufToString();
                                 state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break doctypepublicidentifierdoublequotedloop;
-                            // continue stateloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Parse error.
@@ -5022,29 +5544,32 @@ public class Tokenizer implements Locato
                                 /*
                                  * Emit that DOCTYPE token.
                                  */
-                                publicIdentifier = longStrBufToString();
+                                publicIdentifier = strBufToString();
                                 emitDoctypeToken(pos);
                                 /*
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current DOCTYPE token's
                                  * public identifier.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the DOCTYPE public identifier
                                  * (double-quoted) state.
@@ -5052,7 +5577,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
                     afterdoctypepublicidentifierloop: for (;;) {
                         if (++pos == endPos) {
@@ -5069,7 +5594,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -5080,8 +5605,8 @@ public class Tokenizer implements Locato
                                  * system identifiers state.
                                  */
                                 state = transition(state, Tokenizer.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterdoctypepublicidentifierloop;
-                            // continue stateloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Emit the current
@@ -5092,6 +5617,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '"':
                                 /*
@@ -5102,7 +5630,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's system identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (double-quoted) state.
@@ -5118,7 +5646,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's system identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (single-quoted) state.
@@ -5139,7 +5667,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
                     betweendoctypepublicandsystemidentifiersloop: for (;;) {
                         if (++pos == endPos) {
@@ -5155,7 +5683,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -5176,6 +5704,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '"':
                                 /*
@@ -5183,21 +5714,21 @@ public class Tokenizer implements Locato
                                  * token's system identifier to the empty string
                                  * (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (double-quoted) state.
                                  */
                                 state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break betweendoctypepublicandsystemidentifiersloop;
-                            // continue stateloop;
                             case '\'':
                                 /*
                                  * U+0027 APOSTROPHE (') Set the DOCTYPE token's
                                  * system identifier to the empty string (not
                                  * missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (single-quoted) state.
@@ -5218,7 +5749,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
                     doctypesystemidentifierdoublequotedloop: for (;;) {
                         if (++pos == endPos) {
@@ -5234,9 +5765,10 @@ public class Tokenizer implements Locato
                                  * U+0022 QUOTATION MARK (") Switch to the after
                                  * DOCTYPE system identifier state.
                                  */
-                                systemIdentifier = longStrBufToString();
+                                systemIdentifier = strBufToString();
                                 state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
-                                continue stateloop;
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break doctypesystemidentifierdoublequotedloop;
                             case '>':
                                 /*
                                  * U+003E GREATER-THAN SIGN (>) Parse error.
@@ -5250,29 +5782,32 @@ public class Tokenizer implements Locato
                                 /*
                                  * Emit that DOCTYPE token.
                                  */
-                                systemIdentifier = longStrBufToString();
+                                systemIdentifier = strBufToString();
                                 emitDoctypeToken(pos);
                                 /*
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current DOCTYPE token's
                                  * system identifier.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the DOCTYPE system identifier
                                  * (double-quoted) state.
@@ -5280,7 +5815,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
                     afterdoctypesystemidentifierloop: for (;;) {
                         if (++pos == endPos) {
@@ -5296,7 +5831,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -5316,6 +5851,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             default:
                                 /*
@@ -5325,11 +5863,11 @@ public class Tokenizer implements Locato
                                  */
                                 bogusDoctypeWithoutQuirks();
                                 state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterdoctypesystemidentifierloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BOGUS_DOCTYPE:
                     for (;;) {
                         if (reconsume) {
@@ -5354,13 +5892,16 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\r':
                                 silentCarriageReturn();
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Stay in the bogus DOCTYPE
@@ -5369,7 +5910,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case DOCTYPE_YSTEM:
                     doctypeystemloop: for (;;) {
                         if (++pos == endPos) {
@@ -5390,20 +5931,20 @@ public class Tokenizer implements Locato
                             }
                             if (folded != Tokenizer.YSTEM[index]) {
                                 bogusDoctype();
-                                state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
                                 reconsume = true;
+                                state = transition(state, Tokenizer.BOGUS_DOCTYPE, reconsume, pos);
                                 continue stateloop;
                             }
                             index++;
                             continue stateloop;
                         } else {
-                            state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
                             reconsume = true;
+                            state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
+                            // `break` optimizes; `continue stateloop;` would be valid
                             break doctypeystemloop;
-                            // continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
                     afterdoctypesystemkeywordloop: for (;;) {
                         if (reconsume) {
@@ -5424,7 +5965,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -5435,8 +5976,8 @@ public class Tokenizer implements Locato
                                  * identifier state.
                                  */
                                 state = transition(state, Tokenizer.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break afterdoctypesystemkeywordloop;
-                            // FALL THROUGH continue stateloop
                             case '"':
                                 /*
                                  * U+0022 QUOTATION MARK (") Parse Error.
@@ -5446,7 +5987,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's system identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (double-quoted) state.
@@ -5462,7 +6003,7 @@ public class Tokenizer implements Locato
                                  * Set the DOCTYPE token's public identifier to
                                  * the empty string (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE public identifier
                                  * (single-quoted) state.
@@ -5485,6 +6026,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             default:
                                 bogusDoctype();
@@ -5500,7 +6044,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
                     beforedoctypesystemidentifierloop: for (;;) {
                         if (++pos == endPos) {
@@ -5516,7 +6060,7 @@ public class Tokenizer implements Locato
                                 break stateloop;
                             case '\n':
                                 silentLineFeed();
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case ' ':
                             case '\t':
                             case '\u000C':
@@ -5533,7 +6077,7 @@ public class Tokenizer implements Locato
                                  * token's system identifier to the empty string
                                  * (not missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (double-quoted) state.
@@ -5546,14 +6090,14 @@ public class Tokenizer implements Locato
                                  * system identifier to the empty string (not
                                  * missing),
                                  */
-                                clearLongStrBuf();
+                                clearStrBufBeforeUse();
                                 /*
                                  * then switch to the DOCTYPE system identifier
                                  * (single-quoted) state.
                                  */
                                 state = transition(state, Tokenizer.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
                                 break beforedoctypesystemidentifierloop;
-                            // continue stateloop;
                             case '>':
                                 /* U+003E GREATER-THAN SIGN (>) Parse error. */
                                 errExpectedSystemId();
@@ -5570,6 +6114,9 @@ public class Tokenizer implements Locato
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             default:
                                 bogusDoctype();
@@ -5585,7 +6132,7 @@ public class Tokenizer implements Locato
                                 continue stateloop;
                         }
                     }
-                    // FALLTHRU DON'T REORDER
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
                     for (;;) {
                         if (++pos == endPos) {
@@ -5601,7 +6148,7 @@ public class Tokenizer implements Locato
                                  * U+0027 APOSTROPHE (') Switch to the after
                                  * DOCTYPE system identifier state.
                                  */
-                                systemIdentifier = longStrBufToString();
+                                systemIdentifier = strBufToString();
                                 state = transition(state, Tokenizer.AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
                                 continue stateloop;
                             case '>':
@@ -5614,29 +6161,32 @@ public class Tokenizer implements Locato
                                 /*
                                  * Emit that DOCTYPE token.
                                  */
-                                systemIdentifier = longStrBufToString();
+                                systemIdentifier = strBufToString();
                                 emitDoctypeToken(pos);
                                 /*
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current DOCTYPE token's
                                  * system identifier.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the DOCTYPE system identifier
                                  * (double-quoted) state.
@@ -5644,7 +6194,7 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
-                    // XXX reorder point
+                    // no fallthrough, reordering opportunity
                 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
                     for (;;) {
                         if (++pos == endPos) {
@@ -5660,7 +6210,7 @@ public class Tokenizer implements Locato
                                  * U+0027 APOSTROPHE (') Switch to the after
                                  * DOCTYPE public identifier state.
                                  */
-                                publicIdentifier = longStrBufToString();
+                                publicIdentifier = strBufToString();
                                 state = transition(state, Tokenizer.AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
                                 continue stateloop;
                             case '>':
@@ -5673,29 +6223,32 @@ public class Tokenizer implements Locato
                                 /*
                                  * Emit that DOCTYPE token.
                                  */
-                                publicIdentifier = longStrBufToString();
+                                publicIdentifier = strBufToString();
                                 emitDoctypeToken(pos);
                                 /*
                                  * Switch to the data state.
                                  */
                                 state = transition(state, Tokenizer.DATA, reconsume, pos);
+                                if (shouldSuspend) {
+                                    break stateloop;
+                                }
                                 continue stateloop;
                             case '\r':
-                                appendLongStrBufCarriageReturn();
+                                appendStrBufCarriageReturn();
                                 break stateloop;
                             case '\n':
-                                appendLongStrBufLineFeed();
+                                appendStrBufLineFeed();
                                 continue;
                             case '\u0000':
                                 c = '\uFFFD';
-                                // fall thru
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             default:
                                 /*
                                  * Anything else Append the current input
                                  * character to the current DOCTYPE token's
                                  * public identifier.
                                  */
-                                appendLongStrBuf(c);
+                                appendStrBuf(c);
                                 /*
                                  * Stay in the DOCTYPE public identifier
                                  * (single-quoted) state.
@@ -5703,6 +6256,59 @@ public class Tokenizer implements Locato
                                 continue;
                         }
                     }
+                    // no fallthrough, reordering opportunity
+                case PROCESSING_INSTRUCTION:
+                    processinginstructionloop: for (;;) {
+                        if (++pos == endPos) {
+                            break stateloop;
+                        }
+                        c = checkChar(buf, pos);
+                        switch (c) {
+                            case '?':
+                                state = transition(
+                                        state,
+                                        Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK,
+                                        reconsume, pos);
+                                // `break` optimizes; `continue stateloop;` would be valid
+                                break processinginstructionloop;
+                            default:
+                                continue;
+                        }
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case PROCESSING_INSTRUCTION_QUESTION_MARK:
+                    if (++pos == endPos) {
+                        break stateloop;
+                    }
+                    c = checkChar(buf, pos);
+                    switch (c) {
+                        case '>':
+                            state = transition(state, Tokenizer.DATA,
+                                    reconsume, pos);
+                            // Processing instruction syntax goes through these
+                            // states only in Gecko's XML View Source--not in HTML
+                            // parsing in Java or in Gecko.
+                            // Since XML View Source doesn't use the
+                            // suspension-after-current-token facility, its extension
+                            // to processing-instruction states is strictly unnecessary
+                            // at the moment. However, if these states ever were to be
+                            // used together with the suspension-after-current-token
+                            // facility, these states would need to participate, since
+                            // suspension could be requested when only less-than has been
+                            // seen and we don't yet know if we end up here. Handling
+                            // the currently-unnecessary case in order to avoid leaving
+                            // a trap for future modification.
+                            suspendIfRequestedAfterCurrentNonTextToken();
+                            if (shouldSuspend) {
+                                break stateloop;
+                            }
+                            continue stateloop;
+                        default:
+                            state = transition(state,
+                                    Tokenizer.PROCESSING_INSTRUCTION,
+                                    reconsume, pos);
+                            continue stateloop;
+                    }
                     // END HOTSPOT WORKAROUND
             }
         }
@@ -5715,19 +6321,22 @@ public class Tokenizer implements Locato
         returnStateSave = returnState;
         return pos;
     }
-    
+
     // HOTSPOT WORKAROUND INSERTION POINT
-    
+
     // [NOCPP[
-    
+
     protected int transition(int from, int to, boolean reconsume, int pos) throws SAXException {
         return to;
     }
 
     // ]NOCPP]
-    
+
     private void initDoctypeFields() {
-        doctypeName = "";
+        // Discard the characters "DOCTYPE" accumulated as a potential bogus
+        // comment into strBuf.
+        clearStrBufAfterUse();
+        doctypeName = null;
         if (systemIdentifier != null) {
             Portability.releaseString(systemIdentifier);
             systemIdentifier = null;
@@ -5739,28 +6348,30 @@ public class Tokenizer implements Locato
         forceQuirks = false;
     }
 
-    @Inline private void adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn()
+    private void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
             throws SAXException {
         silentCarriageReturn();
-        adjustDoubleHyphenAndAppendToLongStrBufAndErr('\n');
+        adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
     }
 
-    @Inline private void adjustDoubleHyphenAndAppendToLongStrBufLineFeed()
+    private void adjustDoubleHyphenAndAppendToStrBufLineFeed()
             throws SAXException {
         silentLineFeed();
-        adjustDoubleHyphenAndAppendToLongStrBufAndErr('\n');
+        adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
     }
 
-    @Inline private void appendLongStrBufLineFeed() {
+    private void appendStrBufLineFeed() {
         silentLineFeed();
-        appendLongStrBuf('\n');
+        appendStrBuf('\n');
     }
 
-    @Inline private void appendLongStrBufCarriageReturn() {
+    private void appendStrBufCarriageReturn() {
         silentCarriageReturn();
-        appendLongStrBuf('\n');
+        appendStrBuf('\n');
     }
 
+    // [NOCPP[
+
     @Inline protected void silentCarriageReturn() {
         ++line;
         lastCR = true;
@@ -5770,6 +6381,8 @@ public class Tokenizer implements Locato
         ++line;
     }
 
+    // ]NOCPP]
+
     private void emitCarriageReturn(@NoLength char[] buf, int pos)
             throws SAXException {
         silentCarriageReturn();
@@ -5785,6 +6398,13 @@ public class Tokenizer implements Locato
         cstart = pos + 1;
     }
 
+    private void maybeEmitReplacementCharacter(@NoLength char[] buf, int pos)
+            throws SAXException {
+        flushChars(buf, pos);
+        tokenHandler.zeroOrReplacementCharacter();
+        cstart = pos + 1;
+    }
+
     private void emitPlaintextReplacementCharacter(@NoLength char[] buf, int pos)
             throws SAXException {
         flushChars(buf, pos);
@@ -5809,14 +6429,6 @@ public class Tokenizer implements Locato
         forceQuirks = false;
     }
 
-    private void emitOrAppendStrBuf(int returnState) throws SAXException {
-        if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
-            appendStrBufToLongStrBuf();
-        } else {
-            emitStrBuf();
-        }
-    }
-
     private void handleNcrValue(int returnState) throws SAXException {
         /*
          * If one or more characters match the range, then take them all and
@@ -6022,7 +6634,6 @@ public class Tokenizer implements Locato
                     break eofloop;
                 case MARKUP_DECLARATION_OPEN:
                     errBogusComment();
-                    clearLongStrBuf();
                     emitComment(0, 0);
                     break eofloop;
                 case MARKUP_DECLARATION_HYPHEN:
@@ -6040,7 +6651,7 @@ public class Tokenizer implements Locato
                          * Create a new DOCTYPE token. Set its force-quirks flag
                          * to on.
                          */
-                        doctypeName = "";
+                        doctypeName = null;
                         if (systemIdentifier != null) {
                             Portability.releaseString(systemIdentifier);
                             systemIdentifier = null;
@@ -6062,6 +6673,8 @@ public class Tokenizer implements Locato
                     break eofloop;
                 case COMMENT_START:
                 case COMMENT:
+                case COMMENT_LESSTHAN:
+                case COMMENT_LESSTHAN_BANG:
                     /*
                      * EOF Parse error.
                      */
@@ -6073,6 +6686,7 @@ public class Tokenizer implements Locato
                      */
                     break eofloop;
                 case COMMENT_END:
+                case COMMENT_LESSTHAN_BANG_DASH_DASH:
                     errEofInComment();
                     /* Emit the comment token. */
                     emitComment(2, 0);
@@ -6082,6 +6696,7 @@ public class Tokenizer implements Locato
                     break eofloop;
                 case COMMENT_END_DASH:
                 case COMMENT_START_DASH:
+                case COMMENT_LESSTHAN_BANG_DASH:
                     errEofInComment();
                     /* Emit the comment token. */
                     emitComment(1, 0);
@@ -6158,7 +6773,7 @@ public class Tokenizer implements Locato
                     /*
                      * Emit that DOCTYPE token.
                      */
-                    publicIdentifier = longStrBufToString();
+                    publicIdentifier = strBufToString();
                     emitDoctypeToken(0);
                     /*
                      * Reconsume the EOF character in the data state.
@@ -6191,7 +6806,7 @@ public class Tokenizer implements Locato
                     /*
                      * Emit that DOCTYPE token.
                      */
-                    systemIdentifier = longStrBufToString();
+                    systemIdentifier = strBufToString();
                     emitDoctypeToken(0);
                     /*
                      * Reconsume the EOF character in the data state.
@@ -6233,18 +6848,17 @@ public class Tokenizer implements Locato
                      * This section defines how to consume an entity. This
                      * definition is used when parsing entities in text and in
                      * attributes.
-                     * 
+                     *
                      * The behavior depends on the identity of the next
                      * character (the one immediately after the U+0026 AMPERSAND
                      * character):
                      */
 
-                    emitOrAppendStrBuf(returnState);
+                    emitOrAppendCharRefBuf(returnState);
                     state = returnState;
                     continue;
                 case CHARACTER_REFERENCE_HILO_LOOKUP:
-                    errNoNamedCharacterMatch();
-                    emitOrAppendStrBuf(returnState);
+                    emitOrAppendCharRefBuf(returnState);
                     state = returnState;
                     continue;
                 case CHARACTER_REFERENCE_TAIL:
@@ -6280,7 +6894,7 @@ public class Tokenizer implements Locato
                             }
                             if (entCol == NamedCharacters.NAMES[lo].length()) {
                                 candidate = lo;
-                                strBufMark = strBufLen;
+                                charRefBufMark = charRefBufLen;
                                 lo++;
                             } else if (entCol > NamedCharacters.NAMES[lo].length()) {
                                 break outer;
@@ -6297,11 +6911,7 @@ public class Tokenizer implements Locato
                     }
 
                     if (candidate == -1) {
-                        /*
-                         * If no match can be made, then this is a parse error.
-                         */
-                        errNoNamedCharacterMatch();
-                        emitOrAppendStrBuf(returnState);
+                        emitOrAppendCharRefBuf(returnState);
                         state = returnState;
                         continue eofloop;
                     } else {
@@ -6319,10 +6929,10 @@ public class Tokenizer implements Locato
                                  * not a U+003B SEMICOLON (;),
                                  */
                                 char ch;
-                                if (strBufMark == strBufLen) {
+                                if (charRefBufMark == charRefBufLen) {
                                     ch = '\u0000';
                                 } else {
-                                    ch = strBuf[strBufMark];
+                                    ch = charRefBuf[charRefBufMark];
                                 }
                                 if ((ch >= '0' && ch <= '9')
                                         || (ch >= 'A' && ch <= 'Z')
@@ -6338,8 +6948,7 @@ public class Tokenizer implements Locato
                                      * after the U+0026 AMPERSAND (&) must be
                                      * unconsumed, and nothing is returned.
                                      */
-                                    errNoNamedCharacterMatch();
-                                    appendStrBufToLongStrBuf();
+                                    appendCharRefBufToStrBuf();
                                     state = returnState;
                                     continue eofloop;
                                 }
@@ -6369,16 +6978,16 @@ public class Tokenizer implements Locato
                             emitOrAppendTwo(val, returnState);
                         }
                         // this is so complicated!
-                        if (strBufMark < strBufLen) {
+                        if (charRefBufMark < charRefBufLen) {
                             if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
-                                for (int i = strBufMark; i < strBufLen; i++) {
-                                    appendLongStrBuf(strBuf[i]);
-                                }
+                                appendStrBuf(charRefBuf, charRefBufMark,
+                                        charRefBufLen - charRefBufMark);
                             } else {
-                                tokenHandler.characters(strBuf, strBufMark,
-                                        strBufLen - strBufMark);
+                                tokenHandler.characters(charRefBuf, charRefBufMark,
+                                        charRefBufLen - charRefBufMark);
                             }
                         }
+                        charRefBufLen = 0;
                         state = returnState;
                         continue eofloop;
                         /*
@@ -6397,13 +7006,13 @@ public class Tokenizer implements Locato
                      * characters (and unconsume the U+0023 NUMBER SIGN
                      * character and, if appropriate, the X character). This is
                      * a parse error; nothing is returned.
-                     * 
+                     *
                      * Otherwise, if the next character is a U+003B SEMICOLON,
                      * consume that too. If it isn't, there is a parse error.
                      */
                     if (!seenDigits) {
                         errNoDigitsInNCR();
-                        emitOrAppendStrBuf(returnState);
+                        emitOrAppendCharRefBuf(returnState);
                         state = returnState;
                         continue;
                     } else {
@@ -6432,7 +7041,23 @@ public class Tokenizer implements Locato
         return;
     }
 
+    /**
+     * Emits a doctype token.
+     *
+     * NOTE: The method may set <code>shouldSuspend</code>, so the caller
+     * must have this pattern after the state's <code>transition</code> call:
+     * <pre>
+     * if (shouldSuspend) {
+     *     break stateloop;
+     * }
+     * continue stateloop;
+     * </pre>
+     *
+     * @param pos
+     * @throws SAXException
+     */
     private void emitDoctypeToken(int pos) throws SAXException {
+        // CPPONLY: RememberGt(pos);
         cstart = pos + 1;
         tokenHandler.doctype(doctypeName, publicIdentifier, systemIdentifier,
                 forceQuirks);
@@ -6444,22 +7069,142 @@ public class Tokenizer implements Locato
         publicIdentifier = null;
         Portability.releaseString(systemIdentifier);
         systemIdentifier = null;
+        suspendIfRequestedAfterCurrentNonTextToken();
     }
 
-    @Inline protected char checkChar(@NoLength char[] buf, int pos)
-            throws SAXException {
-        return buf[pos];
+    /**
+     * If a previous call to <code>suspendAfterCurrentTokenIfNotInText()</code>
+     * happened in a non-text context, this method turns that deferred suspension
+     * request into an immediately-pending suspension request.
+     */
+    private void suspendIfRequestedAfterCurrentNonTextToken() {
+        if (suspendAfterCurrentNonTextToken) {
+            suspendAfterCurrentNonTextToken = false;
+            shouldSuspend = true;
+        }
     }
 
-    // [NOCPP[
+    // Making this private until the full Java implementation is done.
+    /**
+     * Request suspension after the current token if the tokenizer is currently
+     * in a non-text state (i.e. it's known that the next token will be a
+     * non-text token).
+     *
+     * Must not be called when <code>tokenizeBuffer()</code> is on the call
+     * stack.
+     */
+    @SuppressWarnings("unused") private void suspendAfterCurrentTokenIfNotInText() {
+        switch (stateSave) {
+            case DATA:
+            case RCDATA:
+            case SCRIPT_DATA:
+            case RAWTEXT:
+            case SCRIPT_DATA_ESCAPED:
+            case PLAINTEXT:
+            case NON_DATA_END_TAG_NAME: // We haven't yet committed to the next
+                                        // token being a non-text token, though
+                                        // it could be.
+            case SCRIPT_DATA_LESS_THAN_SIGN:
+            case SCRIPT_DATA_ESCAPE_START:
+            case SCRIPT_DATA_ESCAPE_START_DASH:
+            case SCRIPT_DATA_ESCAPED_DASH:
+            case SCRIPT_DATA_ESCAPED_DASH_DASH:
+            case RAWTEXT_RCDATA_LESS_THAN_SIGN:
+            case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
+            case SCRIPT_DATA_DOUBLE_ESCAPE_START:
+            case SCRIPT_DATA_DOUBLE_ESCAPED:
+            case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
+            case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
+            case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
+            case SCRIPT_DATA_DOUBLE_ESCAPE_END:
+                return;
+            case TAG_NAME:
+            case BEFORE_ATTRIBUTE_NAME:
+            case ATTRIBUTE_NAME:
+            case AFTER_ATTRIBUTE_NAME:
+            case BEFORE_ATTRIBUTE_VALUE:
+            case AFTER_ATTRIBUTE_VALUE_QUOTED:
+            case BOGUS_COMMENT:
+            case MARKUP_DECLARATION_OPEN:
+            case DOCTYPE:
+            case BEFORE_DOCTYPE_NAME:
+            case DOCTYPE_NAME:
+            case AFTER_DOCTYPE_NAME:
+            case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
+            case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
+            case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
+            case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
+            case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
+            case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
+            case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
+            case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
+            case BOGUS_DOCTYPE:
+            case COMMENT_START:
+            case COMMENT_START_DASH:
+            case COMMENT:
+            case COMMENT_END_DASH:
+            case COMMENT_END:
+            case COMMENT_END_BANG:
+            case TAG_OPEN:
+            case CLOSE_TAG_OPEN:
+            case MARKUP_DECLARATION_HYPHEN:
+            case MARKUP_DECLARATION_OCTYPE:
+            case DOCTYPE_UBLIC:
+            case DOCTYPE_YSTEM:
+            case AFTER_DOCTYPE_PUBLIC_KEYWORD:
+            case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
+            case AFTER_DOCTYPE_SYSTEM_KEYWORD:
+            case SELF_CLOSING_START_TAG:
+            case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
+            case ATTRIBUTE_VALUE_SINGLE_QUOTED:
+            case ATTRIBUTE_VALUE_UNQUOTED:
+            case BOGUS_COMMENT_HYPHEN:
+            case COMMENT_LESSTHAN:
+            case COMMENT_LESSTHAN_BANG:
+            case COMMENT_LESSTHAN_BANG_DASH:
+            case COMMENT_LESSTHAN_BANG_DASH_DASH:
+            case CDATA_START:
+            case CDATA_SECTION:
+            case CDATA_RSQB:
+            case CDATA_RSQB_RSQB:
+            case PROCESSING_INSTRUCTION:
+            case PROCESSING_INSTRUCTION_QUESTION_MARK:
+                break;
+            case CONSUME_CHARACTER_REFERENCE:
+            case CONSUME_NCR:
+            case CHARACTER_REFERENCE_TAIL:
+            case HEX_NCR_LOOP:
+            case DECIMAL_NRC_LOOP:
+            case HANDLE_NCR_VALUE:
+            case HANDLE_NCR_VALUE_RECONSUME:
+            case CHARACTER_REFERENCE_HILO_LOOKUP:
+                if (returnStateSave == DATA || returnStateSave == RCDATA) {
+                    return;
+                }
+                break;
+            default:
+                assert false : "Incomplete switch";
+                return;
+        }
+        suspendAfterCurrentNonTextToken = true;
+    }
 
+    // Making this private until the full Java implementation is done.
     /**
-     * Returns the alreadyComplainedAboutNonAscii.
-     * 
-     * @return the alreadyComplainedAboutNonAscii
+     * Queries if we are about to suspend after the current non-text token due to a request
+     * from <code>suspendAfterCurrentTokenIfNotInText()</code>.
+     * @return <code>true</code> iff <code>suspendAfterCurrentTokenIfNotInText()</code> was
+     * called in a non-text position and the then-current token has not been emitted yet.
      */
-    public boolean isAlreadyComplainedAboutNonAscii() {
-        return true;
+    @SuppressWarnings("unused") private boolean suspensionAfterCurrentNonTextTokenPending() {
+        return suspendAfterCurrentNonTextToken;
+    }
+
+    // [NOCPP[
+
+    @Inline protected char checkChar(@NoLength char[] buf, int pos)
+            throws SAXException {
+        return buf[pos];
     }
 
     // ]NOCPP]
@@ -6479,8 +7224,8 @@ public class Tokenizer implements Locato
     private void emitOrAppendTwo(@Const @NoLength char[] val, int returnState)
             throws SAXException {
         if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
-            appendLongStrBuf(val[0]);
-            appendLongStrBuf(val[1]);
+            appendStrBuf(val[0]);
+            appendStrBuf(val[1]);
         } else {
             tokenHandler.characters(val, 0, 2);
         }
@@ -6489,15 +7234,16 @@ public class Tokenizer implements Locato
     private void emitOrAppendOne(@Const @NoLength char[] val, int returnState)
             throws SAXException {
         if ((returnState & DATA_AND_RCDATA_MASK) != 0) {
-            appendLongStrBuf(val[0]);
+            appendStrBuf(val[0]);
         } else {
             tokenHandler.characters(val, 0, 1);
         }
     }
 
     public void end() throws SAXException {
-        strBuf = null;
-        longStrBuf = null;
+        if (!keepBuffer) {
+            strBuf = null;
+        }
         doctypeName = null;
         if (systemIdentifier != null) {
             Portability.releaseString(systemIdentifier);
@@ -6507,19 +7253,18 @@ public class Tokenizer implements Locato
             Portability.releaseString(publicIdentifier);
             publicIdentifier = null;
         }
-        if (tagName != null) {
-            tagName.release();
-            tagName = null;
-        }
-        if (attributeName != null) {
-            attributeName.release();
-            attributeName = null;
-        }
+        tagName = null;
+        nonInternedTagName.setNameForNonInterned(null
+                // CPPONLY: , false
+                );
+        attributeName = null;
+        // CPPONLY: nonInternedAttributeName.setNameForNonInterned(null);
         tokenHandler.endTokenization();
         if (attributes != null) {
-            attributes.clear(mappingLangToXmlLang);
-            Portability.delete(attributes);
+            // [NOCPP[
             attributes = null;
+            // ]NOCPP]
+            // CPPONLY: attributes.clear(mappingLangToXmlLang);
         }
     }
 
@@ -6528,14 +7273,14 @@ public class Tokenizer implements Locato
     }
 
     // [NOCPP[
-    
+
     public void becomeConfident() {
         confident = true;
     }
 
     /**
      * Returns the nextCharOnNewLine.
-     * 
+     *
      * @return the nextCharOnNewLine
      */
     public boolean isNextCharOnNewLine() {
@@ -6548,7 +7293,7 @@ public class Tokenizer implements Locato
 
     /**
      * Returns the line.
-     * 
+     *
      * @return the line
      */
     public int getLine() {
@@ -6557,7 +7302,7 @@ public class Tokenizer implements Locato
 
     /**
      * Returns the col.
-     * 
+     *
      * @return the col
      */
     public int getCol() {
@@ -6565,14 +7310,14 @@ public class Tokenizer implements Locato
     }
 
     // ]NOCPP]
-    
+
     public boolean isInDataState() {
         return (stateSave == DATA);
     }
 
     public void resetToDataState() {
-        strBufLen = 0;
-        longStrBufLen = 0;
+        clearStrBufAfterUse();
+        charRefBufLen = 0;
         stateSave = Tokenizer.DATA;
         // line = 1; XXX line numbers
         lastCR = false;
@@ -6584,31 +7329,22 @@ public class Tokenizer implements Locato
         lo = 0;
         hi = 0; // will always be overwritten before use anyway
         candidate = -1;
-        strBufMark = 0;
-        prevValue = -1;
+        charRefBufMark = 0;
         value = 0;
         seenDigits = false;
+        suspendAfterCurrentNonTextToken = false;
         endTag = false;
         shouldSuspend = false;
         initDoctypeFields();
-        if (tagName != null) {
-            tagName.release();
-            tagName = null;
-        }
-        if (attributeName != null) {
-            attributeName.release();
-            attributeName = null;
-        }
-        // [NOCPP[
+        containsHyphen = false;
+        tagName = null;
+        attributeName = null;
         if (newAttributesEachTime) {
-            // ]NOCPP]
             if (attributes != null) {
                 Portability.delete(attributes);
                 attributes = null;
             }
-            // [NOCPP[
         }
-        // ]NOCPP]
     }
 
     public void loadState(Tokenizer other) throws SAXException {
@@ -6618,11 +7354,8 @@ public class Tokenizer implements Locato
         }
         System.arraycopy(other.strBuf, 0, strBuf, 0, strBufLen);
 
-        longStrBufLen = other.longStrBufLen;
-        if (longStrBufLen > longStrBuf.length) {
-            longStrBuf = new char[longStrBufLen];
-        }
-        System.arraycopy(other.longStrBuf, 0, longStrBuf, 0, longStrBufLen);
+        charRefBufLen = other.charRefBufLen;
+        System.arraycopy(other.charRefBuf, 0, charRefBuf, 0, charRefBufLen);
 
         stateSave = other.stateSave;
         returnStateSave = other.returnStateSave;
@@ -6638,19 +7371,13 @@ public class Tokenizer implements Locato
         lo = other.lo;
         hi = other.hi;
         candidate = other.candidate;
-        strBufMark = other.strBufMark;
-        prevValue = other.prevValue;
+        charRefBufMark = other.charRefBufMark;
         value = other.value;
         seenDigits = other.seenDigits;
         endTag = other.endTag;
         shouldSuspend = false;
-
-        if (other.doctypeName == null) {
-            doctypeName = null;
-        } else {
-            doctypeName = Portability.newLocalFromLocal(other.doctypeName,
-                    interner);
-        }
+        suspendAfterCurrentNonTextToken = false;
+        doctypeName = other.doctypeName;
 
         Portability.releaseString(systemIdentifier);
         if (other.systemIdentifier == null) {
@@ -6666,41 +7393,52 @@ public class Tokenizer implements Locato
             publicIdentifier = Portability.newStringFromString(other.publicIdentifier);
         }
 
-        if (tagName != null) {
-            tagName.release();
-        }
+        containsHyphen = other.containsHyphen;
         if (other.tagName == null) {
             tagName = null;
+        } else if (other.tagName.isInterned()) {
+            tagName = other.tagName;
         } else {
-            tagName = other.tagName.cloneElementName(interner);
+            // In the C++ case, the atoms in the other tokenizer are from a
+            // different tokenizer-scoped atom table. Therefore, we have to
+            // obtain the correspoding atom from our own atom table.
+            nonInternedTagName.setNameForNonInterned(other.tagName.getName()
+                    // CPPONLY: , other.tagName.isCustom()
+                    );
+            tagName = nonInternedTagName;
         }
 
-        if (attributeName != null) {
-            attributeName.release();
-        }
-        if (other.attributeName == null) {
-            attributeName = null;
-        } else {
-            attributeName = other.attributeName.cloneAttributeName(interner);
-        }
+        // [NOCPP[
+        attributeName = other.attributeName;
+        // ]NOCPP]
+        // CPPONLY: if (other.attributeName == null) {
+        // CPPONLY:     attributeName = null;
+        // CPPONLY: } else if (other.attributeName.isInterned()) {
+        // CPPONLY:     attributeName = other.attributeName;
+        // CPPONLY: } else {
+        // CPPONLY:     // In the C++ case, the atoms in the other tokenizer are from a
+        // CPPONLY:     // different tokenizer-scoped atom table. Therefore, we have to
+        // CPPONLY:     // obtain the correspoding atom from our own atom table.
+        // CPPONLY:     nonInternedAttributeName.setNameForNonInterned(other.attributeName.getLocal(AttributeName.HTML));
+        // CPPONLY:     attributeName = nonInternedAttributeName;
+        // CPPONLY: }
 
-        if (attributes != null) {
-            Portability.delete(attributes);
-        }
+        Portability.delete(attributes);
         if (other.attributes == null) {
             attributes = null;
         } else {
-            attributes = other.attributes.cloneAttributes(interner);
+            attributes = other.attributes.cloneAttributes();
         }
     }
 
     public void initializeWithoutStarting() throws SAXException {
         confident = false;
-        strBuf = new char[64];
-        longStrBuf = new char[1024];
+        if (!keepBuffer) {
+            strBuf = null;
+        }
         line = 1;
+        // CPPONLY: attributeLine = 1;
         // [NOCPP[
-        html4 = false;
         metaBoundaryPassed = false;
         wantsComments = tokenHandler.wantsComments();
         if (!newAttributesEachTime) {
@@ -6737,7 +7475,7 @@ public class Tokenizer implements Locato
     protected void errNamelessDoctype() throws SAXException {
     }
 
-    protected void errConsecutiveHyphens() throws SAXException {
+    protected void errNestedComment() throws SAXException {
     }
 
     protected void errPrematureEndOfComment() throws SAXException {
@@ -6752,16 +7490,9 @@ public class Tokenizer implements Locato
     protected void errSlashNotFollowedByGt() throws SAXException {
     }
 
-    protected void errHtml4XmlVoidSyntax() throws SAXException {
-    }
-
     protected void errNoSpaceBetweenAttributes() throws SAXException {
     }
 
-    protected void errHtml4NonNameInUnquotedAttribute(char c)
-            throws SAXException {
-    }
-
     protected void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char c)
             throws SAXException {
     }
@@ -6887,9 +7618,6 @@ public class Tokenizer implements Locato
     protected void errMissingSpaceBeforeDoctypeName() throws SAXException {
     }
 
-    protected void errHyphenHyphenBang() throws SAXException {
-    }
-
     protected void errNcrControlChar() throws SAXException {
     }
 
@@ -6915,7 +7643,7 @@ public class Tokenizer implements Locato
 
     /**
      * Sets the encodingDeclarationHandler.
-     * 
+     *
      * @param encodingDeclarationHandler
      *            the encodingDeclarationHandler to set
      */
@@ -6923,23 +7651,29 @@ public class Tokenizer implements Locato
             EncodingDeclarationHandler encodingDeclarationHandler) {
         this.encodingDeclarationHandler = encodingDeclarationHandler;
     }
-    
+
     void destructor() {
+        Portability.delete(nonInternedTagName);
+        nonInternedTagName = null;
+        // CPPONLY: Portability.delete(nonInternedAttributeName);
+        // CPPONLY: nonInternedAttributeName = null;
         // The translator will write refcount tracing stuff here
+        Portability.delete(attributes);
+        attributes = null;
     }
-    
+
     // [NOCPP[
-    
+
     /**
-     * Sets an offset to be added to the position reported to 
+     * Sets an offset to be added to the position reported to
      * <code>TransitionHandler</code>.
-     * 
+     *
      * @param offset the offset
      */
     public void setTransitionBaseOffset(int offset) {
-        
+
     }
-    
+
     // ]NOCPP]
 
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/TreeBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/TreeBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/TreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/TreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,35 +1,35 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2007-2011 Mozilla Foundation
- * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla 
+ * Copyright (c) 2007-2017 Mozilla Foundation
+ * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
  * Foundation, and Opera Software ASA.
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 /*
- * The comments following this one that use the same comment syntax as this 
- * comment are quotes from the WHATWG HTML 5 spec as of 27 June 2007 
+ * The comments following this one that use the same comment syntax as this
+ * comment are quotes from the WHATWG HTML 5 spec as of 27 June 2007
  * amended as of June 28 2007.
  * That document came with this statement:
- * "© Copyright 2004-2007 Apple Computer, Inc., Mozilla Foundation, and 
- * Opera Software ASA. You are granted a license to use, reproduce and 
+ * "© Copyright 2004-2007 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce and
  * create derivative works of this document."
  */
 
@@ -39,6 +39,11 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
 import nu.validator.htmlparser.annotation.Auto;
 import nu.validator.htmlparser.annotation.Const;
 import nu.validator.htmlparser.annotation.IdType;
@@ -47,25 +52,20 @@ import nu.validator.htmlparser.annotatio
 import nu.validator.htmlparser.annotation.Local;
 import nu.validator.htmlparser.annotation.NoLength;
 import nu.validator.htmlparser.annotation.NsUri;
-import nu.validator.htmlparser.common.DoctypeExpectation;
 import nu.validator.htmlparser.common.DocumentMode;
 import nu.validator.htmlparser.common.DocumentModeHandler;
 import nu.validator.htmlparser.common.Interner;
 import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
 public abstract class TreeBuilder<T> implements TokenHandler,
         TreeBuilderState<T> {
-    
+
     /**
      * Array version of U+FFFD.
      */
     private static final @NoLength char[] REPLACEMENT_CHARACTER = { '\uFFFD' };
-    
+
     // Start dispatch groups
 
     final static int OTHER = 0;
@@ -96,7 +96,7 @@ public abstract class TreeBuilder<T> imp
 
     final static int INPUT = 13;
 
-    final static int ISINDEX = 14;
+    final static int RT_OR_RP = 14;
 
     final static int LI = 15;
 
@@ -162,19 +162,17 @@ public abstract class TreeBuilder<T> imp
 
     final static int IFRAME = 47;
 
-    final static int EMBED_OR_IMG = 48;
+    final static int EMBED = 48;
 
     final static int AREA_OR_WBR = 49;
 
     final static int DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU = 50;
 
-    final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY = 51;
+    final static int ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY = 51;
 
     final static int RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR = 52;
 
-    final static int RT_OR_RP = 53;
-
-    final static int COMMAND = 54;
+    final static int RB_OR_RTC = 53;
 
     final static int PARAM_OR_SOURCE_OR_TRACK = 55;
 
@@ -190,7 +188,7 @@ public abstract class TreeBuilder<T> imp
 
     final static int FIELDSET = 61;
 
-    final static int OUTPUT_OR_LABEL = 62;
+    final static int OUTPUT = 62;
 
     final static int OBJECT = 63;
 
@@ -198,51 +196,79 @@ public abstract class TreeBuilder<T> imp
 
     final static int KEYGEN = 65;
 
+    final static int TEMPLATE = 66;
+
+    final static int IMG = 67;
+
     // start insertion modes
 
-    private static final int INITIAL = 0;
+    private static final int IN_ROW = 0;
 
-    private static final int BEFORE_HTML = 1;
+    private static final int IN_TABLE_BODY = 1;
 
-    private static final int BEFORE_HEAD = 2;
+    private static final int IN_TABLE = 2;
 
-    private static final int IN_HEAD = 3;
+    private static final int IN_CAPTION = 3;
 
-    private static final int IN_HEAD_NOSCRIPT = 4;
+    private static final int IN_CELL = 4;
 
-    private static final int AFTER_HEAD = 5;
+    private static final int FRAMESET_OK = 5;
 
     private static final int IN_BODY = 6;
 
-    private static final int IN_TABLE = 7;
+    private static final int IN_HEAD = 7;
 
-    private static final int IN_CAPTION = 8;
+    private static final int IN_HEAD_NOSCRIPT = 8;
+
+    // no fall-through
 
     private static final int IN_COLUMN_GROUP = 9;
 
-    private static final int IN_TABLE_BODY = 10;
+    // no fall-through
+
+    private static final int IN_SELECT_IN_TABLE = 10;
+
+    private static final int IN_SELECT = 11;
+
+    // no fall-through
+
+    private static final int AFTER_BODY = 12;
+
+    // no fall-through
+
+    private static final int IN_FRAMESET = 13;
 
-    private static final int IN_ROW = 11;
+    private static final int AFTER_FRAMESET = 14;
 
-    private static final int IN_CELL = 12;
+    // no fall-through
 
-    private static final int IN_SELECT = 13;
+    private static final int INITIAL = 15;
 
-    private static final int IN_SELECT_IN_TABLE = 14;
+    // could add fall-through
 
-    private static final int AFTER_BODY = 15;
+    private static final int BEFORE_HTML = 16;
 
-    private static final int IN_FRAMESET = 16;
+    // could add fall-through
 
-    private static final int AFTER_FRAMESET = 17;
+    private static final int BEFORE_HEAD = 17;
 
-    private static final int AFTER_AFTER_BODY = 18;
+    // no fall-through
 
-    private static final int AFTER_AFTER_FRAMESET = 19;
+    private static final int AFTER_HEAD = 18;
 
-    private static final int TEXT = 20;
+    // no fall-through
 
-    private static final int FRAMESET_OK = 21;
+    private static final int AFTER_AFTER_BODY = 19;
+
+    // no fall-through
+
+    private static final int AFTER_AFTER_FRAMESET = 20;
+
+    // no fall-through
+
+    private static final int TEXT = 21;
+
+    private static final int IN_TEMPLATE = 22;
 
     // start charset states
 
@@ -272,17 +298,6 @@ public abstract class TreeBuilder<T> imp
 
     // end pseudo enums
 
-    // [NOCPP[
-
-    private final static String[] HTML4_PUBLIC_IDS = {
-            "-//W3C//DTD HTML 4.0 Frameset//EN",
-            "-//W3C//DTD HTML 4.0 Transitional//EN",
-            "-//W3C//DTD HTML 4.0//EN", "-//W3C//DTD HTML 4.01 Frameset//EN",
-            "-//W3C//DTD HTML 4.01 Transitional//EN",
-            "-//W3C//DTD HTML 4.01//EN" };
-
-    // ]NOCPP]
-
     @Literal private final static String[] QUIRKY_PUBLIC_IDS = {
             "+//silmaril//dtd html pro v0r11 19970101//",
             "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
@@ -346,7 +361,7 @@ public abstract class TreeBuilder<T> imp
     private int mode = INITIAL;
 
     private int originalMode = INITIAL;
-    
+
     /**
      * Used only when moving back to IN_BODY.
      */
@@ -360,8 +375,6 @@ public abstract class TreeBuilder<T> imp
 
     private DocumentModeHandler documentModeHandler;
 
-    private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML;
-
     // ]NOCPP]
 
     private boolean scriptingEnabled = false;
@@ -382,6 +395,25 @@ public abstract class TreeBuilder<T> imp
 
     private T contextNode;
 
+    /**
+     * Stack of template insertion modes
+     */
+    private @Auto int[] templateModeStack;
+
+    /**
+     * Current template mode stack pointer.
+     */
+    private int templateModePtr = -1;
+
+    private @Auto StackNode<T>[] stackNodes;
+
+    /**
+     * Index of the earliest possible unused or empty element in stackNodes.
+     */
+    private int stackNodesIdx = -1;
+
+    private int numStackNodes = 0;
+
     private @Auto StackNode<T>[] stack;
 
     private int currentPtr = -1;
@@ -394,17 +426,18 @@ public abstract class TreeBuilder<T> imp
 
     private T headPointer;
 
-    /**
-     * Used to work around Gecko limitations. Not used in Java.
-     */
-    private T deepTreeSurrogateParent;
-
     protected @Auto char[] charBuffer;
 
     protected int charBufferLen = 0;
 
     private boolean quirks = false;
 
+    private boolean forceNoQuirks = false;
+
+    private boolean allowDeclarativeShadowRoots = false;
+
+    private boolean keepBuffer = false;
+
     // [NOCPP[
 
     private boolean reportingDoctype = true;
@@ -413,8 +446,6 @@ public abstract class TreeBuilder<T> imp
 
     private final Map<String, LocatorImpl> idLocations = new HashMap<String, LocatorImpl>();
 
-    private boolean html4;
-
     // ]NOCPP]
 
     protected TreeBuilder() {
@@ -424,13 +455,25 @@ public abstract class TreeBuilder<T> imp
     /**
      * Reports an condition that would make the infoset incompatible with XML
      * 1.0 as fatal.
-     * 
+     *
      * @throws SAXException
      * @throws SAXParseException
      */
     protected void fatal() throws SAXException {
     }
 
+    // CPPONLY: @Inline private @Creator Object htmlCreator(@HtmlCreator Object htmlCreator) {
+    // CPPONLY:     @Creator Object creator;
+    // CPPONLY:     creator.html = htmlCreator;
+    // CPPONLY:     return creator;
+    // CPPONLY: }
+    // CPPONLY:
+    // CPPONLY: @Inline private @Creator Object svgCreator(@SvgCreator Object svgCreator) {
+    // CPPONLY:     @Creator Object creator;
+    // CPPONLY:     creator.svg = svgCreator;
+    // CPPONLY:     return creator;
+    // CPPONLY: }
+
     // [NOCPP[
 
     protected final void fatal(Exception e) throws SAXException {
@@ -452,7 +495,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Reports a Parse Error.
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -463,10 +506,10 @@ public abstract class TreeBuilder<T> imp
         }
         errNoCheck(message);
     }
-    
+
     /**
      * Reports a Parse Error without checking if an error handler is present.
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -476,68 +519,6 @@ public abstract class TreeBuilder<T> imp
         errorHandler.error(spe);
     }
 
-    /**
-     * Reports a stray start tag.
-     * @param name the name of the stray tag
-     * 
-     * @throws SAXException
-     */
-    private void errStrayStartTag(String name) throws SAXException {
-        err("Stray end tag \u201C" + name + "\u201D.");
-    }
-
-    /**
-     * Reports a stray end tag.
-     * @param name the name of the stray tag
-     * 
-     * @throws SAXException
-     */
-    private void errStrayEndTag(String name) throws SAXException {
-        err("Stray end tag \u201C" + name + "\u201D.");
-    }
-    
-    /**
-     * Reports a state when elements expected to be closed were not.
-     * 
-     * @param eltPos the position of the start tag on the stack of the element
-     * being closed.
-     * @param name the name of the end tag
-     * 
-     * @throws SAXException
-     */
-    private void errUnclosedElements(int eltPos, String name) throws SAXException {
-        errNoCheck("End tag \u201C" + name + "\u201D seen, but there were open elements.");
-        errListUnclosedStartTags(eltPos);
-    }
-
-    /**
-     * Reports a state when elements expected to be closed ahead of an implied 
-     * end tag but were not.
-     * 
-     * @param eltPos the position of the start tag on the stack of the element
-     * being closed.
-     * @param name the name of the end tag
-     * 
-     * @throws SAXException
-     */
-    private void errUnclosedElementsImplied(int eltPos, String name) throws SAXException {
-        errNoCheck("End tag \u201C" + name + "\u201D implied, but there were open elements.");
-        errListUnclosedStartTags(eltPos);
-    }
-
-    /**
-     * Reports a state when elements expected to be closed ahead of an implied 
-     * table cell close.
-     * 
-     * @param eltPos the position of the start tag on the stack of the element
-     * being closed.
-     * @throws SAXException
-     */
-    private void errUnclosedElementsCell(int eltPos) throws SAXException {
-        errNoCheck("A table cell was implicitly closed, but there were open elements.");
-        errListUnclosedStartTags(eltPos);
-    }
-    
     private void errListUnclosedStartTags(int eltPos) throws SAXException {
         if (currentPtr != -1) {
             for (int i = currentPtr; i > eltPos; i--) {
@@ -547,24 +528,8 @@ public abstract class TreeBuilder<T> imp
     }
 
     /**
-     * Reports arriving at/near end of document with unclosed elements remaining.
-     * 
-     * @param message
-     *            the message
-     * @throws SAXException
-     */
-    private void errEndWithUnclosedElements(String message) throws SAXException {
-        if (errorHandler == null) {
-            return;
-        }
-        errNoCheck(message);
-        // just report all remaining unclosed elements
-        errListUnclosedStartTags(0);
-    }
-
-    /**
      * Reports the name and location of an unclosed element.
-     * 
+     *
      * @throws SAXException
      */
     private final void reportUnclosedElementNameAndLocation(int pos) throws SAXException {
@@ -584,7 +549,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Reports a warning
-     * 
+     *
      * @param message
      *            the message
      * @throws SAXException
@@ -597,27 +562,59 @@ public abstract class TreeBuilder<T> imp
         errorHandler.warning(spe);
     }
 
+    /**
+     * Reports a warning with an explicit locator
+     *
+     * @param message
+     *            the message
+     * @throws SAXException
+     */
+    final void warn(String message, Locator locator) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        SAXParseException spe = new SAXParseException(message, locator);
+        errorHandler.warning(spe);
+    }
+
     // ]NOCPP]
-    
+
+    public void setKeepBuffer(boolean keepBuffer) {
+        this.keepBuffer = keepBuffer;
+    }
+
+    public boolean dropBufferIfLongerThan(int length) {
+        if (charBuffer.length > length) {
+            charBuffer = null;
+            return true;
+        }
+        return false;
+    }
+
     @SuppressWarnings("unchecked") public final void startTokenization(Tokenizer self) throws SAXException {
         tokenizer = self;
+        stackNodes = new StackNode[64];
         stack = new StackNode[64];
+        templateModeStack = new int[64];
         listOfActiveFormattingElements = new StackNode[64];
         needToDropLF = false;
         originalMode = INITIAL;
+        templateModePtr = -1;
+        stackNodesIdx = 0;
+        numStackNodes = 0;
         currentPtr = -1;
         listPtr = -1;
         formPointer = null;
         headPointer = null;
-        deepTreeSurrogateParent = null;
         // [NOCPP[
-        html4 = false;
         idLocations.clear();
         wantingComments = wantsComments();
         // ]NOCPP]
         start(fragment);
         charBufferLen = 0;
-        charBuffer = new char[1024];
+        if (!keepBuffer) {
+            charBuffer = null;
+        }
         framesetOk = true;
         if (fragment) {
             T elt;
@@ -626,264 +623,195 @@ public abstract class TreeBuilder<T> imp
             } else {
                 elt = createHtmlElementSetAsRoot(tokenizer.emptyAttributes());
             }
-            StackNode<T> node = new StackNode<T>(ElementName.HTML, elt
-            // [NOCPP[
-                    , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
-            // ]NOCPP]
-            );
-            currentPtr++;
-            stack[currentPtr] = node;
-            resetTheInsertionMode();
-            if ("title" == contextName || "textarea" == contextName) {
-                tokenizer.setStateAndEndTagExpectation(Tokenizer.RCDATA, contextName);
-            } else if ("style" == contextName || "xmp" == contextName
-                    || "iframe" == contextName || "noembed" == contextName
-                    || "noframes" == contextName
-                    || (scriptingEnabled && "noscript" == contextName)) {
-                tokenizer.setStateAndEndTagExpectation(Tokenizer.RAWTEXT, contextName);
-            } else if ("plaintext" == contextName) {
-                tokenizer.setStateAndEndTagExpectation(Tokenizer.PLAINTEXT, contextName);
-            } else if ("script" == contextName) {
-                tokenizer.setStateAndEndTagExpectation(Tokenizer.SCRIPT_DATA,
-                        contextName);
-            } else {
-                tokenizer.setStateAndEndTagExpectation(Tokenizer.DATA, contextName);
+            // When the context node is not in the HTML namespace, contrary
+            // to the spec, the first node on the stack is not set to "html"
+            // in the HTML namespace. Instead, it is set to a node that has
+            // the characteristics of the appropriate "adjusted current node".
+            // This way, there is no need to perform "adjusted current node"
+            // checks during tree construction. Instead, it's sufficient to
+            // just look at the current node. However, this also means that it
+            // is not safe to treat "html" in the HTML namespace as a sentinel
+            // that ends stack popping. Instead, stack popping loops that are
+            // meant not to pop the first element on the stack need to check
+            // for currentPos becoming zero.
+            if (contextNamespace == "http://www.w3.org/2000/svg") {
+                ElementName elementName = ElementName.SVG;
+                if ("title" == contextName || "desc" == contextName
+                        || "foreignObject" == contextName) {
+                    // These elements are all alike and we don't care about
+                    // the exact name.
+                    elementName = ElementName.FOREIGNOBJECT;
+                }
+                // This is the SVG variant of the StackNode constructor.
+                StackNode<T> node = createStackNode(elementName,
+                        elementName.getCamelCaseName(), elt
+                        // [NOCPP[
+                        , errorHandler == null ? null
+                                : new TaintableLocatorImpl(tokenizer)
+                // ]NOCPP]
+                );
+                currentPtr++;
+                stack[currentPtr] = node;
+                tokenizer.setState(Tokenizer.DATA);
+                // The frameset-ok flag is set even though <frameset> never
+                // ends up being allowed as HTML frameset in the fragment case.
+                mode = FRAMESET_OK;
+            } else if (contextNamespace == "http://www.w3.org/1998/Math/MathML") {
+                ElementName elementName = ElementName.MATH;
+                if ("mi" == contextName || "mo" == contextName
+                        || "mn" == contextName || "ms" == contextName
+                        || "mtext" == contextName) {
+                    // These elements are all alike and we don't care about
+                    // the exact name.
+                    elementName = ElementName.MTEXT;
+                } else if ("annotation-xml" == contextName) {
+                    elementName = ElementName.ANNOTATION_XML;
+                    // Blink does not check the encoding attribute of the
+                    // annotation-xml element innerHTML is being set on.
+                    // Let's do the same at least until
+                    // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26783
+                    // is resolved.
+                }
+                // This is the MathML variant of the StackNode constructor.
+                StackNode<T> node = createStackNode(elementName, elt,
+                        elementName.getName(), false
+                        // [NOCPP[
+                        , errorHandler == null ? null
+                                : new TaintableLocatorImpl(tokenizer)
+                // ]NOCPP]
+                );
+                currentPtr++;
+                stack[currentPtr] = node;
+                tokenizer.setState(Tokenizer.DATA);
+                // The frameset-ok flag is set even though <frameset> never
+                // ends up being allowed as HTML frameset in the fragment case.
+                mode = FRAMESET_OK;
+            } else { // html
+                StackNode<T> node = createStackNode(ElementName.HTML, elt
+                // [NOCPP[
+                        , errorHandler == null ? null
+                                : new TaintableLocatorImpl(tokenizer)
+                // ]NOCPP]
+                );
+                currentPtr++;
+                stack[currentPtr] = node;
+                if ("template" == contextName) {
+                    pushTemplateMode(IN_TEMPLATE);
+                }
+                resetTheInsertionMode();
+                formPointer = getFormPointerForContext(contextNode);
+                if ("title" == contextName || "textarea" == contextName) {
+                    tokenizer.setState(Tokenizer.RCDATA);
+                } else if ("style" == contextName || "xmp" == contextName
+                        || "iframe" == contextName || "noembed" == contextName
+                        || "noframes" == contextName
+                        || (scriptingEnabled && "noscript" == contextName)) {
+                    tokenizer.setState(Tokenizer.RAWTEXT);
+                } else if ("plaintext" == contextName) {
+                    tokenizer.setState(Tokenizer.PLAINTEXT);
+                } else if ("script" == contextName) {
+                    tokenizer.setState(Tokenizer.SCRIPT_DATA);
+                } else {
+                    tokenizer.setState(Tokenizer.DATA);
+                }
             }
-            contextName = null;
-            contextNode = null;
         } else {
             mode = INITIAL;
+            // If we are viewing XML source, put a foreign element permanently
+            // on the stack so that cdataSectionAllowed() returns true.
+            // CPPONLY: if (tokenizer.isViewingXmlSource()) {
+            // CPPONLY: T elt = createElement("http://www.w3.org/2000/svg",
+            // CPPONLY: "svg",
+            // CPPONLY: tokenizer.emptyAttributes(), null,
+            // CPPONLY: svgCreator(NS_NewSVGSVGElement));
+            // CPPONLY: StackNode<T> node = createStackNode(ElementName.SVG,
+            // CPPONLY: "svg",
+            // CPPONLY: elt);
+            // CPPONLY: currentPtr++;
+            // CPPONLY: stack[currentPtr] = node;
+            // CPPONLY: }
         }
     }
 
     public final void doctype(@Local String name, String publicIdentifier,
             String systemIdentifier, boolean forceQuirks) throws SAXException {
         needToDropLF = false;
-        if (!isInForeign()) {
-            switch (mode) {
-                case INITIAL:
-                    // [NOCPP[
-                    if (reportingDoctype) {
-                        // ]NOCPP]
-                        String emptyString = Portability.newEmptyString();
-                        appendDoctypeToDocument(name == null ? "" : name,
-                                publicIdentifier == null ? emptyString
-                                        : publicIdentifier,
-                                systemIdentifier == null ? emptyString
-                                        : systemIdentifier);
-                        Portability.releaseString(emptyString);
-                        // [NOCPP[
-                    }
-                    switch (doctypeExpectation) {
-                        case HTML:
-                            // ]NOCPP]
-                            if (isQuirky(name, publicIdentifier,
-                                    systemIdentifier, forceQuirks)) {
-                                err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
-                                documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            } else if (isAlmostStandards(publicIdentifier,
-                                    systemIdentifier)) {
-                                err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.");
-                                documentModeInternal(
-                                        DocumentMode.ALMOST_STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            } else {
-                                // [NOCPP[
-                                if ((Portability.literalEqualsString(
-                                        "-//W3C//DTD HTML 4.0//EN",
-                                        publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
-                                        "http://www.w3.org/TR/REC-html40/strict.dtd",
-                                        systemIdentifier)))
-                                        || (Portability.literalEqualsString(
-                                                "-//W3C//DTD HTML 4.01//EN",
-                                                publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
-                                                "http://www.w3.org/TR/html4/strict.dtd",
-                                                systemIdentifier)))
-                                        || (Portability.literalEqualsString(
-                                                "-//W3C//DTD XHTML 1.0 Strict//EN",
-                                                publicIdentifier) && Portability.literalEqualsString(
-                                                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
-                                                systemIdentifier))
-                                        || (Portability.literalEqualsString(
-                                                "-//W3C//DTD XHTML 1.1//EN",
-                                                publicIdentifier) && Portability.literalEqualsString(
-                                                "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd",
-                                                systemIdentifier))
-
-                                ) {
-                                    warn("Obsolete doctype. Expected \u201C<!DOCTYPE html>\u201D.");
-                                } else if (!((systemIdentifier == null || Portability.literalEqualsString(
-                                        "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
-                                    err("Legacy doctype. Expected \u201C<!DOCTYPE html>\u201D.");
-                                }
-                                // ]NOCPP]
-                                documentModeInternal(
-                                        DocumentMode.STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            }
-                            // [NOCPP[
-                            break;
-                        case HTML401_STRICT:
-                            html4 = true;
-                            tokenizer.turnOnAdditionalHtml4Errors();
-                            if (isQuirky(name, publicIdentifier,
-                                    systemIdentifier, forceQuirks)) {
-                                err("Quirky doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            } else if (isAlmostStandards(publicIdentifier,
-                                    systemIdentifier)) {
-                                err("Almost standards mode doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                documentModeInternal(
-                                        DocumentMode.ALMOST_STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            } else {
-                                if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
-                                    if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
-                                        warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                    }
-                                } else {
-                                    err("The doctype was not the HTML 4.01 Strict doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                }
-                                documentModeInternal(
-                                        DocumentMode.STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            }
-                            break;
-                        case HTML401_TRANSITIONAL:
-                            html4 = true;
-                            tokenizer.turnOnAdditionalHtml4Errors();
-                            if (isQuirky(name, publicIdentifier,
-                                    systemIdentifier, forceQuirks)) {
-                                err("Quirky doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            } else if (isAlmostStandards(publicIdentifier,
-                                    systemIdentifier)) {
-                                if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)
-                                        && systemIdentifier != null) {
-                                    if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) {
-                                        warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                    }
-                                } else {
-                                    err("The doctype was not a non-quirky HTML 4.01 Transitional doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                }
-                                documentModeInternal(
-                                        DocumentMode.ALMOST_STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            } else {
-                                err("The doctype was not the HTML 4.01 Transitional doctype. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                documentModeInternal(
-                                        DocumentMode.STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        true);
-                            }
-                            break;
-                        case AUTO:
-                            html4 = isHtml4Doctype(publicIdentifier);
-                            if (html4) {
-                                tokenizer.turnOnAdditionalHtml4Errors();
-                            }
-                            if (isQuirky(name, publicIdentifier,
-                                    systemIdentifier, forceQuirks)) {
-                                err("Quirky doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        html4);
-                            } else if (isAlmostStandards(publicIdentifier,
-                                    systemIdentifier)) {
-                                if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)) {
-                                    if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) {
-                                        warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                    }
-                                } else {
-                                    err("Almost standards mode doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                }
-                                documentModeInternal(
-                                        DocumentMode.ALMOST_STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        html4);
-                            } else {
-                                if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) {
-                                    if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) {
-                                        warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                    }
-                                } else {
-                                    if (!(publicIdentifier == null && systemIdentifier == null)) {
-                                        err("Legacy doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                    }
-                                }
-                                documentModeInternal(
-                                        DocumentMode.STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        html4);
-                            }
-                            break;
-                        case NO_DOCTYPE_ERRORS:
-                            if (isQuirky(name, publicIdentifier,
-                                    systemIdentifier, forceQuirks)) {
-                                documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            } else if (isAlmostStandards(publicIdentifier,
-                                    systemIdentifier)) {
-                                documentModeInternal(
-                                        DocumentMode.ALMOST_STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            } else {
-                                documentModeInternal(
-                                        DocumentMode.STANDARDS_MODE,
-                                        publicIdentifier, systemIdentifier,
-                                        false);
-                            }
-                            break;
-                    }
-                    // ]NOCPP]
-
-                    /*
-                     * 
-                     * Then, switch to the root element mode of the tree
-                     * construction stage.
-                     */
-                    mode = BEFORE_HTML;
-                    return;
-                default:
-                    break;
+        if (!isInForeign() && mode == INITIAL) {
+            // [NOCPP[
+            if (reportingDoctype) {
+                // ]NOCPP]
+                String emptyString = Portability.newEmptyString();
+                appendDoctypeToDocument(name == null ? "" : name,
+                        publicIdentifier == null ? emptyString
+                                : publicIdentifier,
+                        systemIdentifier == null ? emptyString
+                                : systemIdentifier);
+                Portability.releaseString(emptyString);
+                // [NOCPP[
+            }
+            // ]NOCPP]
+            if (isQuirky(name, publicIdentifier, systemIdentifier,
+                    forceQuirks)) {
+                errQuirkyDoctype();
+                documentModeInternal(DocumentMode.QUIRKS_MODE,
+                        publicIdentifier, systemIdentifier);
+            } else if (isAlmostStandards(publicIdentifier,
+                    systemIdentifier)) {
+                errAlmostStandardsDoctype();
+                documentModeInternal(
+                        DocumentMode.ALMOST_STANDARDS_MODE,
+                        publicIdentifier, systemIdentifier);
+            } else {
+                // [NOCPP[
+                if ((Portability.literalEqualsString(
+                        "-//W3C//DTD HTML 4.0//EN", publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
+                        "http://www.w3.org/TR/REC-html40/strict.dtd",
+                        systemIdentifier)))
+                        || (Portability.literalEqualsString(
+                                "-//W3C//DTD HTML 4.01//EN",
+                                publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString(
+                                "http://www.w3.org/TR/html4/strict.dtd",
+                                systemIdentifier)))
+                        || (Portability.literalEqualsString(
+                                "-//W3C//DTD XHTML 1.0 Strict//EN",
+                                publicIdentifier) && Portability.literalEqualsString(
+                                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
+                                systemIdentifier))
+                        || (Portability.literalEqualsString(
+                                "-//W3C//DTD XHTML 1.1//EN",
+                                publicIdentifier) && Portability.literalEqualsString(
+                                "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd",
+                                systemIdentifier))
+
+                ) {
+                    err("Obsolete doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+                } else if (!((systemIdentifier == null || Portability.literalEqualsString(
+                        "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) {
+                    err("Legacy doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+                }
+                // ]NOCPP]
+                documentModeInternal(DocumentMode.STANDARDS_MODE,
+                        publicIdentifier, systemIdentifier);
             }
+
+            /*
+             *
+             * Then, switch to the root element mode of the tree construction
+             * stage.
+             */
+            mode = BEFORE_HTML;
+            return;
         }
         /*
          * A DOCTYPE token Parse error.
          */
-        err("Stray doctype.");
+        errStrayDoctype();
         /*
          * Ignore the token.
          */
         return;
     }
 
-    // [NOCPP[
-
-    private boolean isHtml4Doctype(String publicIdentifier) {
-        if (publicIdentifier != null
-                && (Arrays.binarySearch(TreeBuilder.HTML4_PUBLIC_IDS,
-                        publicIdentifier) > -1)) {
-            return true;
-        }
-        return false;
-    }
-
-    // ]NOCPP]
-
     public final void comment(@NoLength char[] buf, int start, int length)
             throws SAXException {
         needToDropLF = false;
@@ -934,6 +862,11 @@ public abstract class TreeBuilder<T> imp
      */
     public final void characters(@Const @NoLength char[] buf, int start, int length)
             throws SAXException {
+        // Note: Can't attach error messages to EOF in C++ yet
+
+        // CPPONLY: if (tokenizer.isViewingXmlSource()) {
+        // CPPONLY: return;
+        // CPPONLY: }
         if (needToDropLF) {
             needToDropLF = false;
             if (buf[start] == '\n') {
@@ -950,10 +883,10 @@ public abstract class TreeBuilder<T> imp
             case IN_BODY:
             case IN_CELL:
             case IN_CAPTION:
-                if (!isInForeign()) {
+                if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                     reconstructTheActiveFormattingElements();
                 }
-                // fall through
+                // CPPONLY: MOZ_FALLTHROUGH;
             case TEXT:
                 accumulateCharacters(buf, start, length);
                 return;
@@ -996,6 +929,7 @@ public abstract class TreeBuilder<T> imp
                                      */
                                     continue;
                                 case FRAMESET_OK:
+                                case IN_TEMPLATE:
                                 case IN_BODY:
                                 case IN_CELL:
                                 case IN_CAPTION:
@@ -1009,7 +943,7 @@ public abstract class TreeBuilder<T> imp
                                      * Reconstruct the active formatting
                                      * elements, if any.
                                      */
-                                    if (!isInForeign()) {
+                                    if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                                         flushCharacters();
                                         reconstructTheActiveFormattingElements();
                                     }
@@ -1047,6 +981,7 @@ public abstract class TreeBuilder<T> imp
                                      */
                                     continue;
                             }
+                            // CPPONLY: MOZ_FALLTHROUGH_ASSERT();
                         default:
                             /*
                              * A character token that is not one of one of
@@ -1059,29 +994,16 @@ public abstract class TreeBuilder<T> imp
                                      * Parse error.
                                      */
                                     // [NOCPP[
-                                    switch (doctypeExpectation) {
-                                        case AUTO:
-                                            err("Non-space characters found without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                            break;
-                                        case HTML:
-                                            err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
-                                            break;
-                                        case HTML401_STRICT:
-                                            err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                            break;
-                                        case HTML401_TRANSITIONAL:
-                                            err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                            break;
-                                        case NO_DOCTYPE_ERRORS:
-                                    }
+                                    // XXX figure out a way to report this in the Gecko View Source case
+                                    err("Non-space characters found without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
                                     // ]NOCPP]
                                     /*
-                                     * 
+                                     *
                                      * Set the document to quirks mode.
                                      */
                                     documentModeInternal(
                                             DocumentMode.QUIRKS_MODE, null,
-                                            null, false);
+                                            null);
                                     /*
                                      * Then, switch to the root element mode of
                                      * the tree construction stage
@@ -1124,7 +1046,7 @@ public abstract class TreeBuilder<T> imp
                                     mode = IN_HEAD;
                                     /*
                                      * then reprocess the current token.
-                                     * 
+                                     *
                                      * This will result in an empty head element
                                      * being generated, with the current token
                                      * being reprocessed in the "after head"
@@ -1160,7 +1082,7 @@ public abstract class TreeBuilder<T> imp
                                      * Parse error. Act as if an end tag with
                                      * the tag name "noscript" had been seen
                                      */
-                                    err("Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D.");
+                                    errNonSpaceInNoscriptInHead();
                                     flushCharacters();
                                     pop();
                                     mode = IN_HEAD;
@@ -1193,6 +1115,7 @@ public abstract class TreeBuilder<T> imp
                                     mode = IN_BODY;
                                     i--;
                                     continue;
+                                case IN_TEMPLATE:
                                 case IN_BODY:
                                 case IN_CELL:
                                 case IN_CAPTION:
@@ -1205,7 +1128,7 @@ public abstract class TreeBuilder<T> imp
                                      * Reconstruct the active formatting
                                      * elements, if any.
                                      */
-                                    if (!isInForeign()) {
+                                    if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
                                         flushCharacters();
                                         reconstructTheActiveFormattingElements();
                                     }
@@ -1232,8 +1155,9 @@ public abstract class TreeBuilder<T> imp
                                      * that token wasn't ignored, reprocess the
                                      * current token.
                                      */
-                                    if (currentPtr == 0) {
-                                        err("Non-space in \u201Ccolgroup\u201D when parsing fragment.");
+                                    if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+                                            TreeBuilder.TEMPLATE) {
+                                        errNonSpaceInColgroupInFragment();
                                         start = i + 1;
                                         continue;
                                     }
@@ -1246,7 +1170,7 @@ public abstract class TreeBuilder<T> imp
                                 case IN_SELECT_IN_TABLE:
                                     break charactersloop;
                                 case AFTER_BODY:
-                                    err("Non-space character after body.");
+                                    errNonSpaceAfterBody();
                                     fatal();
                                     mode = framesetOk ? FRAMESET_OK : IN_BODY;
                                     i--;
@@ -1255,12 +1179,12 @@ public abstract class TreeBuilder<T> imp
                                     if (start < i) {
                                         accumulateCharacters(buf, start, i
                                                 - start);
-                                        start = i;
+                                        // start index is adjusted below.
                                     }
                                     /*
                                      * Parse error.
                                      */
-                                    err("Non-space in \u201Cframeset\u201D.");
+                                    errNonSpaceInFrameset();
                                     /*
                                      * Ignore the token.
                                      */
@@ -1270,12 +1194,12 @@ public abstract class TreeBuilder<T> imp
                                     if (start < i) {
                                         accumulateCharacters(buf, start, i
                                                 - start);
-                                        start = i;
+                                        // start index is adjusted below.
                                     }
                                     /*
                                      * Parse error.
                                      */
-                                    err("Non-space after \u201Cframeset\u201D.");
+                                    errNonSpaceAfterFrameset();
                                     /*
                                      * Ignore the token.
                                      */
@@ -1285,7 +1209,7 @@ public abstract class TreeBuilder<T> imp
                                     /*
                                      * Parse error.
                                      */
-                                    err("Non-space character in page trailer.");
+                                    errNonSpaceInTrailer();
                                     /*
                                      * Switch back to the main mode and
                                      * reprocess the token.
@@ -1294,16 +1218,19 @@ public abstract class TreeBuilder<T> imp
                                     i--;
                                     continue;
                                 case AFTER_AFTER_FRAMESET:
+                                    if (start < i) {
+                                        accumulateCharacters(buf, start, i
+                                                - start);
+                                        // start index is adjusted below.
+                                    }
                                     /*
                                      * Parse error.
                                      */
-                                    err("Non-space character in page trailer.");
+                                    errNonSpaceInTrailer();
                                     /*
-                                     * Switch back to the main mode and
-                                     * reprocess the token.
+                                     * Ignore the token.
                                      */
-                                    mode = IN_FRAMESET;
-                                    i--;
+                                    start = i + 1;
                                     continue;
                             }
                     }
@@ -1323,56 +1250,37 @@ public abstract class TreeBuilder<T> imp
             return;
         }
         if (currentPtr >= 0) {
-            StackNode<T> stackNode = stack[currentPtr];
-            if (stackNode.ns == "http://www.w3.org/1999/xhtml") {
-                return;
-            }
-            if (stackNode.isHtmlIntegrationPoint()) {
-                return;
-            }
-            if (stackNode.ns == "http://www.w3.org/1998/Math/MathML"
-                    && stackNode.getGroup() == MI_MO_MN_MS_MTEXT) {
+            if (isSpecialParentInForeign(stack[currentPtr])) {
                 return;
             }
             accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
         }
     }
 
+    /**
+     * @see nu.validator.htmlparser.common.TokenHandler#zeroOrReplacementCharacter()
+     */
+    public void zeroOrReplacementCharacter() throws SAXException {
+        zeroOriginatingReplacementCharacter();
+    }
+
     public final void eof() throws SAXException {
         flushCharacters();
+        // Note: Can't attach error messages to EOF in C++ yet
         eofloop: for (;;) {
-            if (isInForeign()) {
-                err("End of file in a foreign namespace context.");
-                break eofloop;
-            }
             switch (mode) {
                 case INITIAL:
                     /*
                      * Parse error.
                      */
                     // [NOCPP[
-                    switch (doctypeExpectation) {
-                        case AUTO:
-                            err("End of file seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML:
-                            err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML401_STRICT:
-                            err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                            break;
-                        case HTML401_TRANSITIONAL:
-                            err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                            break;
-                        case NO_DOCTYPE_ERRORS:
-                    }
+                    err("End of file seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
                     // ]NOCPP]
                     /*
-                     * 
+                     *
                      * Set the document to quirks mode.
                      */
-                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
-                            false);
+                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null);
                     /*
                      * Then, switch to the root element mode of the tree
                      * construction stage
@@ -1400,16 +1308,20 @@ public abstract class TreeBuilder<T> imp
                     mode = IN_HEAD;
                     continue;
                 case IN_HEAD:
+                    // [NOCPP[
                     if (errorHandler != null && currentPtr > 1) {
-                        errEndWithUnclosedElements("End of file seen and there were open elements.");
+                        errEofWithUnclosedElements();
                     }
+                    // ]NOCPP]
                     while (currentPtr > 0) {
                         popOnEof();
                     }
                     mode = AFTER_HEAD;
                     continue;
                 case IN_HEAD_NOSCRIPT:
-                    errEndWithUnclosedElements("End of file seen and there were open elements.");
+                    // [NOCPP[
+                    errEofWithUnclosedElements();
+                    // ]NOCPP]
                     while (currentPtr > 1) {
                         popOnEof();
                     }
@@ -1419,21 +1331,19 @@ public abstract class TreeBuilder<T> imp
                     appendToCurrentNodeAndPushBodyElement();
                     mode = IN_BODY;
                     continue;
+                case IN_TABLE_BODY:
+                case IN_ROW:
+                case IN_TABLE:
+                case IN_SELECT_IN_TABLE:
+                case IN_SELECT:
                 case IN_COLUMN_GROUP:
-                    if (currentPtr == 0) {
-                        assert fragment;
-                        break eofloop;
-                    } else {
-                        popOnEof();
-                        mode = IN_TABLE;
-                        continue;
-                    }
                 case FRAMESET_OK:
                 case IN_CAPTION:
                 case IN_CELL:
                 case IN_BODY:
                     // [NOCPP[
-                    openelementloop: for (int i = currentPtr; i >= 0; i--) {
+                    // i > 0 to stop in time in the foreign fragment case.
+                    openelementloop: for (int i = currentPtr; i > 0; i--) {
                         int group = stack[i].getGroup();
                         switch (group) {
                             case DD_OR_DT:
@@ -1445,17 +1355,43 @@ public abstract class TreeBuilder<T> imp
                             case HTML:
                                 break;
                             default:
-                                errEndWithUnclosedElements("End of file seen and there were open elements.");
+                                errEofWithUnclosedElements();
                                 break openelementloop;
                         }
                     }
                     // ]NOCPP]
-                    break eofloop;
+
+                    if (isTemplateModeStackEmpty()) {
+                        break eofloop;
+                    }
+
+                    // fall through to IN_TEMPLATE
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case IN_TEMPLATE:
+                    int eltPos = findLast("template");
+                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                        assert fragment;
+                        break eofloop;
+                    }
+                    if (errorHandler != null) {
+                        errListUnclosedStartTags(0);
+                    }
+                    while (currentPtr >= eltPos) {
+                        pop();
+                    }
+                    clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+                    popTemplateMode();
+                    resetTheInsertionMode();
+
+                    // Reprocess token.
+                    continue;
                 case TEXT:
+                    // [NOCPP[
                     if (errorHandler != null) {
                         errNoCheck("End of file seen when expecting text or an end tag.");
                         errListUnclosedStartTags(0);
                     }
+                    // ]NOCPP]
                     // XXX mark script as already executed
                     if (originalMode == AFTER_HEAD) {
                         popOnEof();
@@ -1463,15 +1399,12 @@ public abstract class TreeBuilder<T> imp
                     popOnEof();
                     mode = originalMode;
                     continue;
-                case IN_TABLE_BODY:
-                case IN_ROW:
-                case IN_TABLE:
-                case IN_SELECT:
-                case IN_SELECT_IN_TABLE:
                 case IN_FRAMESET:
+                    // [NOCPP[
                     if (errorHandler != null && currentPtr > 0) {
-                        errEndWithUnclosedElements("End of file seen and there were open elements.");
+                        errEofWithUnclosedElements();
                     }
+                    // ]NOCPP]
                     break eofloop;
                 case AFTER_BODY:
                 case AFTER_FRAMESET:
@@ -1503,10 +1436,12 @@ public abstract class TreeBuilder<T> imp
     public final void endTokenization() throws SAXException {
         formPointer = null;
         headPointer = null;
-        deepTreeSurrogateParent = null;
+        contextName = null;
+        contextNode = null;
+        templateModeStack = null;
         if (stack != null) {
             while (currentPtr > -1) {
-                stack[currentPtr].release();
+                stack[currentPtr].release(this);
                 currentPtr--;
             }
             stack = null;
@@ -1514,16 +1449,28 @@ public abstract class TreeBuilder<T> imp
         if (listOfActiveFormattingElements != null) {
             while (listPtr > -1) {
                 if (listOfActiveFormattingElements[listPtr] != null) {
-                    listOfActiveFormattingElements[listPtr].release();
+                    listOfActiveFormattingElements[listPtr].release(this);
                 }
                 listPtr--;
             }
             listOfActiveFormattingElements = null;
         }
+        if (stackNodes != null) {
+            for (int i = 0; i < numStackNodes; i++) {
+                assert stackNodes[i].isUnused();
+                Portability.delete(stackNodes[i]);
+            }
+            numStackNodes = 0;
+            stackNodesIdx = 0;
+            stackNodes = null;
+        }
         // [NOCPP[
         idLocations.clear();
         // ]NOCPP]
-        charBuffer = null;
+
+        if (!keepBuffer) {
+            charBuffer = null;
+        }
         end();
     }
 
@@ -1532,10 +1479,12 @@ public abstract class TreeBuilder<T> imp
         flushCharacters();
 
         // [NOCPP[
+        boolean wasSelfClosing = selfClosing;
+        boolean voidElement = false;
         if (errorHandler != null) {
             // ID uniqueness
             @IdType String id = attributes.getId();
-            if (id != null) {
+            if (id != null && !isTemplateContents()) {
                 LocatorImpl oldLoc = idLocations.get(id);
                 if (oldLoc != null) {
                     err("Duplicate ID \u201C" + id + "\u201D.");
@@ -1553,7 +1502,7 @@ public abstract class TreeBuilder<T> imp
         needToDropLF = false;
         starttagloop: for (;;) {
             int group = elementName.getGroup();
-            @Local String name = elementName.name;
+            @Local String name = elementName.getName();
             if (isInForeign()) {
                 StackNode<T> currentNode = stack[currentPtr];
                 @NsUri String currNs = currentNode.ns;
@@ -1566,7 +1515,8 @@ public abstract class TreeBuilder<T> imp
                         case RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
                         case DD_OR_DT:
                         case UL_OR_OL_OR_DL:
-                        case EMBED_OR_IMG:
+                        case EMBED:
+                        case IMG:
                         case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                         case HEAD:
                         case HR:
@@ -1576,26 +1526,19 @@ public abstract class TreeBuilder<T> imp
                         case P:
                         case PRE_OR_LISTING:
                         case TABLE:
-                            err("HTML start tag \u201C"
-                                    + name
-                                    + "\u201D in a foreign namespace context.");
-                            while (!isSpecialParentInForeign(stack[currentPtr])) {
-                                pop();
-                            }
-                            continue starttagloop;
                         case FONT:
-                            if (attributes.contains(AttributeName.COLOR)
-                                    || attributes.contains(AttributeName.FACE)
-                                    || attributes.contains(AttributeName.SIZE)) {
-                                err("HTML start tag \u201C"
-                                        + name
-                                        + "\u201D in a foreign namespace context.");
-                                while (!isSpecialParentInForeign(stack[currentPtr])) {
-                                    pop();
-                                }
-                                continue starttagloop;
+                            // re-check FONT to deal with the special case
+                            if (!(group == FONT && !(attributes.contains(AttributeName.COLOR)
+                                    || attributes.contains(AttributeName.FACE) || attributes.contains(AttributeName.SIZE)))) {
+                                errHtmlStartTagInForeignContext(name);
+                                if (!fragment) {
+                                    while (!isSpecialParentInForeign(stack[currentPtr])) {
+                                        popForeign(-1, -1);
+                                    }
+                                    continue starttagloop;
+                                } // else fall thru
                             }
-                            // else fall thru
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         default:
                             if ("http://www.w3.org/2000/svg" == currNs) {
                                 attributes.adjustForSvg();
@@ -1626,41 +1569,79 @@ public abstract class TreeBuilder<T> imp
                 } // foreignObject / annotation-xml
             }
             switch (mode) {
-                case IN_TABLE_BODY:
+                case IN_TEMPLATE:
                     switch (group) {
+                        case COL:
+                            popTemplateMode();
+                            pushTemplateMode(IN_COLUMN_GROUP);
+                            mode = IN_COLUMN_GROUP;
+                            // Reprocess token.
+                            continue;
+                        case CAPTION:
+                        case COLGROUP:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                            popTemplateMode();
+                            pushTemplateMode(IN_TABLE);
+                            mode = IN_TABLE;
+                            // Reprocess token.
+                            continue;
                         case TR:
-                            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
-                            appendToCurrentNodeAndPushElement(
+                            popTemplateMode();
+                            pushTemplateMode(IN_TABLE_BODY);
+                            mode = IN_TABLE_BODY;
+                            // Reprocess token.
+                            continue;
+                        case TD_OR_TH:
+                            popTemplateMode();
+                            pushTemplateMode(IN_ROW);
+                            mode = IN_ROW;
+                            // Reprocess token.
+                            continue;
+                        case META:
+                            checkMetaCharset(attributes);
+                            appendVoidElementToCurrentMayFoster(
                                     elementName,
                                     attributes);
-                            mode = IN_ROW;
+                            selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TITLE:
+                            startTagTitleInHead(elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case BASE:
+                        case LINK_OR_BASEFONT_OR_BGSOUND:
+                            appendVoidElementToCurrentMayFoster(
+                                    elementName,
+                                    attributes);
+                            selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case SCRIPT:
+                            startTagScriptInHead(elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case NOFRAMES:
+                        case STYLE:
+                            startTagGenericRawText(elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TEMPLATE:
+                            startTagTemplateInHead(elementName, attributes);
                             attributes = null; // CPP
                             break starttagloop;
-                        case TD_OR_TH:
-                            err("\u201C" + name
-                                    + "\u201D start tag in table body.");
-                            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
-                            appendToCurrentNodeAndPushElement(
-                                    ElementName.TR,
-                                    HtmlAttributes.EMPTY_ATTRIBUTES);
-                            mode = IN_ROW;
-                            continue;
-                        case CAPTION:
-                        case COL:
-                        case COLGROUP:
-                        case TBODY_OR_THEAD_OR_TFOOT:
-                            eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
-                            if (eltPos == 0) {
-                                errStrayStartTag(name);
-                                break starttagloop;
-                            } else {
-                                clearStackBackTo(eltPos);
-                                pop();
-                                mode = IN_TABLE;
-                                continue;
-                            }
                         default:
-                            // fall through to IN_TABLE
+                            popTemplateMode();
+                            pushTemplateMode(IN_BODY);
+                            mode = IN_BODY;
+                            // Reprocess token.
+                            continue;
                     }
                 case IN_ROW:
                     switch (group) {
@@ -1680,8 +1661,8 @@ public abstract class TreeBuilder<T> imp
                         case TR:
                             eltPos = findLastOrRoot(TreeBuilder.TR);
                             if (eltPos == 0) {
-                                assert fragment;
-                                err("No table row to close.");
+                                assert fragment || isTemplateContents();
+                                errNoTableRowToClose();
                                 break starttagloop;
                             }
                             clearStackBackTo(eltPos);
@@ -1691,6 +1672,44 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_TABLE
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case IN_TABLE_BODY:
+                    switch (group) {
+                        case TR:
+                            clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+                            appendToCurrentNodeAndPushElement(
+                                    elementName,
+                                    attributes);
+                            mode = IN_ROW;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TD_OR_TH:
+                            errStartTagInTableBody(name);
+                            clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
+                            appendToCurrentNodeAndPushElement(
+                                    ElementName.TR,
+                                    HtmlAttributes.EMPTY_ATTRIBUTES);
+                            mode = IN_ROW;
+                            continue;
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                            eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+                            if (eltPos == 0 || stack[eltPos].getGroup() == TEMPLATE) {
+                                assert fragment || isTemplateContents();
+                                errStrayStartTag(name);
+                                break starttagloop;
+                            } else {
+                                clearStackBackTo(eltPos);
+                                pop();
+                                mode = IN_TABLE;
+                                continue;
+                            }
+                        default:
+                            // fall through to IN_TABLE
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_TABLE:
                     intableloop: for (;;) {
                         switch (group) {
@@ -1734,17 +1753,19 @@ public abstract class TreeBuilder<T> imp
                                         HtmlAttributes.EMPTY_ATTRIBUTES);
                                 mode = IN_TABLE_BODY;
                                 continue starttagloop;
+                            case TEMPLATE:
+                                // fall through to IN_HEAD
+                                break intableloop;
                             case TABLE:
-                                err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.");
+                                errTableSeenWhileTableOpen();
                                 eltPos = findLastInTableScope(name);
                                 if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    assert fragment;
+                                    assert fragment || isTemplateContents();
                                     break starttagloop;
                                 }
                                 generateImpliedEndTags();
-                                // XXX is the next if dead code?
                                 if (errorHandler != null && !isCurrent("table")) {
-                                    errNoCheck("Unclosed elements on stack.");
+                                    errNoCheckUnclosedElementsOnStack();
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
@@ -1776,34 +1797,38 @@ public abstract class TreeBuilder<T> imp
                                 attributes = null; // CPP
                                 break starttagloop;
                             case INPUT:
+                                errStartTagInTable(name);
                                 if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
                                         "hidden",
                                         attributes.getValue(AttributeName.TYPE))) {
                                     break intableloop;
                                 }
-                                appendVoidElementToCurrent(
-                                        name, attributes,
+                                appendVoidInputToCurrent(
+                                        attributes,
                                         formPointer);
                                 selfClosing = false;
+                                // [NOCPP[
+                                voidElement = true;
+                                // ]NOCPP]
                                 attributes = null; // CPP
                                 break starttagloop;
                             case FORM:
-                                if (formPointer != null) {
-                                    err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.");
+                                if (formPointer != null || isTemplateContents()) {
+                                    errFormWhenFormOpen();
                                     break starttagloop;
                                 } else {
-                                    err("Start tag \u201Cform\u201D seen in \u201Ctable\u201D.");
+                                    errStartTagInTable(name);
                                     appendVoidFormToCurrent(attributes);
                                     attributes = null; // CPP
                                     break starttagloop;
                                 }
                             default:
-                                err("Start tag \u201C" + name
-                                        + "\u201D seen in \u201Ctable\u201D.");
+                                errStartTagInTable(name);
                                 // fall through to IN_BODY
                                 break intableloop;
                         }
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_CAPTION:
                     switch (group) {
                         case CAPTION:
@@ -1812,14 +1837,15 @@ public abstract class TreeBuilder<T> imp
                         case TBODY_OR_THEAD_OR_TFOOT:
                         case TR:
                         case TD_OR_TH:
-                            errStrayStartTag(name);
                             eltPos = findLastInTableScope("caption");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment || isTemplateContents();
+                                errStrayStartTag(name);
                                 break starttagloop;
                             }
                             generateImpliedEndTags();
                             if (errorHandler != null && currentPtr != eltPos) {
-                                errNoCheck("Unclosed elements on stack.");
+                                errNoCheckUnclosedElementsOnStack();
                             }
                             while (currentPtr >= eltPos) {
                                 pop();
@@ -1830,6 +1856,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_CELL:
                     switch (group) {
                         case CAPTION:
@@ -1840,7 +1867,7 @@ public abstract class TreeBuilder<T> imp
                         case TD_OR_TH:
                             eltPos = findLastInTableScopeTdTh();
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                err("No cell to close.");
+                                errNoCellToClose();
                                 break starttagloop;
                             } else {
                                 closeTheCell(eltPos);
@@ -1849,16 +1876,17 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case FRAMESET_OK:
                     switch (group) {
                         case FRAMESET:
                             if (mode == FRAMESET_OK) {
                                 if (currentPtr == 0 || stack[1].getGroup() != BODY) {
-                                    assert fragment;
+                                    assert fragment || isTemplateContents();
                                     errStrayStartTag(name);
                                     break starttagloop;
                                 } else {
-                                    err("\u201Cframeset\u201D start tag seen.");
+                                    errFramesetStart();
                                     detachFromParent(stack[1].node);
                                     while (currentPtr > 0) {
                                         pop();
@@ -1883,10 +1911,11 @@ public abstract class TreeBuilder<T> imp
                         case OBJECT:
                         case TABLE:
                         case AREA_OR_WBR:
+                        case KEYGEN:
                         case BR:
-                        case EMBED_OR_IMG:
+                        case EMBED:
+                        case IMG:
                         case INPUT:
-                        case KEYGEN:
                         case HR:
                         case TEXTAREA:
                         case XMP:
@@ -1899,16 +1928,17 @@ public abstract class TreeBuilder<T> imp
                                 framesetOk = false;
                                 mode = IN_BODY;
                             }
-                            // fall through to IN_BODY
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         default:
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_BODY:
                     inbodyloop: for (;;) {
                         switch (group) {
                             case HTML:
                                 errStrayStartTag(name);
-                                if (!fragment) {
+                                if (!fragment && !isTemplateContents()) {
                                     addAttributesToHtml(attributes);
                                     attributes = null; // CPP
                                 }
@@ -1919,17 +1949,16 @@ public abstract class TreeBuilder<T> imp
                             case STYLE:
                             case SCRIPT:
                             case TITLE:
-                            case COMMAND:
+                            case TEMPLATE:
                                 // Fall through to IN_HEAD
                                 break inbodyloop;
                             case BODY:
-                                if (currentPtr == 0
-                                        || stack[1].getGroup() != BODY) {
-                                    assert fragment;
+                                if (currentPtr == 0 || stack[1].getGroup() != BODY || isTemplateContents()) {
+                                    assert fragment || isTemplateContents();
                                     errStrayStartTag(name);
                                     break starttagloop;
                                 }
-                                err("\u201Cbody\u201D start tag found but the \u201Cbody\u201D element is already open.");
+                                errFooSeenWhenFooOpen(name);
                                 framesetOk = false;
                                 if (mode == FRAMESET_OK) {
                                     mode = IN_BODY;
@@ -1941,7 +1970,7 @@ public abstract class TreeBuilder<T> imp
                             case P:
                             case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
                             case UL_OR_OL_OR_DL:
-                            case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
+                            case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY:
                                 implicitlyCloseP();
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
@@ -1951,7 +1980,7 @@ public abstract class TreeBuilder<T> imp
                             case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                                 implicitlyCloseP();
                                 if (stack[currentPtr].getGroup() == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
-                                    err("Heading cannot be a child of another heading.");
+                                    errHeadingWhenHeadingOpen();
                                     pop();
                                 }
                                 appendToCurrentNodeAndPushElementMayFoster(
@@ -1975,8 +2004,8 @@ public abstract class TreeBuilder<T> imp
                                 attributes = null; // CPP
                                 break starttagloop;
                             case FORM:
-                                if (formPointer != null) {
-                                    err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.");
+                                if (formPointer != null && !isTemplateContents()) {
+                                    errFormWhenFormOpen();
                                     break starttagloop;
                                 } else {
                                     implicitlyCloseP();
@@ -2001,10 +2030,11 @@ public abstract class TreeBuilder<T> imp
                                             pop();
                                         }
                                         break;
-                                    } else if (node.isScoping()
-                                            || (node.isSpecial()
-                                                    && node.name != "p"
-                                                    && node.name != "address" && node.name != "div")) {
+                                    } else if (eltPos == 0 || (node.isSpecial()
+                                            && (node.ns != "http://www.w3.org/1999/xhtml"
+                                                    || (node.name != "p"
+                                                            && node.name != "address"
+                                                            && node.name != "div")))) {
                                         break;
                                     }
                                     eltPos--;
@@ -2027,7 +2057,7 @@ public abstract class TreeBuilder<T> imp
                             case A:
                                 int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a");
                                 if (activeAPos != -1) {
-                                    err("An \u201Ca\u201D start tag seen with already an active \u201Ca\u201D element.");
+                                    errFooSeenWhenFooOpen(name);
                                     StackNode<T> activeA = listOfActiveFormattingElements[activeAPos];
                                     activeA.retain();
                                     adoptionAgencyEndTag("a");
@@ -2036,7 +2066,7 @@ public abstract class TreeBuilder<T> imp
                                     if (activeAPos != -1) {
                                         removeFromListOfActiveFormattingElements(activeAPos);
                                     }
-                                    activeA.release();
+                                    activeA.release(this);
                                 }
                                 reconstructTheActiveFormattingElements();
                                 appendToCurrentNodeAndPushFormattingElementMayFoster(
@@ -2047,7 +2077,7 @@ public abstract class TreeBuilder<T> imp
                             case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
                             case FONT:
                                 reconstructTheActiveFormattingElements();
-                                maybeForgetEarlierDuplicateFormattingElement(elementName.name, attributes);
+                                maybeForgetEarlierDuplicateFormattingElement(elementName.getName(), attributes);
                                 appendToCurrentNodeAndPushFormattingElementMayFoster(
                                         elementName,
                                         attributes);
@@ -2056,7 +2086,7 @@ public abstract class TreeBuilder<T> imp
                             case NOBR:
                                 reconstructTheActiveFormattingElements();
                                 if (TreeBuilder.NOT_FOUND_ON_STACK != findLastInScope("nobr")) {
-                                    err("\u201Cnobr\u201D start tag seen when there was an open \u201Cnobr\u201D element in scope.");
+                                    errFooSeenWhenFooOpen(name);
                                     adoptionAgencyEndTag("nobr");
                                     reconstructTheActiveFormattingElements();
                                 }
@@ -2068,8 +2098,7 @@ public abstract class TreeBuilder<T> imp
                             case BUTTON:
                                 eltPos = findLastInScope(name);
                                 if (eltPos != TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    err("\u201Cbutton\u201D start tag seen when there was an open \u201Cbutton\u201D element in scope.");
-
+                                    errFooSeenWhenFooOpen(name);
                                     generateImpliedEndTags();
                                     if (errorHandler != null
                                             && !isCurrent(name)) {
@@ -2116,15 +2145,20 @@ public abstract class TreeBuilder<T> imp
                                 attributes = null; // CPP
                                 break starttagloop;
                             case BR:
-                            case EMBED_OR_IMG:
+                            case EMBED:
                             case AREA_OR_WBR:
+                            case KEYGEN:
                                 reconstructTheActiveFormattingElements();
                                 // FALL THROUGH to PARAM_OR_SOURCE_OR_TRACK
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case PARAM_OR_SOURCE_OR_TRACK:
                                 appendVoidElementToCurrentMayFoster(
                                         elementName,
                                         attributes);
                                 selfClosing = false;
+                                // [NOCPP[
+                                voidElement = true;
+                                // ]NOCPP]
                                 attributes = null; // CPP
                                 break starttagloop;
                             case HR:
@@ -2133,92 +2167,26 @@ public abstract class TreeBuilder<T> imp
                                         elementName,
                                         attributes);
                                 selfClosing = false;
+                                // [NOCPP[
+                                voidElement = true;
+                                // ]NOCPP]
                                 attributes = null; // CPP
                                 break starttagloop;
                             case IMAGE:
-                                err("Saw a start tag \u201Cimage\u201D.");
+                                errImage();
                                 elementName = ElementName.IMG;
                                 continue starttagloop;
-                            case KEYGEN:
+                            case IMG:
                             case INPUT:
                                 reconstructTheActiveFormattingElements();
                                 appendVoidElementToCurrentMayFoster(
-                                        name, attributes,
+                                        elementName, attributes,
                                         formPointer);
                                 selfClosing = false;
-                                attributes = null; // CPP
-                                break starttagloop;
-                            case ISINDEX:
-                                err("\u201Cisindex\u201D seen.");
-                                if (formPointer != null) {
-                                    break starttagloop;
-                                }
-                                implicitlyCloseP();
-                                HtmlAttributes formAttrs = new HtmlAttributes(0);
-                                int actionIndex = attributes.getIndex(AttributeName.ACTION);
-                                if (actionIndex > -1) {
-                                    formAttrs.addAttribute(
-                                            AttributeName.ACTION,
-                                            attributes.getValue(actionIndex)
-                                            // [NOCPP[
-                                            , XmlViolationPolicy.ALLOW
-                                    // ]NOCPP]
-                                    );
-                                }
-                                appendToCurrentNodeAndPushFormElementMayFoster(formAttrs);
-                                appendVoidElementToCurrentMayFoster(
-                                        ElementName.HR,
-                                        HtmlAttributes.EMPTY_ATTRIBUTES);
-                                appendToCurrentNodeAndPushElementMayFoster(
-                                        ElementName.LABEL,
-                                        HtmlAttributes.EMPTY_ATTRIBUTES);
-                                int promptIndex = attributes.getIndex(AttributeName.PROMPT);
-                                if (promptIndex > -1) {
-                                    @Auto char[] prompt = Portability.newCharArrayFromString(attributes.getValue(promptIndex));
-                                    appendCharacters(stack[currentPtr].node,
-                                            prompt, 0, prompt.length);
-                                } else {
-                                    appendIsindexPrompt(stack[currentPtr].node);
-                                }
-                                HtmlAttributes inputAttributes = new HtmlAttributes(
-                                        0);
-                                inputAttributes.addAttribute(
-                                        AttributeName.NAME,
-                                        Portability.newStringFromLiteral("isindex")
-                                        // [NOCPP[
-                                        , XmlViolationPolicy.ALLOW
+                                // [NOCPP[
+                                voidElement = true;
                                 // ]NOCPP]
-                                );
-                                for (int i = 0; i < attributes.getLength(); i++) {
-                                    AttributeName attributeQName = attributes.getAttributeName(i);
-                                    if (AttributeName.NAME == attributeQName
-                                            || AttributeName.PROMPT == attributeQName) {
-                                        attributes.releaseValue(i);
-                                    } else if (AttributeName.ACTION != attributeQName) {
-                                        inputAttributes.addAttribute(
-                                                attributeQName,
-                                                attributes.getValue(i)
-                                                // [NOCPP[
-                                                , XmlViolationPolicy.ALLOW
-                                        // ]NOCPP]
-
-                                        );
-                                    }
-                                }
-                                attributes.clearWithoutReleasingContents();
-                                appendVoidElementToCurrentMayFoster(
-                                        "input",
-                                        inputAttributes, formPointer);
-                                pop(); // label
-                                appendVoidElementToCurrentMayFoster(
-                                        ElementName.HR,
-                                        HtmlAttributes.EMPTY_ATTRIBUTES);
-                                pop(); // form
-                                selfClosing = false;
-                                // Portability.delete(formAttrs);
-                                // Portability.delete(inputAttributes);
-                                // Don't delete attributes, they are deleted
-                                // later
+                                attributes = null; // CPP
                                 break starttagloop;
                             case TEXTAREA:
                                 appendToCurrentNodeAndPushElementMayFoster(
@@ -2251,19 +2219,12 @@ public abstract class TreeBuilder<T> imp
                                             attributes);
                                     attributes = null; // CPP
                                     break starttagloop;
-                                } else {
-                                    // fall through
                                 }
+                                // CPPONLY: MOZ_FALLTHROUGH;
                             case NOFRAMES:
                             case IFRAME:
                             case NOEMBED:
-                                appendToCurrentNodeAndPushElementMayFoster(
-                                        elementName,
-                                        attributes);
-                                originalMode = mode;
-                                mode = TEXT;
-                                tokenizer.setStateAndEndTagExpectation(
-                                        Tokenizer.RAWTEXT, elementName);
+                                startTagGenericRawText(elementName, attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
                             case SELECT:
@@ -2297,36 +2258,36 @@ public abstract class TreeBuilder<T> imp
                                         attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
-                            case RT_OR_RP:
-                                /*
-                                 * If the stack of open elements has a ruby
-                                 * element in scope, then generate implied end
-                                 * tags. If the current node is not then a ruby
-                                 * element, this is a parse error; pop all the
-                                 * nodes from the current node up to the node
-                                 * immediately before the bottommost ruby
-                                 * element on the stack of open elements.
-                                 * 
-                                 * Insert an HTML element for the token.
-                                 */
+                            case RB_OR_RTC:
                                 eltPos = findLastInScope("ruby");
                                 if (eltPos != NOT_FOUND_ON_STACK) {
                                     generateImpliedEndTags();
                                 }
                                 if (eltPos != currentPtr) {
-                                    if (errorHandler != null) {
-                                        if (eltPos != NOT_FOUND_ON_STACK) {
-
-                                            errNoCheck("Start tag \u201C"
-                                                    + name
-                                                    + "\u201D seen without a \u201Cruby\u201D element being open.");
+                                    if (eltPos == NOT_FOUND_ON_STACK) {
+                                        errStartTagSeenWithoutRuby(name);
+                                    } else {
+                                        errUnclosedChildrenInRuby();
+                                    }
+                                }
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        elementName,
+                                        attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case RT_OR_RP:
+                                eltPos = findLastInScope("ruby");
+                                if (eltPos != NOT_FOUND_ON_STACK) {
+                                    generateImpliedEndTagsExceptFor("rtc");
+                                }
+                                if (eltPos != currentPtr) {
+                                    if (!isCurrent("rtc")) {
+                                        if (eltPos == NOT_FOUND_ON_STACK) {
+                                            errStartTagSeenWithoutRuby(name);
                                         } else {
-                                            errNoCheck("Unclosed children in \u201Cruby\u201D.");
+                                            errUnclosedChildrenInRuby();
                                         }
                                     }
-                                    while (currentPtr > eltPos) {
-                                        pop();
-                                    }
                                 }
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
@@ -2371,7 +2332,7 @@ public abstract class TreeBuilder<T> imp
                             case HEAD:
                                 errStrayStartTag(name);
                                 break starttagloop;
-                            case OUTPUT_OR_LABEL:
+                            case OUTPUT:
                                 reconstructTheActiveFormattingElements();
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
@@ -2387,36 +2348,33 @@ public abstract class TreeBuilder<T> imp
                                 break starttagloop;
                         }
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_HEAD:
                     inheadloop: for (;;) {
                         switch (group) {
                             case HTML:
                                 errStrayStartTag(name);
-                                if (!fragment) {
+                                if (!fragment && !isTemplateContents()) {
                                     addAttributesToHtml(attributes);
                                     attributes = null; // CPP
                                 }
                                 break starttagloop;
                             case BASE:
-                            case COMMAND:
+                            case LINK_OR_BASEFONT_OR_BGSOUND:
                                 appendVoidElementToCurrentMayFoster(
                                         elementName,
                                         attributes);
                                 selfClosing = false;
+                                // [NOCPP[
+                                voidElement = true;
+                                // ]NOCPP]
                                 attributes = null; // CPP
                                 break starttagloop;
                             case META:
-                            case LINK_OR_BASEFONT_OR_BGSOUND:
                                 // Fall through to IN_HEAD_NOSCRIPT
                                 break inheadloop;
                             case TITLE:
-                                appendToCurrentNodeAndPushElementMayFoster(
-                                        elementName,
-                                        attributes);
-                                originalMode = mode;
-                                mode = TEXT;
-                                tokenizer.setStateAndEndTagExpectation(
-                                        Tokenizer.RCDATA, elementName);
+                                startTagTitleInHead(elementName, attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
                             case NOSCRIPT:
@@ -2437,48 +2395,37 @@ public abstract class TreeBuilder<T> imp
                                 attributes = null; // CPP
                                 break starttagloop;
                             case SCRIPT:
-                                // XXX need to manage much more stuff
-                                // here if
-                                // supporting
-                                // document.write()
-                                appendToCurrentNodeAndPushElementMayFoster(
-                                        elementName,
-                                        attributes);
-                                originalMode = mode;
-                                mode = TEXT;
-                                tokenizer.setStateAndEndTagExpectation(
-                                        Tokenizer.SCRIPT_DATA, elementName);
+                                startTagScriptInHead(elementName, attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
                             case STYLE:
                             case NOFRAMES:
-                                appendToCurrentNodeAndPushElementMayFoster(
-                                        elementName,
-                                        attributes);
-                                originalMode = mode;
-                                mode = TEXT;
-                                tokenizer.setStateAndEndTagExpectation(
-                                        Tokenizer.RAWTEXT, elementName);
+                                startTagGenericRawText(elementName, attributes);
                                 attributes = null; // CPP
                                 break starttagloop;
                             case HEAD:
                                 /* Parse error. */
-                                err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
+                                errFooSeenWhenFooOpen(name);
                                 /* Ignore the token. */
                                 break starttagloop;
+                            case TEMPLATE:
+                                startTagTemplateInHead(elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
                             default:
                                 pop();
                                 mode = AFTER_HEAD;
                                 continue starttagloop;
                         }
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_HEAD_NOSCRIPT:
                     switch (group) {
                         case HTML:
                             // XXX did Hixie really mean to omit "base"
                             // here?
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2488,6 +2435,9 @@ public abstract class TreeBuilder<T> imp
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             attributes = null; // CPP
                             break starttagloop;
                         case META:
@@ -2496,6 +2446,9 @@ public abstract class TreeBuilder<T> imp
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             attributes = null; // CPP
                             break starttagloop;
                         case STYLE:
@@ -2510,14 +2463,13 @@ public abstract class TreeBuilder<T> imp
                             attributes = null; // CPP
                             break starttagloop;
                         case HEAD:
-                            err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
+                            errFooSeenWhenFooOpen(name);
                             break starttagloop;
                         case NOSCRIPT:
-                            err("Start tag for \u201Cnoscript\u201D seen when \u201Cnoscript\u201D was already open.");
+                            errFooSeenWhenFooOpen(name);
                             break starttagloop;
                         default:
-                            err("Bad start tag in \u201C" + name
-                                    + "\u201D in \u201Chead\u201D.");
+                            errBadStartTagInNoscriptInHead(name);
                             pop();
                             mode = IN_HEAD;
                             continue;
@@ -2526,7 +2478,7 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2536,12 +2488,19 @@ public abstract class TreeBuilder<T> imp
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TEMPLATE:
+                            startTagTemplateInHead(elementName, attributes);
                             attributes = null; // CPP
                             break starttagloop;
                         default:
-                            if (currentPtr == 0) {
-                                assert fragment;
-                                err("Garbage in \u201Ccolgroup\u201D fragment.");
+                            if (currentPtr == 0 || stack[currentPtr].getGroup() == TEMPLATE) {
+                                assert fragment || isTemplateContents();
+                                errGarbageInColgroup();
                                 break starttagloop;
                             }
                             pop();
@@ -2555,9 +2514,7 @@ public abstract class TreeBuilder<T> imp
                         case TR:
                         case TD_OR_TH:
                         case TABLE:
-                            err("\u201C"
-                                    + name
-                                    + "\u201D start tag with \u201Cselect\u201D open.");
+                            errStartTagWithSelectOpen(name);
                             eltPos = findLastInTableScope("select");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 assert fragment;
@@ -2571,6 +2528,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_SELECT
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_SELECT:
                     switch (group) {
                         case HTML:
@@ -2602,11 +2560,11 @@ public abstract class TreeBuilder<T> imp
                             attributes = null; // CPP
                             break starttagloop;
                         case SELECT:
-                            err("\u201Cselect\u201D start tag where end tag expected.");
+                            errStartSelectWhereEndSelectExpected();
                             eltPos = findLastInTableScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 assert fragment;
-                                err("No \u201Cselect\u201D in table scope.");
+                                errNoSelectInTableScope();
                                 break starttagloop;
                             } else {
                                 while (currentPtr >= eltPos) {
@@ -2617,10 +2575,7 @@ public abstract class TreeBuilder<T> imp
                             }
                         case INPUT:
                         case TEXTAREA:
-                        case KEYGEN:
-                            err("\u201C"
-                                    + name
-                                    + "\u201D start tag seen in \u201Cselect\2201D.");
+                            errStartTagWithSelectOpen(name);
                             eltPos = findLastInTableScope("select");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 assert fragment;
@@ -2632,17 +2587,25 @@ public abstract class TreeBuilder<T> imp
                             resetTheInsertionMode();
                             continue;
                         case SCRIPT:
-                            // XXX need to manage much more stuff
-                            // here if
-                            // supporting
-                            // document.write()
-                            appendToCurrentNodeAndPushElementMayFoster(
-                                    elementName,
-                                    attributes);
-                            originalMode = mode;
-                            mode = TEXT;
-                            tokenizer.setStateAndEndTagExpectation(
-                                    Tokenizer.SCRIPT_DATA, elementName);
+                            startTagScriptInHead(elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TEMPLATE:
+                            startTagTemplateInHead(elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case HR:
+                            if (isCurrent("option")) {
+                                pop();
+                            }
+                            if (isCurrent("optgroup")) {
+                                pop();
+                            }
+                            appendVoidElementToCurrent(elementName, attributes);
+                            selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             attributes = null; // CPP
                             break starttagloop;
                         default:
@@ -2653,7 +2616,7 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2676,16 +2639,20 @@ public abstract class TreeBuilder<T> imp
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             attributes = null; // CPP
                             break starttagloop;
                         default:
                             // fall through to AFTER_FRAMESET
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case AFTER_FRAMESET:
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2708,29 +2675,12 @@ public abstract class TreeBuilder<T> imp
                     /*
                      * Parse error.
                      */
-                    // [NOCPP[
-                    switch (doctypeExpectation) {
-                        case AUTO:
-                            err("Start tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML:
-                            err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML401_STRICT:
-                            err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                            break;
-                        case HTML401_TRANSITIONAL:
-                            err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                            break;
-                        case NO_DOCTYPE_ERRORS:
-                    }
-                    // ]NOCPP]
+                    errStartTagWithoutDoctype();
                     /*
-                     * 
+                     *
                      * Set the document to quirks mode.
                      */
-                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
-                            false);
+                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null);
                     /*
                      * Then, switch to the root element mode of the tree
                      * construction stage
@@ -2777,7 +2727,7 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2785,12 +2735,12 @@ public abstract class TreeBuilder<T> imp
                         case HEAD:
                             /*
                              * A start tag whose tag name is "head"
-                             * 
+                             *
                              * Create an element for the token.
-                             * 
+                             *
                              * Set the head element pointer to this new element
                              * node.
-                             * 
+                             *
                              * Append the new element to the current node and
                              * push it onto the stack of open elements.
                              */
@@ -2804,7 +2754,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             /*
                              * Any other start tag token
-                             * 
+                             *
                              * Act as if a start tag token with the tag name
                              * "head" and no attributes had been seen,
                              */
@@ -2812,7 +2762,7 @@ public abstract class TreeBuilder<T> imp
                             mode = IN_HEAD;
                             /*
                              * then reprocess the current token.
-                             * 
+                             *
                              * This will result in an empty head element being
                              * generated, with the current token being
                              * reprocessed in the "after head" insertion mode.
@@ -2823,7 +2773,7 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2849,39 +2799,44 @@ public abstract class TreeBuilder<T> imp
                             mode = IN_FRAMESET;
                             attributes = null; // CPP
                             break starttagloop;
-                        case BASE:
-                            err("\u201Cbase\u201D element outside \u201Chead\u201D.");
+                        case TEMPLATE:
+                            errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
-                            appendVoidElementToCurrentMayFoster(
-                                    elementName,
-                                    attributes);
-                            selfClosing = false;
-                            pop(); // head
+                            StackNode<T> headOnStack = stack[currentPtr];
+                            startTagTemplateInHead(elementName, attributes);
+                            removeFromStack(headOnStack);
                             attributes = null; // CPP
                             break starttagloop;
+                        case BASE:
                         case LINK_OR_BASEFONT_OR_BGSOUND:
-                            err("\u201Clink\u201D element outside \u201Chead\u201D.");
+                            errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
                             appendVoidElementToCurrentMayFoster(
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             pop(); // head
                             attributes = null; // CPP
                             break starttagloop;
                         case META:
-                            err("\u201Cmeta\u201D element outside \u201Chead\u201D.");
+                            errFooBetweenHeadAndBody(name);
                             checkMetaCharset(attributes);
                             pushHeadPointerOntoStack();
                             appendVoidElementToCurrentMayFoster(
                                     elementName,
                                     attributes);
                             selfClosing = false;
+                            // [NOCPP[
+                            voidElement = true;
+                            // ]NOCPP]
                             pop(); // head
                             attributes = null; // CPP
                             break starttagloop;
                         case SCRIPT:
-                            err("\u201Cscript\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+                            errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
                             appendToCurrentNodeAndPushElement(
                                     elementName,
@@ -2894,9 +2849,7 @@ public abstract class TreeBuilder<T> imp
                             break starttagloop;
                         case STYLE:
                         case NOFRAMES:
-                            err("\u201C"
-                                    + name
-                                    + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+                            errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
                             appendToCurrentNodeAndPushElement(
                                     elementName,
@@ -2908,7 +2861,7 @@ public abstract class TreeBuilder<T> imp
                             attributes = null; // CPP
                             break starttagloop;
                         case TITLE:
-                            err("\u201Ctitle\u201D element outside \u201Chead\u201D.");
+                            errFooBetweenHeadAndBody(name);
                             pushHeadPointerOntoStack();
                             appendToCurrentNodeAndPushElement(
                                     elementName,
@@ -2931,7 +2884,7 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
@@ -2946,19 +2899,13 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case HTML:
                             errStrayStartTag(name);
-                            if (!fragment) {
+                            if (!fragment && !isTemplateContents()) {
                                 addAttributesToHtml(attributes);
                                 attributes = null; // CPP
                             }
                             break starttagloop;
                         case NOFRAMES:
-                            appendToCurrentNodeAndPushElementMayFoster(
-                                    elementName,
-                                    attributes);
-                            originalMode = mode;
-                            mode = TEXT;
-                            tokenizer.setStateAndEndTagExpectation(
-                                    Tokenizer.SCRIPT_DATA, elementName);
+                            startTagGenericRawText(elementName, attributes);
                             attributes = null; // CPP
                             break starttagloop;
                         default:
@@ -2971,12 +2918,58 @@ public abstract class TreeBuilder<T> imp
                                         // fails
             }
         }
-        if (errorHandler != null && selfClosing) {
-            errNoCheck("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.");
-        }
-        if (attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
-            Portability.delete(attributes);
+        if (selfClosing) {
+            errSelfClosing();
+        // [NOCPP[
+        } else if (wasSelfClosing && voidElement
+                && tokenizer.getErrorProfile() != null
+                && tokenizer.getErrorProfile().get("html-strict") != null) {
+            warn("Trailing slash on void elements has no effect and interacts"
+                    + " badly with unquoted attribute values.");
+        // ]NOCPP]
         }
+        // CPPONLY: if (mBuilder == null && attributes != HtmlAttributes.EMPTY_ATTRIBUTES) {
+        // CPPONLY:    Portability.delete(attributes);
+        // CPPONLY: }
+    }
+
+    private void startTagTitleInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+        appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+        originalMode = mode;
+        mode = TEXT;
+        tokenizer.setStateAndEndTagExpectation(Tokenizer.RCDATA, elementName);
+    }
+
+    private void startTagGenericRawText(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+        appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+        originalMode = mode;
+        mode = TEXT;
+        tokenizer.setStateAndEndTagExpectation(Tokenizer.RAWTEXT, elementName);
+    }
+
+    private void startTagScriptInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+        // XXX need to manage much more stuff here if supporting document.write()
+        appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
+        originalMode = mode;
+        mode = TEXT;
+        tokenizer.setStateAndEndTagExpectation(Tokenizer.SCRIPT_DATA, elementName);
+    }
+
+    private void startTagTemplateInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
+        appendToCurrentNodeAndPushElement(elementName, attributes);
+        insertMarker();
+        framesetOk = false;
+        originalMode = mode;
+        mode = IN_TEMPLATE;
+        pushTemplateMode(IN_TEMPLATE);
+    }
+
+    private boolean isTemplateContents() {
+        return TreeBuilder.NOT_FOUND_ON_STACK != findLast("template");
+    }
+
+    private boolean isTemplateModeStackEmpty() {
+        return templateModePtr == -1;
     }
 
     private boolean isSpecialParentInForeign(StackNode<T> stackNode) {
@@ -2986,16 +2979,36 @@ public abstract class TreeBuilder<T> imp
                 || (("http://www.w3.org/1998/Math/MathML" == ns) && (stackNode.getGroup() == MI_MO_MN_MS_MTEXT));
     }
 
+    private T getDeclarativeShadowRoot(T currentNode, T templateNode, HtmlAttributes attributes) {
+        if (!isAllowDeclarativeShadowRoots()) {
+            return null;
+        }
+
+        String shadowRootMode = attributes.getValue(AttributeName.SHADOWROOTMODE);
+        if (shadowRootMode == null) {
+            return null;
+        }
+
+        boolean shadowRootIsClonable = attributes.contains(AttributeName.SHADOWROOTCLONABLE);
+        boolean shadowRootIsSerializable = attributes.contains(AttributeName.SHADOWROOTSERIALIZABLE);
+        boolean shadowRootDelegatesFocus = attributes.contains(AttributeName.SHADOWROOTDELEGATESFOCUS);
+        String shadowRootReferenceTarget = attributes.getValue(AttributeName.SHADOWROOTREFERENCETARGET);
+
+        return getShadowRootFromHost(currentNode, templateNode, shadowRootMode, shadowRootIsClonable, shadowRootIsSerializable, shadowRootDelegatesFocus, shadowRootReferenceTarget);
+    }
+
     /**
-     * 
+     *
      * <p>
      * C++ memory note: The return value must be released.
-     * 
+     *
      * @return
      * @throws SAXException
      * @throws StopSniffingException
      */
-    public static String extractCharsetFromContent(String attributeValue) {
+    public static String extractCharsetFromContent(String attributeValue
+        // CPPONLY: , TreeBuilder tb
+    ) {
         // This is a bit ugly. Converting the string to char array in order to
         // make the portability layer smaller.
         int charsetState = CHARSET_INITIAL;
@@ -3141,15 +3154,20 @@ public abstract class TreeBuilder<T> imp
                     }
             }
         }
-        String charset = null;
         if (start != -1) {
             if (end == -1) {
-                end = buffer.length;
+                if (charsetState == CHARSET_UNQUOTED) {
+                    end = buffer.length;
+                } else {
+                    return null;
+                }
             }
-            charset = Portability.newStringFromBuffer(buffer, start, end
-                    - start);
+            return Portability.newStringFromBuffer(buffer, start, end
+                    - start
+                // CPPONLY: , tb, false
+            );
         }
-        return charset;
+        return null;
     }
 
     private void checkMetaCharset(HtmlAttributes attributes)
@@ -3159,7 +3177,7 @@ public abstract class TreeBuilder<T> imp
             if (tokenizer.internalEncodingDeclaration(charset)) {
                 requestSuspension();
                 return;
-            }            
+            }
             return;
         }
         if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
@@ -3169,12 +3187,14 @@ public abstract class TreeBuilder<T> imp
         }
         String content = attributes.getValue(AttributeName.CONTENT);
         if (content != null) {
-            String extract = TreeBuilder.extractCharsetFromContent(content);
+            String extract = TreeBuilder.extractCharsetFromContent(content
+                // CPPONLY: , this
+            );
             // remember not to return early without releasing the string
             if (extract != null) {
                 if (tokenizer.internalEncodingDeclaration(extract)) {
                     requestSuspension();
-                }                
+                }
             }
             Portability.releaseString(extract);
         }
@@ -3185,20 +3205,26 @@ public abstract class TreeBuilder<T> imp
         needToDropLF = false;
         int eltPos;
         int group = elementName.getGroup();
-        @Local String name = elementName.name;
+        @Local String name = elementName.getName();
         endtagloop: for (;;) {
             if (isInForeign()) {
-                if (errorHandler != null && stack[currentPtr].name != name) {
-                    errNoCheck("End tag \u201C"
-                            + name
-                            + "\u201D did not match the name of the current open element (\u201C"
-                            + stack[currentPtr].popName + "\u201D).");
+                if (stack[currentPtr].name != name) {
+                    if (currentPtr == 0) {
+                        errStrayEndTag(name);
+                    } else {
+                        errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr].popName);
+                    }
                 }
                 eltPos = currentPtr;
+                int origPos = currentPtr;
                 for (;;) {
+                    if (eltPos == 0) {
+                        assert fragment: "We can get this close to the root of the stack in foreign content only in the fragment case.";
+                        break endtagloop;
+                    }
                     if (stack[eltPos].name == name) {
                         while (currentPtr >= eltPos) {
-                            pop();
+                            popForeign(origPos, eltPos);
                         }
                         break endtagloop;
                     }
@@ -3208,13 +3234,23 @@ public abstract class TreeBuilder<T> imp
                 }
             }
             switch (mode) {
+                case IN_TEMPLATE:
+                    switch (group) {
+                        case TEMPLATE:
+                            // fall through to IN_HEAD
+                            break;
+                        default:
+                            errStrayEndTag(name);
+                            break endtagloop;
+                    }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_ROW:
                     switch (group) {
                         case TR:
                             eltPos = findLastOrRoot(TreeBuilder.TR);
                             if (eltPos == 0) {
-                                assert fragment;
-                                err("No table row to close.");
+                                assert fragment || isTemplateContents();
+                                errNoTableRowToClose();
                                 break endtagloop;
                             }
                             clearStackBackTo(eltPos);
@@ -3224,8 +3260,8 @@ public abstract class TreeBuilder<T> imp
                         case TABLE:
                             eltPos = findLastOrRoot(TreeBuilder.TR);
                             if (eltPos == 0) {
-                                assert fragment;
-                                err("No table row to close.");
+                                assert fragment || isTemplateContents();
+                                errNoTableRowToClose();
                                 break endtagloop;
                             }
                             clearStackBackTo(eltPos);
@@ -3239,8 +3275,8 @@ public abstract class TreeBuilder<T> imp
                             }
                             eltPos = findLastOrRoot(TreeBuilder.TR);
                             if (eltPos == 0) {
-                                assert fragment;
-                                err("No table row to close.");
+                                assert fragment || isTemplateContents();
+                                errNoTableRowToClose();
                                 break endtagloop;
                             }
                             clearStackBackTo(eltPos);
@@ -3258,6 +3294,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_TABLE
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_TABLE_BODY:
                     switch (group) {
                         case TBODY_OR_THEAD_OR_TFOOT:
@@ -3271,9 +3308,9 @@ public abstract class TreeBuilder<T> imp
                             mode = IN_TABLE;
                             break endtagloop;
                         case TABLE:
-                            eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
-                            if (eltPos == 0) {
-                                assert fragment;
+                            eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
+                            if (eltPos == 0 || stack[eltPos].getGroup() == TEMPLATE) {
+                                assert fragment || isTemplateContents();
                                 errStrayEndTag(name);
                                 break endtagloop;
                             }
@@ -3293,12 +3330,13 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_TABLE
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_TABLE:
                     switch (group) {
                         case TABLE:
                             eltPos = findLast("table");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                assert fragment;
+                                assert fragment || isTemplateContents();
                                 errStrayEndTag(name);
                                 break endtagloop;
                             }
@@ -3317,10 +3355,14 @@ public abstract class TreeBuilder<T> imp
                         case TR:
                             errStrayEndTag(name);
                             break endtagloop;
+                        case TEMPLATE:
+                            // fall through to IN_HEAD
+                            break;
                         default:
                             errStrayEndTag(name);
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_CAPTION:
                     switch (group) {
                         case CAPTION:
@@ -3339,9 +3381,11 @@ public abstract class TreeBuilder<T> imp
                             mode = IN_TABLE;
                             break endtagloop;
                         case TABLE:
-                            err("\u201Ctable\u201D closed but \u201Ccaption\u201D was still open.");
                             eltPos = findLastInTableScope("caption");
+
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment || isTemplateContents();
+                                errStrayEndTag(name);
                                 break endtagloop;
                             }
                             generateImpliedEndTags();
@@ -3366,6 +3410,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_CELL:
                     switch (group) {
                         case TD_OR_TH:
@@ -3388,6 +3433,7 @@ public abstract class TreeBuilder<T> imp
                         case TBODY_OR_THEAD_OR_TFOOT:
                         case TR:
                             if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert name == "tbody" || name == "tfoot" || name == "thead" || fragment || isTemplateContents();
                                 errStrayEndTag(name);
                                 break endtagloop;
                             }
@@ -3403,12 +3449,13 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_BODY
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case FRAMESET_OK:
                 case IN_BODY:
                     switch (group) {
                         case BODY:
                             if (!isSecondOnStackBody()) {
-                                assert fragment;
+                                assert fragment || isTemplateContents();
                                 errStrayEndTag(name);
                                 break endtagloop;
                             }
@@ -3421,12 +3468,13 @@ public abstract class TreeBuilder<T> imp
                                         case OPTGROUP:
                                         case OPTION: // is this possible?
                                         case P:
+                                        case RB_OR_RTC:
                                         case RT_OR_RP:
                                         case TD_OR_TH:
                                         case TBODY_OR_THEAD_OR_TFOOT:
                                             break;
                                         default:
-                                            errEndWithUnclosedElements("End tag for \u201Cbody\u201D seen but there were unclosed elements.");
+                                            errEndWithUnclosedElements(name);
                                             break uncloseloop1;
                                     }
                                 }
@@ -3435,7 +3483,7 @@ public abstract class TreeBuilder<T> imp
                             break endtagloop;
                         case HTML:
                             if (!isSecondOnStackBody()) {
-                                assert fragment;
+                                assert fragment || isTemplateContents();
                                 errStrayEndTag(name);
                                 break endtagloop;
                             }
@@ -3445,13 +3493,15 @@ public abstract class TreeBuilder<T> imp
                                         case DD_OR_DT:
                                         case LI:
                                         case P:
+                                        case RB_OR_RTC:
+                                        case RT_OR_RP:
                                         case TBODY_OR_THEAD_OR_TFOOT:
                                         case TD_OR_TH:
                                         case BODY:
                                         case HTML:
                                             break;
                                         default:
-                                            errEndWithUnclosedElements("End tag for \u201Chtml\u201D seen but there were unclosed elements.");
+                                            errEndWithUnclosedElements(name);
                                             break uncloseloop2;
                                     }
                                 }
@@ -3463,7 +3513,7 @@ public abstract class TreeBuilder<T> imp
                         case PRE_OR_LISTING:
                         case FIELDSET:
                         case BUTTON:
-                        case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_NAV_OR_SECTION_OR_SUMMARY:
+                        case ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIALOG_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SEARCH_OR_SECTION_OR_SUMMARY:
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 errStrayEndTag(name);
@@ -3478,32 +3528,48 @@ public abstract class TreeBuilder<T> imp
                             }
                             break endtagloop;
                         case FORM:
-                            if (formPointer == null) {
-                                errStrayEndTag(name);
+                            if (!isTemplateContents()) {
+                                if (formPointer == null) {
+                                    errStrayEndTag(name);
+                                    break endtagloop;
+                                }
+                                formPointer = null;
+                                eltPos = findLastInScope(name);
+                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                    errStrayEndTag(name);
+                                    break endtagloop;
+                                }
+                                generateImpliedEndTags();
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errUnclosedElements(eltPos, name);
+                                }
+                                removeFromStack(eltPos);
                                 break endtagloop;
-                            }
-                            formPointer = null;
-                            eltPos = findLastInScope(name);
-                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                errStrayEndTag(name);
+                            } else {
+                                eltPos = findLastInScope(name);
+                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                    errStrayEndTag(name);
+                                    break endtagloop;
+                                }
+                                generateImpliedEndTags();
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errUnclosedElements(eltPos, name);
+                                }
+                                while (currentPtr >= eltPos) {
+                                    pop();
+                                }
                                 break endtagloop;
                             }
-                            generateImpliedEndTags();
-                            if (errorHandler != null && !isCurrent(name)) {
-                                errUnclosedElements(eltPos, name);
-                            }
-                            removeFromStack(eltPos);
-                            break endtagloop;
                         case P:
                             eltPos = findLastInButtonScope("p");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                err("No \u201Cp\u201D element in scope but a \u201Cp\u201D end tag seen.");
+                                errNoElementToCloseButEndTagSeen("p");
                                 // XXX Can the 'in foreign' case happen anymore?
                                 if (isInForeign()) {
-                                    err("HTML start tag \u201C"
-                                            + name
-                                            + "\u201D in a foreign namespace context.");
-                                    while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+                                    errHtmlStartTagInForeignContext(name);
+                                    // Check for currentPtr for the fragment
+                                    // case.
+                                    while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                                         pop();
                                     }
                                 }
@@ -3524,7 +3590,7 @@ public abstract class TreeBuilder<T> imp
                         case LI:
                             eltPos = findLastInListScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                err("No \u201Cli\u201D element in list scope but a \u201Cli\u201D end tag seen.");
+                                errNoElementToCloseButEndTagSeen(name);
                             } else {
                                 generateImpliedEndTagsExceptFor(name);
                                 if (errorHandler != null
@@ -3539,10 +3605,7 @@ public abstract class TreeBuilder<T> imp
                         case DD_OR_DT:
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                err("No \u201C"
-                                        + name
-                                        + "\u201D element in scope but a \u201C"
-                                        + name + "\u201D end tag seen.");
+                                errNoElementToCloseButEndTagSeen(name);
                             } else {
                                 generateImpliedEndTagsExceptFor(name);
                                 if (errorHandler != null
@@ -3585,12 +3648,13 @@ public abstract class TreeBuilder<T> imp
                             }
                             break endtagloop;
                         case BR:
-                            err("End tag \u201Cbr\u201D.");
+                            errEndTagBr();
                             if (isInForeign()) {
-                                err("HTML start tag \u201C"
-                                        + name
-                                        + "\u201D in a foreign namespace context.");
-                                while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+                                // XXX can this happen anymore?
+                                errHtmlStartTagInForeignContext(name);
+                                // Check for currentPtr for the fragment
+                                // case.
+                                while (currentPtr >= 0 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                                     pop();
                                 }
                             }
@@ -3599,14 +3663,17 @@ public abstract class TreeBuilder<T> imp
                                     elementName,
                                     HtmlAttributes.EMPTY_ATTRIBUTES);
                             break endtagloop;
+                        case TEMPLATE:
+                            // fall through to IN_HEAD;
+                            break;
                         case AREA_OR_WBR:
+                        case KEYGEN: // XXX??
                         case PARAM_OR_SOURCE_OR_TRACK:
-                        case EMBED_OR_IMG:
+                        case EMBED:
+                        case IMG:
                         case IMAGE:
                         case INPUT:
-                        case KEYGEN: // XXX??
                         case HR:
-                        case ISINDEX:
                         case IFRAME:
                         case NOEMBED: // XXX???
                         case NOFRAMES: // XXX??
@@ -3619,9 +3686,8 @@ public abstract class TreeBuilder<T> imp
                             if (scriptingEnabled) {
                                 errStrayEndTag(name);
                                 break endtagloop;
-                            } else {
-                                // fall through
                             }
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         case A:
                         case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
                         case FONT:
@@ -3630,6 +3696,7 @@ public abstract class TreeBuilder<T> imp
                                 break endtagloop;
                             }
                             // else handle like any other tag
+                            // CPPONLY: MOZ_FALLTHROUGH;
                         default:
                             if (isCurrent(name)) {
                                 pop();
@@ -3639,7 +3706,7 @@ public abstract class TreeBuilder<T> imp
                             eltPos = currentPtr;
                             for (;;) {
                                 StackNode<T> node = stack[eltPos];
-                                if (node.name == name) {
+                                if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
                                     generateImpliedEndTags();
                                     if (errorHandler != null
                                             && !isCurrent(name)) {
@@ -3649,19 +3716,55 @@ public abstract class TreeBuilder<T> imp
                                         pop();
                                     }
                                     break endtagloop;
-                                } else if (node.isSpecial()) {
+                                } else if (eltPos == 0 || node.isSpecial()) {
                                     errStrayEndTag(name);
                                     break endtagloop;
                                 }
                                 eltPos--;
                             }
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
+                case IN_HEAD:
+                    switch (group) {
+                        case HEAD:
+                            pop();
+                            mode = AFTER_HEAD;
+                            break endtagloop;
+                        case BR:
+                        case HTML:
+                        case BODY:
+                            pop();
+                            mode = AFTER_HEAD;
+                            continue;
+                        case TEMPLATE:
+                            endTagTemplateInHead();
+                            break endtagloop;
+                        default:
+                            errStrayEndTag(name);
+                            break endtagloop;
+                    }
+                case IN_HEAD_NOSCRIPT:
+                    switch (group) {
+                        case NOSCRIPT:
+                            pop();
+                            mode = IN_HEAD;
+                            break endtagloop;
+                        case BR:
+                            errStrayEndTag(name);
+                            pop();
+                            mode = IN_HEAD;
+                            continue;
+                        default:
+                            errStrayEndTag(name);
+                            break endtagloop;
+                    }
                 case IN_COLUMN_GROUP:
                     switch (group) {
                         case COLGROUP:
-                            if (currentPtr == 0) {
-                                assert fragment;
-                                err("Garbage in \u201Ccolgroup\u201D fragment.");
+                            if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+                                    TreeBuilder.TEMPLATE) {
+                                assert fragment || isTemplateContents();
+                                errGarbageInColgroup();
                                 break endtagloop;
                             }
                             pop();
@@ -3670,10 +3773,14 @@ public abstract class TreeBuilder<T> imp
                         case COL:
                             errStrayEndTag(name);
                             break endtagloop;
+                        case TEMPLATE:
+                            endTagTemplateInHead();
+                            break endtagloop;
                         default:
-                            if (currentPtr == 0) {
-                                assert fragment;
-                                err("Garbage in \u201Ccolgroup\u201D fragment.");
+                            if (currentPtr == 0 || stack[currentPtr].getGroup() ==
+                                    TreeBuilder.TEMPLATE) {
+                                assert fragment || isTemplateContents();
+                                errGarbageInColgroup();
                                 break endtagloop;
                             }
                             pop();
@@ -3687,9 +3794,7 @@ public abstract class TreeBuilder<T> imp
                         case TBODY_OR_THEAD_OR_TFOOT:
                         case TR:
                         case TD_OR_TH:
-                            err("\u201C"
-                                    + name
-                                    + "\u201D end tag with \u201Cselect\u201D open.");
+                            errEndTagSeenWithSelectOpen(name);
                             if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) {
                                 eltPos = findLastInTableScope("select");
                                 if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
@@ -3707,6 +3812,7 @@ public abstract class TreeBuilder<T> imp
                         default:
                             // fall through to IN_SELECT
                     }
+                    // CPPONLY: MOZ_FALLTHROUGH;
                 case IN_SELECT:
                     switch (group) {
                         case OPTION:
@@ -3740,6 +3846,9 @@ public abstract class TreeBuilder<T> imp
                             }
                             resetTheInsertionMode();
                             break endtagloop;
+                        case TEMPLATE:
+                            endTagTemplateInHead();
+                            break endtagloop;
                         default:
                             errStrayEndTag(name);
                             break endtagloop;
@@ -3755,7 +3864,7 @@ public abstract class TreeBuilder<T> imp
                                 break endtagloop;
                             }
                         default:
-                            err("Saw an end tag after \u201Cbody\u201D had been closed.");
+                            errEndTagAfterBody();
                             mode = framesetOk ? FRAMESET_OK : IN_BODY;
                             continue;
                     }
@@ -3789,29 +3898,12 @@ public abstract class TreeBuilder<T> imp
                     /*
                      * Parse error.
                      */
-                    // [NOCPP[
-                    switch (doctypeExpectation) {
-                        case AUTO:
-                            err("End tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML:
-                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
-                            break;
-                        case HTML401_STRICT:
-                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                            break;
-                        case HTML401_TRANSITIONAL:
-                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                            break;
-                        case NO_DOCTYPE_ERRORS:
-                    }
-                    // ]NOCPP]
+                    errEndTagSeenWithoutDoctype();
                     /*
-                     * 
+                     *
                      * Set the document to quirks mode.
                      */
-                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
-                            false);
+                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null);
                     /*
                      * Then, switch to the root element mode of the tree
                      * construction stage
@@ -3856,39 +3948,11 @@ public abstract class TreeBuilder<T> imp
                             errStrayEndTag(name);
                             break endtagloop;
                     }
-                case IN_HEAD:
-                    switch (group) {
-                        case HEAD:
-                            pop();
-                            mode = AFTER_HEAD;
-                            break endtagloop;
-                        case BR:
-                        case HTML:
-                        case BODY:
-                            pop();
-                            mode = AFTER_HEAD;
-                            continue;
-                        default:
-                            errStrayEndTag(name);
-                            break endtagloop;
-                    }
-                case IN_HEAD_NOSCRIPT:
-                    switch (group) {
-                        case NOSCRIPT:
-                            pop();
-                            mode = IN_HEAD;
-                            break endtagloop;
-                        case BR:
-                            errStrayEndTag(name);
-                            pop();
-                            mode = IN_HEAD;
-                            continue;
-                        default:
-                            errStrayEndTag(name);
-                            break endtagloop;
-                    }
                 case AFTER_HEAD:
                     switch (group) {
+                        case TEMPLATE:
+                            endTagTemplateInHead();
+                            break endtagloop;
                         case HTML:
                         case BODY:
                         case BR:
@@ -3905,8 +3969,7 @@ public abstract class TreeBuilder<T> imp
                     continue;
                 case AFTER_AFTER_FRAMESET:
                     errStrayEndTag(name);
-                    mode = IN_FRAMESET;
-                    continue;
+                    break endtagloop;
                 case TEXT:
                     // XXX need to manage insertion point here
                     pop();
@@ -3919,9 +3982,29 @@ public abstract class TreeBuilder<T> imp
         } // endtagloop
     }
 
-    private int findLastInTableScopeOrRootTbodyTheadTfoot() {
+    private void endTagTemplateInHead() throws SAXException {
+        int eltPos = findLast("template");
+        if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+            errStrayEndTag("template");
+            return;
+        }
+        generateImpliedEndTagsThoroughly();
+        if (errorHandler != null && !isCurrent("template")) {
+            errUnclosedElements(eltPos, "template");
+        }
+        while (currentPtr >= eltPos) {
+            pop();
+        }
+        clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+        popTemplateMode();
+        resetTheInsertionMode();
+    }
+
+    private int findLastInTableScopeOrRootTemplateTbodyTheadTfoot() {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].getGroup() == TreeBuilder.TBODY_OR_THEAD_OR_TFOOT) {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml"
+                    && (stack[i].getGroup() == TreeBuilder.TBODY_OR_THEAD_OR_TFOOT
+                            || stack[i].getGroup() == TreeBuilder.TEMPLATE)) {
                 return i;
             }
         }
@@ -3930,7 +4013,7 @@ public abstract class TreeBuilder<T> imp
 
     private int findLast(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
                 return i;
             }
         }
@@ -3939,10 +4022,12 @@ public abstract class TreeBuilder<T> imp
 
     private int findLastInTableScope(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
-                return i;
-            } else if (stack[i].name == "table") {
-                return TreeBuilder.NOT_FOUND_ON_STACK;
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+                if (stack[i].name == name) {
+                    return i;
+                } else if (stack[i].name == "table" || stack[i].name == "template") {
+                    return TreeBuilder.NOT_FOUND_ON_STACK;
+                }
             }
         }
         return TreeBuilder.NOT_FOUND_ON_STACK;
@@ -3950,9 +4035,15 @@ public abstract class TreeBuilder<T> imp
 
     private int findLastInButtonScope(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
-                return i;
-            } else if (stack[i].isScoping() || stack[i].name == "button") {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+                if (stack[i].name == name) {
+                    return i;
+                } else if (stack[i].name == "button") {
+                    return TreeBuilder.NOT_FOUND_ON_STACK;
+                }
+            }
+
+            if (stack[i].isScoping()) {
                 return TreeBuilder.NOT_FOUND_ON_STACK;
             }
         }
@@ -3961,7 +4052,7 @@ public abstract class TreeBuilder<T> imp
 
     private int findLastInScope(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
                 return i;
             } else if (stack[i].isScoping()) {
                 return TreeBuilder.NOT_FOUND_ON_STACK;
@@ -3972,15 +4063,21 @@ public abstract class TreeBuilder<T> imp
 
     private int findLastInListScope(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
-                return i;
-            } else if (stack[i].isScoping() || stack[i].name == "ul" || stack[i].name == "ol") {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+                if (stack[i].name == name) {
+                    return i;
+                } else if (stack[i].name == "ul" || stack[i].name == "ol") {
+                    return TreeBuilder.NOT_FOUND_ON_STACK;
+                }
+            }
+
+            if (stack[i].isScoping()) {
                 return TreeBuilder.NOT_FOUND_ON_STACK;
             }
         }
         return TreeBuilder.NOT_FOUND_ON_STACK;
     }
-    
+
     private int findLastInScopeHn() {
         for (int i = currentPtr; i > 0; i--) {
             if (stack[i].getGroup() == TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
@@ -4002,8 +4099,9 @@ public abstract class TreeBuilder<T> imp
                 case DD_OR_DT:
                 case OPTION:
                 case OPTGROUP:
+                case RB_OR_RTC:
                 case RT_OR_RP:
-                    if (node.name == name) {
+                    if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
                         return;
                     }
                     pop();
@@ -4022,6 +4120,7 @@ public abstract class TreeBuilder<T> imp
                 case DD_OR_DT:
                 case OPTION:
                 case OPTGROUP:
+                case RB_OR_RTC:
                 case RT_OR_RP:
                     pop();
                     continue;
@@ -4031,46 +4130,82 @@ public abstract class TreeBuilder<T> imp
         }
     }
 
+    private void generateImpliedEndTagsThoroughly() throws SAXException {
+        for (;;) {
+            switch (stack[currentPtr].getGroup()) {
+                case CAPTION:
+                case COLGROUP:
+                case DD_OR_DT:
+                case LI:
+                case OPTGROUP:
+                case OPTION:
+                case P:
+                case RB_OR_RTC:
+                case RT_OR_RP:
+                case TBODY_OR_THEAD_OR_TFOOT:
+                case TD_OR_TH:
+                case TR:
+                    pop();
+                    continue;
+                default:
+                    return;
+            }
+        }
+    }
+
     private boolean isSecondOnStackBody() {
         return currentPtr >= 1 && stack[1].getGroup() == TreeBuilder.BODY;
     }
 
     private void documentModeInternal(DocumentMode m, String publicIdentifier,
-            String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+            String systemIdentifier)
             throws SAXException {
+
+        if (forceNoQuirks) {
+            // Srcdoc documents are always rendered in standards mode.
+            quirks = false;
+            if (documentModeHandler != null) {
+                documentModeHandler.documentMode(
+                        DocumentMode.STANDARDS_MODE
+                        // [NOCPP[
+                        , null, null
+                // ]NOCPP]
+                );
+            }
+            return;
+        }
+
         quirks = (m == DocumentMode.QUIRKS_MODE);
         if (documentModeHandler != null) {
             documentModeHandler.documentMode(
                     m
                     // [NOCPP[
-                    , publicIdentifier, systemIdentifier,
-                    html4SpecificAdditionalErrorChecks
+                    , publicIdentifier, systemIdentifier
             // ]NOCPP]
             );
         }
         // [NOCPP[
-        documentMode(m, publicIdentifier, systemIdentifier,
-                html4SpecificAdditionalErrorChecks);
+        documentMode(m, publicIdentifier, systemIdentifier);
         // ]NOCPP]
     }
 
     private boolean isAlmostStandards(String publicIdentifier,
             String systemIdentifier) {
-        if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                "-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
+        if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                "-//w3c//dtd xhtml 1.0 transitional//", publicIdentifier)) {
             return true;
         }
-        if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                "-//w3c//dtd xhtml 1.0 frameset//en", publicIdentifier)) {
+        if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                "-//w3c//dtd xhtml 1.0 frameset//", publicIdentifier)) {
             return true;
         }
         if (systemIdentifier != null) {
-            if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                    "-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+            if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                    "-//w3c//dtd html 4.01 transitional//", publicIdentifier)) {
                 return true;
             }
-            if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                    "-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+            if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                    "-//w3c//dtd html 4.01 frameset//", publicIdentifier)) {
                 return true;
             }
         }
@@ -4103,11 +4238,11 @@ public abstract class TreeBuilder<T> imp
             }
         }
         if (systemIdentifier == null) {
-            if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                    "-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
+            if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                    "-//w3c//dtd html 4.01 transitional//", publicIdentifier)) {
                 return true;
-            } else if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                    "-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
+            } else if (Portability.lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+                    "-//w3c//dtd html 4.01 frameset//", publicIdentifier)) {
                 return true;
             }
         } else if (Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
@@ -4134,17 +4269,25 @@ public abstract class TreeBuilder<T> imp
     private int findLastInTableScopeTdTh() {
         for (int i = currentPtr; i > 0; i--) {
             @Local String name = stack[i].name;
-            if ("td" == name || "th" == name) {
-                return i;
-            } else if (name == "table") {
-                return TreeBuilder.NOT_FOUND_ON_STACK;
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
+                if ("td" == name || "th" == name) {
+                    return i;
+                } else if (name == "table" || name == "template") {
+                    return TreeBuilder.NOT_FOUND_ON_STACK;
+                }
             }
         }
         return TreeBuilder.NOT_FOUND_ON_STACK;
     }
 
     private void clearStackBackTo(int eltPos) throws SAXException {
+        int eltGroup = stack[eltPos].getGroup();
         while (currentPtr > eltPos) { // > not >= intentional
+            if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml"
+                    && stack[currentPtr].getGroup() == TEMPLATE
+                    && (eltGroup == TABLE || eltGroup == TBODY_OR_THEAD_OR_TFOOT|| eltGroup == TR || eltPos == 0)) {
+                return;
+            }
             pop();
         }
     }
@@ -4159,14 +4302,30 @@ public abstract class TreeBuilder<T> imp
             ns = node.ns;
             if (i == 0) {
                 if (!(contextNamespace == "http://www.w3.org/1999/xhtml" && (contextName == "td" || contextName == "th"))) {
-                    name = contextName;
-                    ns = contextNamespace;
+                    if (fragment) {
+                        // Make sure we are parsing a fragment otherwise the context element doesn't make sense.
+                        name = contextName;
+                        ns = contextNamespace;
+                    }
                 } else {
                     mode = framesetOk ? FRAMESET_OK : IN_BODY; // XXX from Hixie's email
                     return;
                 }
             }
             if ("select" == name) {
+                int ancestorIndex = i;
+                while (ancestorIndex > 0) {
+                    StackNode<T> ancestor = stack[ancestorIndex--];
+                    if ("http://www.w3.org/1999/xhtml" == ancestor.ns) {
+                        if ("template" == ancestor.name) {
+                            break;
+                        }
+                        if ("table" == ancestor.name) {
+                            mode = IN_SELECT_IN_TABLE;
+                            return;
+                        }
+                    }
+                }
                 mode = IN_SELECT;
                 return;
             } else if ("td" == name || "th" == name) {
@@ -4190,17 +4349,27 @@ public abstract class TreeBuilder<T> imp
             } else if ("http://www.w3.org/1999/xhtml" != ns) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
-            } else if ("head" == name) {
-                mode = framesetOk ? FRAMESET_OK : IN_BODY; // really
+            } else if ("template" == name) {
+                assert templateModePtr >= 0;
+                mode = templateModeStack[templateModePtr];
+                return;
+            }  else if ("head" == name) {
+                if (name == contextName) {
+                    mode = framesetOk ? FRAMESET_OK : IN_BODY; // really
+                } else {
+                    mode = IN_HEAD;
+                }
                 return;
             } else if ("body" == name) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
             } else if ("frameset" == name) {
+                // TODO: Fragment case. Add error reporting.
                 mode = IN_FRAMESET;
                 return;
             } else if ("html" == name) {
                 if (headPointer == null) {
+                    // TODO: Fragment case. Add error reporting.
                     mode = BEFORE_HEAD;
                 } else {
                     mode = AFTER_HEAD;
@@ -4215,7 +4384,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * @throws SAXException
-     * 
+     *
      */
     private void implicitlyCloseP() throws SAXException {
         int eltPos = findLastInButtonScope("p");
@@ -4231,16 +4400,26 @@ public abstract class TreeBuilder<T> imp
         }
     }
 
-    private boolean clearLastStackSlot() {
+    private boolean debugOnlyClearLastStackSlot() {
         stack[currentPtr] = null;
         return true;
     }
 
-    private boolean clearLastListSlot() {
+    private boolean debugOnlyClearLastListSlot() {
         listOfActiveFormattingElements[listPtr] = null;
         return true;
     }
 
+    private void pushTemplateMode(int mode) {
+        templateModePtr++;
+        if (templateModePtr == templateModeStack.length) {
+            int[] newStack = new int[templateModeStack.length + 64];
+            System.arraycopy(templateModeStack, 0, newStack, 0, templateModeStack.length);
+            templateModeStack = newStack;
+        }
+        templateModeStack[templateModePtr] = mode;
+    }
+
     @SuppressWarnings("unchecked") private void push(StackNode<T> node) throws SAXException {
         currentPtr++;
         if (currentPtr == stack.length) {
@@ -4283,13 +4462,14 @@ public abstract class TreeBuilder<T> imp
                 --listPtr;
                 return;
             }
-            listOfActiveFormattingElements[listPtr].release();
+            listOfActiveFormattingElements[listPtr].release(this);
             --listPtr;
         }
     }
 
     @Inline private boolean isCurrent(@Local String name) {
-        return name == stack[currentPtr].name;
+        return stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
+                name == stack[currentPtr].name;
     }
 
     private void removeFromStack(int pos) throws SAXException {
@@ -4297,9 +4477,9 @@ public abstract class TreeBuilder<T> imp
             pop();
         } else {
             fatal();
-            stack[pos].release();
+            stack[pos].release(this);
             System.arraycopy(stack, pos + 1, stack, pos, currentPtr - pos);
-            assert clearLastStackSlot();
+            assert debugOnlyClearLastStackSlot();
             currentPtr--;
         }
     }
@@ -4317,7 +4497,7 @@ public abstract class TreeBuilder<T> imp
                 return;
             }
             fatal();
-            node.release();
+            node.release(this);
             System.arraycopy(stack, pos + 1, stack, pos, currentPtr - pos);
             currentPtr--;
         }
@@ -4325,27 +4505,49 @@ public abstract class TreeBuilder<T> imp
 
     private void removeFromListOfActiveFormattingElements(int pos) {
         assert listOfActiveFormattingElements[pos] != null;
-        listOfActiveFormattingElements[pos].release();
+        listOfActiveFormattingElements[pos].release(this);
         if (pos == listPtr) {
-            assert clearLastListSlot();
+            assert debugOnlyClearLastListSlot();
             listPtr--;
             return;
         }
         assert pos < listPtr;
         System.arraycopy(listOfActiveFormattingElements, pos + 1,
                 listOfActiveFormattingElements, pos, listPtr - pos);
-        assert clearLastListSlot();
+        assert debugOnlyClearLastListSlot();
         listPtr--;
     }
 
+    /**
+     * Adoption agency algorithm.
+     *
+     * @param name subject as described in the specified algorithm.
+     * @return Returns true if the algorithm has completed and there is nothing remaining to
+     * be done. Returns false if the algorithm needs to "act as described in the 'any other
+     * end tag' entry" as described in the specified algorithm.
+     * @throws SAXException
+     */
     private boolean adoptionAgencyEndTag(@Local String name) throws SAXException {
+        // This check intends to ensure that for properly nested tags, closing tags will match
+        // against the stack instead of the listOfActiveFormattingElements.
+        if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
+                stack[currentPtr].name == name &&
+                findInListOfActiveFormattingElements(stack[currentPtr]) == -1) {
+            // If the current element matches the name but isn't on the list of active
+            // formatting elements, then it is possible that the list was mangled by the Noah's Ark
+            // clause. In this case, we want to match the end tag against the stack instead of
+            // proceeding with the AAA algorithm that may match against the list of
+            // active formatting elements (and possibly mangle the tree in unexpected ways).
+            pop();
+            return true;
+        }
+
         // If you crash around here, perhaps some stack node variable claimed to
         // be a weak ref isn't.
         for (int i = 0; i < 8; ++i) {
             int formattingEltListPos = listPtr;
             while (formattingEltListPos > -1) {
-                StackNode<T> listNode = listOfActiveFormattingElements[formattingEltListPos]; // weak
-                                                                                              // ref
+                StackNode<T> listNode = listOfActiveFormattingElements[formattingEltListPos]; // weak ref
                 if (listNode == null) {
                     formattingEltListPos = -1;
                     break;
@@ -4357,18 +4559,8 @@ public abstract class TreeBuilder<T> imp
             if (formattingEltListPos == -1) {
                 return false;
             }
-            StackNode<T> formattingElt = listOfActiveFormattingElements[formattingEltListPos]; // this
-            // *looks*
-            // like
-            // a
-            // weak
-            // ref
-            // to
-            // the
-            // list
-            // of
-            // formatting
-            // elements
+            // this *looks* like a weak ref to the list of formatting elements
+            StackNode<T> formattingElt = listOfActiveFormattingElements[formattingEltListPos];
             int formattingEltStackPos = currentPtr;
             boolean inScope = true;
             while (formattingEltStackPos > -1) {
@@ -4381,21 +4573,22 @@ public abstract class TreeBuilder<T> imp
                 formattingEltStackPos--;
             }
             if (formattingEltStackPos == -1) {
-                err("No element \u201C" + name + "\u201D to close.");
+                errNoElementToCloseButEndTagSeen(name);
                 removeFromListOfActiveFormattingElements(formattingEltListPos);
                 return true;
             }
             if (!inScope) {
-                err("No element \u201C" + name + "\u201D to close.");
+                errNoElementToCloseButEndTagSeen(name);
                 return true;
             }
             // stackPos now points to the formatting element and it is in scope
-            if (errorHandler != null && formattingEltStackPos != currentPtr) {
-                errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules.");
+            if (formattingEltStackPos != currentPtr) {
+                errEndTagViolatesNestingRules(name);
             }
             int furthestBlockPos = formattingEltStackPos + 1;
             while (furthestBlockPos <= currentPtr) {
                 StackNode<T> node = stack[furthestBlockPos]; // weak ref
+                assert furthestBlockPos > 0: "How is formattingEltStackPos + 1 not > 0?";
                 if (node.isSpecial()) {
                     break;
                 }
@@ -4409,30 +4602,51 @@ public abstract class TreeBuilder<T> imp
                 removeFromListOfActiveFormattingElements(formattingEltListPos);
                 return true;
             }
-            StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak
-            // ref
+            // commonAncestor is used for running the algorithm and
+            // insertionCommonAncestor is used for the actual insertions to
+            // keep them depth-limited.
+            StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak ref
+            T insertionCommonAncestor = nodeFromStackWithBlinkCompat(formattingEltStackPos - 1); // weak ref
             StackNode<T> furthestBlock = stack[furthestBlockPos]; // weak ref
             // detachFromParent(furthestBlock.node); XXX AAA CHANGE
             int bookmark = formattingEltListPos;
             int nodePos = furthestBlockPos;
             StackNode<T> lastNode = furthestBlock; // weak ref
-            for (int j = 0; j < 3; ++j) {
+            int j = 0;
+            for (;;) {
+                ++j;
                 nodePos--;
+                if (nodePos == formattingEltStackPos) {
+                    break;
+                }
                 StackNode<T> node = stack[nodePos]; // weak ref
                 int nodeListPos = findInListOfActiveFormattingElements(node);
+
+                if (j > 3 && nodeListPos != -1) {
+                    removeFromListOfActiveFormattingElements(nodeListPos);
+
+                    // Adjust the indices into the list to account
+                    // for the removal of nodeListPos.
+                    if (nodeListPos <= formattingEltListPos) {
+                        formattingEltListPos--;
+                    }
+                    if (nodeListPos <= bookmark) {
+                        bookmark--;
+                    }
+
+                    // Update position to reflect removal from list.
+                    nodeListPos = -1;
+                }
+
                 if (nodeListPos == -1) {
                     assert formattingEltStackPos < nodePos;
                     assert bookmark < nodePos;
                     assert furthestBlockPos > nodePos;
-                    removeFromStack(nodePos); // node is now a bad pointer in
-                    // C++
+                    removeFromStack(nodePos); // node is now a bad pointer in C++
                     furthestBlockPos--;
                     continue;
                 }
                 // now node is both on stack and in the list
-                if (nodePos == formattingEltStackPos) {
-                    break;
-                }
                 if (nodePos == furthestBlockPos) {
                     bookmark = nodeListPos + 1;
                 }
@@ -4440,52 +4654,52 @@ public abstract class TreeBuilder<T> imp
                 assert node == listOfActiveFormattingElements[nodeListPos];
                 assert node == stack[nodePos];
                 T clone = createElement("http://www.w3.org/1999/xhtml",
-                        node.name, node.attributes.cloneAttributes(null));
-                StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+                        node.name, node.attributes.cloneAttributes(), insertionCommonAncestor
+                        // CPPONLY: , htmlCreator(node.getHtmlCreator())
+                        );
+                StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
                         node.name, clone, node.popName, node.attributes
+                        // CPPONLY: , node.getHtmlCreator()
                         // [NOCPP[
                         , node.getLocator()
-                // ]NOCPP]       
-                ); // creation
-                // ownership
-                // goes
-                // to
-                // stack
+                        // ]NOCPP]
+                ); // creation ownership goes to stack
                 node.dropAttributes(); // adopt ownership to newNode
                 stack[nodePos] = newNode;
                 newNode.retain(); // retain for list
                 listOfActiveFormattingElements[nodeListPos] = newNode;
-                node.release(); // release from stack
-                node.release(); // release from list
+                node.release(this); // release from stack
+                node.release(this); // release from list
                 node = newNode;
                 // } XXX AAA CHANGE
                 detachFromParent(lastNode.node);
-                appendElement(lastNode.node, node.node);
+                appendElement(lastNode.node, nodeFromStackWithBlinkCompat(nodePos));
                 lastNode = node;
             }
+            // If we insert into a foster parent, for simplicity, we insert
+            // accoding to the spec without Blink's depth limit.
             if (commonAncestor.isFosterParenting()) {
                 fatal();
                 detachFromParent(lastNode.node);
                 insertIntoFosterParent(lastNode.node);
             } else {
                 detachFromParent(lastNode.node);
-                appendElement(lastNode.node, commonAncestor.node);
+                appendElement(lastNode.node, insertionCommonAncestor);
             }
             T clone = createElement("http://www.w3.org/1999/xhtml",
                     formattingElt.name,
-                    formattingElt.attributes.cloneAttributes(null));
-            StackNode<T> formattingClone = new StackNode<T>(
+                    formattingElt.attributes.cloneAttributes(), furthestBlock.node
+                    // CPPONLY: , htmlCreator(formattingElt.getHtmlCreator())
+                    );
+            StackNode<T> formattingClone = createStackNode(
                     formattingElt.getFlags(), formattingElt.ns,
                     formattingElt.name, clone, formattingElt.popName,
                     formattingElt.attributes
+                    // CPPONLY: , formattingElt.getHtmlCreator()
                     // [NOCPP[
                     , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
-            // ]NOCPP]
-            ); // Ownership
-            // transfers
-            // to
-            // stack
-            // below
+                    // ]NOCPP]
+            ); // Ownership transfers to stack below
             formattingElt.dropAttributes(); // transfer ownership to
                                             // formattingClone
             appendChildrenToNewParent(furthestBlock.node, clone);
@@ -4569,10 +4783,10 @@ public abstract class TreeBuilder<T> imp
             removeFromListOfActiveFormattingElements(candidate);
         }
     }
-    
+
     private int findLastOrRoot(@Local String name) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].name == name) {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
                 return i;
             }
         }
@@ -4581,7 +4795,7 @@ public abstract class TreeBuilder<T> imp
 
     private int findLastOrRoot(int group) {
         for (int i = currentPtr; i > 0; i--) {
-            if (stack[i].getGroup() == group) {
+            if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].getGroup() == group) {
                 return i;
             }
         }
@@ -4619,10 +4833,9 @@ public abstract class TreeBuilder<T> imp
 
     private void pushHeadPointerOntoStack() throws SAXException {
         assert headPointer != null;
-        assert !fragment;
         assert mode == AFTER_HEAD;
         fatal();
-        silentPush(new StackNode<T>(ElementName.HEAD, headPointer
+        silentPush(createStackNode(ElementName.HEAD, headPointer
         // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -4631,7 +4844,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * @throws SAXException
-     * 
+     *
      */
     private void reconstructTheActiveFormattingElements() throws SAXException {
         if (listPtr == -1) {
@@ -4657,40 +4870,207 @@ public abstract class TreeBuilder<T> imp
         while (entryPos < listPtr) {
             entryPos++;
             StackNode<T> entry = listOfActiveFormattingElements[entryPos];
-            T clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
-                    entry.attributes.cloneAttributes(null));
-            StackNode<T> entryClone = new StackNode<T>(entry.getFlags(),
+            StackNode<T> current = stack[currentPtr];
+
+            T clone;
+            if (current.isFosterParenting()) {
+                clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
+                        entry.attributes.cloneAttributes()
+                        // CPPONLY: , htmlCreator(entry.getHtmlCreator())
+                        );
+            } else {
+                T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+                clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
+                        entry.attributes.cloneAttributes(), currentNode
+                        // CPPONLY: , htmlCreator(entry.getHtmlCreator())
+                        );
+                appendElement(clone, currentNode);
+            }
+
+            StackNode<T> entryClone = createStackNode(entry.getFlags(),
                     entry.ns, entry.name, clone, entry.popName,
                     entry.attributes
+                    // CPPONLY: , entry.getHtmlCreator()
                     // [NOCPP[
                     , entry.getLocator()
-            // ]NOCPP]
+                    // ]NOCPP]
             );
+
             entry.dropAttributes(); // transfer ownership to entryClone
-            StackNode<T> currentNode = stack[currentPtr];
-            if (currentNode.isFosterParenting()) {
-                insertIntoFosterParent(clone);
-            } else {
-                appendElement(clone, currentNode.node);
-            }
+
             push(entryClone);
             // stack takes ownership of the local variable
             listOfActiveFormattingElements[entryPos] = entryClone;
             // overwriting the old entry on the list, so release & retain
-            entry.release();
+            entry.release(this);
             entryClone.retain();
         }
     }
 
+    void notifyUnusedStackNode(int idxInStackNodes) {
+        // stackNodesIdx is the earliest possible index of a stack node that might be unused,
+        // so update the index if necessary.
+        if (idxInStackNodes < stackNodesIdx) {
+            stackNodesIdx = idxInStackNodes;
+        }
+    }
+
+    @SuppressWarnings("unchecked") private StackNode<T> getUnusedStackNode() {
+        // Search for an unused stack node.
+        while (stackNodesIdx < numStackNodes) {
+            if (stackNodes[stackNodesIdx].isUnused()) {
+                return stackNodes[stackNodesIdx++];
+            }
+            stackNodesIdx++;
+        }
+
+        if (stackNodesIdx < stackNodes.length) {
+            // No unused stack nodes, but there is still space in the storage array.
+            stackNodes[stackNodesIdx] = new StackNode<T>(stackNodesIdx);
+            numStackNodes++;
+            return stackNodes[stackNodesIdx++];
+        }
+
+        // Could not find an unused stack node and storage array is full.
+        StackNode<T>[] newStack = new StackNode[stackNodes.length + 64];
+        System.arraycopy(stackNodes, 0, newStack, 0, stackNodes.length);
+        stackNodes = newStack;
+
+        // Create a new stack node and return it.
+        stackNodes[stackNodesIdx] = new StackNode<T>(stackNodesIdx);
+        numStackNodes++;
+        return stackNodes[stackNodesIdx++];
+    }
+
+    private StackNode<T> createStackNode(int flags, @NsUri String ns, @Local String name, T node,
+            @Local String popName, HtmlAttributes attributes
+            // CPPONLY: , @HtmlCreator Object htmlCreator
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(flags, ns, name, node, popName, attributes
+                // CPPONLY: , htmlCreator
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
+    private StackNode<T> createStackNode(ElementName elementName, T node
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(elementName, node
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
+    private StackNode<T> createStackNode(ElementName elementName, T node, HtmlAttributes attributes
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(elementName, node, attributes
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
+    private StackNode<T> createStackNode(ElementName elementName, T node, @Local String popName
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(elementName, node, popName
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
+    private StackNode<T> createStackNode(ElementName elementName, @Local String popName, T node
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(elementName, popName, node
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
+    private StackNode<T> createStackNode(ElementName elementName, T node, @Local String popName,
+            boolean markAsIntegrationPoint
+            // [NOCPP[
+            , TaintableLocatorImpl locator
+            // ]NOCPP]
+    ) {
+        StackNode<T> instance = getUnusedStackNode();
+        instance.setValues(elementName, node, popName, markAsIntegrationPoint
+                // [NOCPP[
+                , locator
+                // ]NOCPP]
+        );
+        return instance;
+    }
+
     private void insertIntoFosterParent(T child) throws SAXException {
-        int eltPos = findLastOrRoot(TreeBuilder.TABLE);
-        StackNode<T> node = stack[eltPos];
-        T elt = node.node;
-        if (eltPos == 0) {
-            appendElement(child, elt);
+        int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+        int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+        if (templatePos >= tablePos) {
+            appendElement(child, stack[templatePos].node);
             return;
         }
-        insertFosterParentedChild(child, elt, stack[eltPos - 1].node);
+
+        StackNode<T> node = stack[tablePos];
+        insertFosterParentedChild(child, node.node, stack[tablePos - 1].node);
+    }
+
+    private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+            HtmlAttributes attributes
+            // CPPONLY: , @Creator Object creator
+            ) throws SAXException {
+        return createAndInsertFosterParentedElement(ns, name, attributes, null
+                // CPPONLY: , creator
+                );
+    }
+
+    private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+            HtmlAttributes attributes, T form
+            // CPPONLY: , @Creator Object creator
+            ) throws SAXException {
+        int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+        int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+        if (templatePos >= tablePos) {
+            T child = createElement(ns, name, attributes, form, stack[templatePos].node
+                    // CPPONLY: , creator
+                    );
+            appendElement(child, stack[templatePos].node);
+            return child;
+        }
+
+        StackNode<T> node = stack[tablePos];
+        return createAndInsertFosterParentedElement(ns, name, attributes, form, node.node, stack[tablePos - 1].node
+                // CPPONLY: , creator
+                );
     }
 
     private boolean isInStack(StackNode<T> node) {
@@ -4702,28 +5082,43 @@ public abstract class TreeBuilder<T> imp
         return false;
     }
 
+    private void popTemplateMode() {
+        templateModePtr--;
+    }
+
     private void pop() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
+        currentPtr--;
+        elementPopped(node.ns, node.popName, node.node);
+        node.release(this);
+    }
+
+    private void popForeign(int origPos, int eltPos) throws SAXException {
+        StackNode<T> node = stack[currentPtr];
+        if (origPos != currentPtr || eltPos != currentPtr) {
+            markMalformedIfScript(node.node);
+        }
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
         elementPopped(node.ns, node.popName, node.node);
-        node.release();
+        node.release(this);
     }
 
     private void silentPop() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
-        node.release();
+        node.release(this);
     }
 
     private void popOnEof() throws SAXException {
         StackNode<T> node = stack[currentPtr];
-        assert clearLastStackSlot();
+        assert debugOnlyClearLastStackSlot();
         currentPtr--;
         markMalformedIfScript(node.node);
         elementPopped(node.ns, node.popName, node.node);
-        node.release();
+        node.release(this);
     }
 
     // [NOCPP[
@@ -4734,25 +5129,21 @@ public abstract class TreeBuilder<T> imp
             for (int i = 0; i < len; i++) {
                 AttributeName name = attributes.getXmlnsAttributeName(i);
                 if (name == AttributeName.XMLNS) {
-                    if (html4) {
-                        err("Attribute \u201Cxmlns\u201D not allowed here. (HTML4-only error.)");
-                    } else {
-                        String xmlns = attributes.getXmlnsValue(i);
-                        if (!ns.equals(xmlns)) {
-                            err("Bad value \u201C"
-                                    + xmlns
-                                    + "\u201D for the attribute \u201Cxmlns\u201D (only \u201C"
-                                    + ns + "\u201D permitted here).");
-                            switch (namePolicy) {
-                                case ALTER_INFOSET:
-                                    // fall through
-                                case ALLOW:
-                                    warn("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
-                                    break;
-                                case FATAL:
-                                    fatal("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
-                                    break;
-                            }
+                    String xmlns = attributes.getXmlnsValue(i);
+                    if (!ns.equals(xmlns)) {
+                        err("Bad value \u201C"
+                                + xmlns
+                                + "\u201D for the attribute \u201Cxmlns\u201D (only \u201C"
+                                + ns + "\u201D permitted here).");
+                        switch (namePolicy) {
+                            case ALTER_INFOSET:
+                                // fall through
+                            case ALLOW:
+                                warn("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
+                                break;
+                            case FATAL:
+                                fatal("Attribute \u201Cxmlns\u201D is not serializable as XML 1.0.");
+                                break;
                         }
                     }
                 } else if (ns != "http://www.w3.org/1999/xhtml"
@@ -4766,10 +5157,10 @@ public abstract class TreeBuilder<T> imp
                             case ALTER_INFOSET:
                                 // fall through
                             case ALLOW:
-                                warn("Attribute \u201Cxmlns:xlink\u201D with the value \u201Chttp://www.w3org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
+                                warn("Attribute \u201Cxmlns:xlink\u201D with a value other than \u201Chttp://www.w3.org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
                                 break;
                             case FATAL:
-                                fatal("Attribute \u201Cxmlns:xlink\u201D with the value \u201Chttp://www.w3org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
+                                fatal("Attribute \u201Cxmlns:xlink\u201D with a value other than \u201Chttp://www.w3.org/1999/xlink\u201D is not serializable as XML 1.0 without changing document semantics.");
                                 break;
                         }
                     }
@@ -4825,7 +5216,7 @@ public abstract class TreeBuilder<T> imp
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         T elt = createHtmlElementSetAsRoot(attributes);
-        StackNode<T> node = new StackNode<T>(ElementName.HTML,
+        StackNode<T> node = createStackNode(ElementName.HTML,
                 elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
@@ -4843,11 +5234,16 @@ public abstract class TreeBuilder<T> imp
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1999/xhtml", "head",
-                attributes);
-        appendElement(elt, stack[currentPtr].node);
+        T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+        T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode
+                /*
+                 * head uses NS_NewHTMLSharedElement creator
+                 */
+                // CPPONLY: , htmlCreator(NS_NewHTMLSharedElement)
+                );
+        appendElement(elt, currentNode);
         headPointer = elt;
-        StackNode<T> node = new StackNode<T>(ElementName.HEAD,
+        StackNode<T> node = createStackNode(ElementName.HEAD,
                 elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
@@ -4871,21 +5267,31 @@ public abstract class TreeBuilder<T> imp
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1999/xhtml", "form",
-                attributes);
-        formPointer = elt;
+
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", "form", attributes
+                    // CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, currentNode
+                    // CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
+                    );
+            appendElement(elt, currentNode);
         }
-        StackNode<T> node = new StackNode<T>(ElementName.FORM,
+
+        if (!isTemplateContents()) {
+            formPointer = elt;
+        }
+
+        StackNode<T> node = createStackNode(ElementName.FORM,
                 elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
-        // ]NOCPP]
+                // ]NOCPP]
         );
         push(node);
     }
@@ -4897,15 +5303,24 @@ public abstract class TreeBuilder<T> imp
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         // This method can't be called for custom elements
-        T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
+        HtmlAttributes clone = attributes.cloneAttributes();
+        // Attributes must not be read after calling createElement, because
+        // createElement may delete attributes in C++.
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
+            appendElement(elt, currentNode);
         }
-        StackNode<T> node = new StackNode<T>(elementName, elt, attributes.cloneAttributes(null)
+        StackNode<T> node = createStackNode(elementName, elt, clone
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -4922,9 +5337,23 @@ public abstract class TreeBuilder<T> imp
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         // This method can't be called for custom elements
-        T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
-        appendElement(elt, stack[currentPtr].node);
-        StackNode<T> node = new StackNode<T>(elementName, elt
+        T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+        T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
+                // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                );
+        if (ElementName.TEMPLATE == elementName) {
+            T root = getDeclarativeShadowRoot(currentNode, elt, attributes);
+            if (root != null) {
+                setDocumentFragmentForTemplate(elt, root);
+                elt = root;
+            } else {
+                appendElement(elt, currentNode);
+                elt = getDocumentFragmentForTemplate(elt);
+            }
+        } else {
+            appendElement(elt, currentNode);
+        }
+        StackNode<T> node = createStackNode(elementName, elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -4935,22 +5364,28 @@ public abstract class TreeBuilder<T> imp
     private void appendToCurrentNodeAndPushElementMayFoster(ElementName elementName,
             HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.name;
+        @Local String popName = elementName.getName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes);
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
+            appendElement(elt, currentNode);
         }
-        StackNode<T> node = new StackNode<T>(elementName, elt, popName
+        StackNode<T> node = createStackNode(elementName, elt, popName
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -4961,28 +5396,35 @@ public abstract class TreeBuilder<T> imp
     private void appendToCurrentNodeAndPushElementMayFosterMathML(
             ElementName elementName, HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.name;
+        @Local String popName = elementName.getName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1998/Math/MathML");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1998/Math/MathML", popName,
-                attributes);
-        StackNode<T> current = stack[currentPtr];
-        if (current.isFosterParenting()) {
-            fatal();
-            insertIntoFosterParent(elt);
-        } else {
-            appendElement(elt, current.node);
-        }
         boolean markAsHtmlIntegrationPoint = false;
         if (ElementName.ANNOTATION_XML == elementName
                 && annotationXmlEncodingPermitsHtml(attributes)) {
             markAsHtmlIntegrationPoint = true;
         }
-        StackNode<T> node = new StackNode<T>(elementName, elt, popName,
+        // Attributes must not be read after calling createElement(), since
+        // createElement may delete the object in C++.
+        T elt;
+        StackNode<T> current = stack[currentPtr];
+        if (current.isFosterParenting()) {
+            fatal();
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes
+                    // CPPONLY: , htmlCreator(null)
+                    );
+        } else {
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt  = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
+                    // CPPONLY: , htmlCreator(null)
+                    );
+            appendElement(elt, currentNode);
+        }
+        StackNode<T> node = createStackNode(elementName, elt, popName,
                 markAsHtmlIntegrationPoint
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
@@ -4991,6 +5433,25 @@ public abstract class TreeBuilder<T> imp
         push(node);
     }
 
+    // [NOCPP[
+    T getDocumentFragmentForTemplate(T template) {
+        return template;
+    }
+
+    void setDocumentFragmentForTemplate(T template, T fragment) {
+    }
+
+    T getShadowRootFromHost(T host, T template, String shadowRootMode,
+            boolean shadowRootIsClonable, boolean shadowRootIsSerializable, boolean shadowRootDelegatesFocus,
+            String shadowRootReferenceTarget) {
+        return null;
+    }
+
+    T getFormPointerForContext(T context) {
+        return null;
+    }
+    // ]NOCPP]
+
     private boolean annotationXmlEncodingPermitsHtml(HtmlAttributes attributes) {
         String encoding = attributes.getValue(AttributeName.ENCODING);
         if (encoding == null) {
@@ -5005,22 +5466,28 @@ public abstract class TreeBuilder<T> imp
     private void appendToCurrentNodeAndPushElementMayFosterSVG(
             ElementName elementName, HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.camelCaseName;
+        @Local String popName = elementName.getCamelCaseName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/2000/svg");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/2000/svg", popName, attributes);
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes
+                    // CPPONLY: , svgCreator(elementName.getSvgCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
+                    // CPPONLY: , svgCreator(elementName.getSvgCreator())
+                    );
+            appendElement(elt, currentNode);
         }
-        StackNode<T> node = new StackNode<T>(elementName, popName, elt
+        StackNode<T> node = createStackNode(elementName, popName, elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -5035,16 +5502,24 @@ public abstract class TreeBuilder<T> imp
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         // Can't be called for custom elements
-        T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes, fragment ? null
-                : form);
+        T elt;
+        T formOwner = form == null || fragment || isTemplateContents() ? null : form;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.getName(),
+                    attributes, formOwner
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(),
+                    attributes, formOwner, currentNode
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
+            appendElement(elt, currentNode);
         }
-        StackNode<T> node = new StackNode<T>(elementName, elt
+        StackNode<T> node = createStackNode(elementName, elt
                 // [NOCPP[
                 , errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
         // ]NOCPP]
@@ -5052,19 +5527,49 @@ public abstract class TreeBuilder<T> imp
         push(node);
     }
 
+    private void appendVoidElementToCurrent(
+            ElementName elementName, HtmlAttributes attributes)
+            throws SAXException {
+        @Local String popName = elementName.getName();
+        // [NOCPP[
+        checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
+        if (!elementName.isInterned()) {
+            popName = checkPopName(popName);
+        }
+        // ]NOCPP]
+        T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+        T elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
+                // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                );
+        appendElement(elt, currentNode);
+        elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
+        elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
+    }
+
     private void appendVoidElementToCurrentMayFoster(
-            @Local String name, HtmlAttributes attributes, T form) throws SAXException {
+            ElementName elementName, HtmlAttributes attributes, T form) throws SAXException {
+        @Local String name = elementName.getName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         // Can't be called for custom elements
-        T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes, fragment ? null : form);
+        T elt;
+        T formOwner = form == null || fragment || isTemplateContents() ? null : form;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", name,
+                    attributes, formOwner
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", name,
+
+                    attributes, formOwner, currentNode
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
+            appendElement(elt, currentNode);
         }
         elementPushed("http://www.w3.org/1999/xhtml", name, elt);
         elementPopped("http://www.w3.org/1999/xhtml", name, elt);
@@ -5073,20 +5578,26 @@ public abstract class TreeBuilder<T> imp
     private void appendVoidElementToCurrentMayFoster(
             ElementName elementName, HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.name;
+        @Local String popName = elementName.getName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes);
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
+                    // CPPONLY: , htmlCreator(elementName.getHtmlCreator())
+                    );
+            appendElement(elt, currentNode);
         }
         elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
         elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
@@ -5095,20 +5606,26 @@ public abstract class TreeBuilder<T> imp
     private void appendVoidElementToCurrentMayFosterSVG(
             ElementName elementName, HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.camelCaseName;
+        @Local String popName = elementName.getCamelCaseName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/2000/svg");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/2000/svg", popName, attributes);
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes
+                    // CPPONLY: , svgCreator(elementName.getSvgCreator())
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
+                    // CPPONLY: , svgCreator(elementName.getSvgCreator())
+                    );
+            appendElement(elt, currentNode);
         }
         elementPushed("http://www.w3.org/2000/svg", popName, elt);
         elementPopped("http://www.w3.org/2000/svg", popName, elt);
@@ -5117,68 +5634,94 @@ public abstract class TreeBuilder<T> imp
     private void appendVoidElementToCurrentMayFosterMathML(
             ElementName elementName, HtmlAttributes attributes)
             throws SAXException {
-        @Local String popName = elementName.name;
+        @Local String popName = elementName.getName();
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1998/Math/MathML");
-        if (elementName.isCustom()) {
+        if (!elementName.isInterned()) {
             popName = checkPopName(popName);
         }
         // ]NOCPP]
-        T elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
+        T elt;
         StackNode<T> current = stack[currentPtr];
         if (current.isFosterParenting()) {
             fatal();
-            insertIntoFosterParent(elt);
+            elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes
+                    // CPPONLY: , htmlCreator(null)
+                    );
         } else {
-            appendElement(elt, current.node);
+            T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+            elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
+                    // CPPONLY: , htmlCreator(null)
+                    );
+            appendElement(elt, currentNode);
         }
         elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
         elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
     }
 
-    private void appendVoidElementToCurrent(
-            @Local String name, HtmlAttributes attributes, T form) throws SAXException {
+    private void appendVoidInputToCurrent(HtmlAttributes attributes, T form) throws SAXException {
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
         // Can't be called for custom elements
-        T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes, fragment ? null : form);
-        StackNode<T> current = stack[currentPtr];
-        appendElement(elt, current.node);
-        elementPushed("http://www.w3.org/1999/xhtml", name, elt);
-        elementPopped("http://www.w3.org/1999/xhtml", name, elt);
+        T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
+        T elt = createElement("http://www.w3.org/1999/xhtml", "input", attributes,
+                form == null || fragment || isTemplateContents() ? null : form, currentNode
+                        // CPPONLY: , htmlCreator(NS_NewHTMLInputElement)
+                        );
+        appendElement(elt, currentNode);
+        elementPushed("http://www.w3.org/1999/xhtml", "input", elt);
+        elementPopped("http://www.w3.org/1999/xhtml", "input", elt);
     }
 
     private void appendVoidFormToCurrent(HtmlAttributes attributes) throws SAXException {
         // [NOCPP[
         checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
         // ]NOCPP]
+        T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
         T elt = createElement("http://www.w3.org/1999/xhtml", "form",
-                attributes);
+                attributes, currentNode
+                // CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
+                );
         formPointer = elt;
         // ownership transferred to form pointer
-        StackNode<T> current = stack[currentPtr];
-        appendElement(elt, current.node);
+        appendElement(elt, currentNode);
         elementPushed("http://www.w3.org/1999/xhtml", "form", elt);
         elementPopped("http://www.w3.org/1999/xhtml", "form", elt);
     }
 
     // [NOCPP[
-    
+
     private final void accumulateCharactersForced(@Const @NoLength char[] buf,
             int start, int length) throws SAXException {
-        int newLen = charBufferLen + length;
-        if (newLen > charBuffer.length) {
-            char[] newBuf = new char[newLen];
+        System.arraycopy(buf, start, charBuffer, charBufferLen, length);
+        charBufferLen += length;
+    }
+
+    @Override public void ensureBufferSpace(int inputLength)
+            throws SAXException {
+        // TODO: Unify Tokenizer.strBuf and TreeBuilder.charBuffer so that
+        // this method becomes unnecessary.
+        int worstCase = charBufferLen + inputLength;
+        if (charBuffer == null) {
+            // Add an arbitrary small value to avoid immediate reallocation
+            // once there are a few characters in the buffer.
+            charBuffer = new char[worstCase + 128];
+        } else if (worstCase > charBuffer.length) {
+            // HotSpot reportedly allocates memory with 8-byte accuracy, so
+            // there's no point in trying to do math here to avoid slop.
+            // Maybe we should add some small constant to worstCase here
+            // but not doing that without profiling. In C++ with jemalloc,
+            // the corresponding method should do math to round up here
+            // to avoid slop.
+            char[] newBuf = new char[worstCase];
             System.arraycopy(charBuffer, 0, newBuf, 0, charBufferLen);
             charBuffer = newBuf;
         }
-        System.arraycopy(buf, start, charBuffer, charBufferLen, length);
-        charBufferLen = newLen;
     }
-    
+
     // ]NOCPP]
-    
+
     protected void accumulateCharacters(@Const @NoLength char[] buf, int start,
             int length) throws SAXException {
         appendCharacters(stack[currentPtr].node, buf, start, length);
@@ -5191,11 +5734,17 @@ public abstract class TreeBuilder<T> imp
     }
 
     protected abstract T createElement(@NsUri String ns, @Local String name,
-            HtmlAttributes attributes) throws SAXException;
+            HtmlAttributes attributes, T intendedParent
+            // CPPONLY: , @Creator Object creator
+            ) throws SAXException;
 
     protected T createElement(@NsUri String ns, @Local String name,
-            HtmlAttributes attributes, T form) throws SAXException {
-        return createElement("http://www.w3.org/1999/xhtml", name, attributes);
+            HtmlAttributes attributes, T form, T intendedParent
+            // CPPONLY: , @Creator Object creator
+            ) throws SAXException {
+        return createElement("http://www.w3.org/1999/xhtml", name, attributes, intendedParent
+                // CPPONLY: , creator
+                );
     }
 
     protected abstract T createHtmlElementSetAsRoot(HtmlAttributes attributes)
@@ -5214,6 +5763,22 @@ public abstract class TreeBuilder<T> imp
     protected abstract void insertFosterParentedChild(T child, T table,
             T stackParent) throws SAXException;
 
+    // We don't generate CPP code for this method because it is not used in generated CPP
+    // code. Instead, the form owner version of this method is called with a null form owner.
+    // [NOCPP[
+
+    protected abstract T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+            HtmlAttributes attributes, T table, T stackParent) throws SAXException;
+
+    // ]NOCPP]
+
+    protected T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
+            HtmlAttributes attributes, T form, T table, T stackParent
+            // CPPONLY: , @Creator Object creator
+            ) throws SAXException {
+        return createAndInsertFosterParentedElement(ns, name, attributes, table, stackParent);
+    };
+
     protected abstract void insertFosterParentedCharacters(
             @NoLength char[] buf, int start, int length, T table, T stackParent)
             throws SAXException;
@@ -5221,8 +5786,6 @@ public abstract class TreeBuilder<T> imp
     protected abstract void appendCharacters(T parent, @NoLength char[] buf,
             int start, int length) throws SAXException;
 
-    protected abstract void appendIsindexPrompt(T parent) throws SAXException;
-    
     protected abstract void appendComment(T parent, @NoLength char[] buf,
             int start, int length) throws SAXException;
 
@@ -5263,7 +5826,7 @@ public abstract class TreeBuilder<T> imp
     // [NOCPP[
 
     protected void documentMode(DocumentMode m, String publicIdentifier,
-            String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+            String systemIdentifier)
             throws SAXException {
 
     }
@@ -5281,7 +5844,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Sets the errorHandler.
-     * 
+     *
      * @param errorHandler
      *            the errorHandler to set
      */
@@ -5291,7 +5854,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Returns the errorHandler.
-     * 
+     *
      * @return the errorHandler
      */
     public ErrorHandler getErrorHandler() {
@@ -5300,7 +5863,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * The argument MUST be an interned string or <code>null</code>.
-     * 
+     *
      * @param context
      */
     public final void setFragmentContext(@Local String context) {
@@ -5319,19 +5882,35 @@ public abstract class TreeBuilder<T> imp
     @Inline public boolean cdataSectionAllowed() throws SAXException {
         return isInForeign();
     }
-    
+
     private boolean isInForeign() {
         return currentPtr >= 0
                 && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml";
     }
 
+    private boolean isInForeignButNotHtmlOrMathTextIntegrationPoint() {
+        if (currentPtr < 0) {
+            return false;
+        }
+        return !isSpecialParentInForeign(stack[currentPtr]);
+    }
+
     /**
      * The argument MUST be an interned string or <code>null</code>.
-     * 
+     *
      * @param context
      */
     public final void setFragmentContext(@Local String context,
             @NsUri String ns, T node, boolean quirks) {
+        // [NOCPP[
+        if (!((context == null && ns == null)
+                || "http://www.w3.org/1999/xhtml" == ns
+                || "http://www.w3.org/2000/svg" == ns || "http://www.w3.org/1998/Math/MathML" == ns)) {
+            throw new IllegalArgumentException(
+                    "The namespace must be the HTML, SVG or MathML namespace (or null when the local name is null). Got: "
+                            + ns);
+        }
+        // ]NOCPP]
         this.contextName = context;
         this.contextNamespace = ns;
         this.contextNode = node;
@@ -5345,7 +5924,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Returns the scriptingEnabled.
-     * 
+     *
      * @return the scriptingEnabled
      */
     public boolean isScriptingEnabled() {
@@ -5354,7 +5933,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Sets the scriptingEnabled.
-     * 
+     *
      * @param scriptingEnabled
      *            the scriptingEnabled to set
      */
@@ -5362,25 +5941,32 @@ public abstract class TreeBuilder<T> imp
         this.scriptingEnabled = scriptingEnabled;
     }
 
-    // [NOCPP[
+    public void setForceNoQuirks(boolean forceNoQuirks) {
+        this.forceNoQuirks = forceNoQuirks;
+    }
 
-    /**
-     * Sets the doctypeExpectation.
-     * 
-     * @param doctypeExpectation
-     *            the doctypeExpectation to set
-     */
-    public void setDoctypeExpectation(DoctypeExpectation doctypeExpectation) {
-        this.doctypeExpectation = doctypeExpectation;
+    // Redundant method retained because previously public.
+    public void setIsSrcdocDocument(boolean isSrcdocDocument) {
+        this.setForceNoQuirks(isSrcdocDocument);
     }
 
+    public boolean isAllowDeclarativeShadowRoots() {
+        return allowDeclarativeShadowRoots;
+    }
+
+    public void setAllowDeclarativeShadowRoots(boolean allow) {
+        allowDeclarativeShadowRoots = allow;
+    }
+
+    // [NOCPP[
+
     public void setNamePolicy(XmlViolationPolicy namePolicy) {
         this.namePolicy = namePolicy;
     }
 
     /**
      * Sets the documentModeHandler.
-     * 
+     *
      * @param documentModeHandler
      *            the documentModeHandler to set
      */
@@ -5390,7 +5976,7 @@ public abstract class TreeBuilder<T> imp
 
     /**
      * Sets the reportingDoctype.
-     * 
+     *
      * @param reportingDoctype
      *            the reportingDoctype to set
      */
@@ -5408,7 +5994,7 @@ public abstract class TreeBuilder<T> imp
         if (charBufferLen > 0) {
             if ((mode == IN_TABLE || mode == IN_TABLE_BODY || mode == IN_ROW)
                     && charBufferContainsNonWhitespace()) {
-                err("Misplaced non-space characters insided a table.");
+                errNonSpaceInTable();
                 reconstructTheActiveFormattingElements();
                 if (!stack[currentPtr].isFosterParenting()) {
                     // reconstructing gave us a new current node
@@ -5417,16 +6003,19 @@ public abstract class TreeBuilder<T> imp
                     charBufferLen = 0;
                     return;
                 }
-                int eltPos = findLastOrRoot(TreeBuilder.TABLE);
-                StackNode<T> node = stack[eltPos];
-                T elt = node.node;
-                if (eltPos == 0) {
-                    appendCharacters(elt, charBuffer, 0, charBufferLen);
+
+                int tablePos = findLastOrRoot(TreeBuilder.TABLE);
+                int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
+
+                if (templatePos >= tablePos) {
+                    appendCharacters(stack[templatePos].node, charBuffer, 0, charBufferLen);
                     charBufferLen = 0;
                     return;
                 }
+
+                StackNode<T> tableElt = stack[tablePos];
                 insertFosterParentedCharacters(charBuffer, 0, charBufferLen,
-                        elt, stack[eltPos - 1].node);
+                        tableElt.node, stack[tablePos - 1].node);
                 charBufferLen = 0;
                 return;
             }
@@ -5456,7 +6045,7 @@ public abstract class TreeBuilder<T> imp
      * creation is only supported immediately after a script end tag has been
      * processed. In C++ the caller is responsible for calling
      * <code>delete</code> on the returned object.
-     * 
+     *
      * @return a snapshot.
      * @throws SAXException
      */
@@ -5466,12 +6055,14 @@ public abstract class TreeBuilder<T> imp
         for (int i = 0; i < listCopy.length; i++) {
             StackNode<T> node = listOfActiveFormattingElements[i];
             if (node != null) {
-                StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+                StackNode<T> newNode = new StackNode<T>(-1);
+                newNode.setValues(node.getFlags(), node.ns,
                         node.name, node.node, node.popName,
-                        node.attributes.cloneAttributes(null)
+                        node.attributes.cloneAttributes()
+                        // CPPONLY: , node.getHtmlCreator()
                         // [NOCPP[
                         , node.getLocator()
-                // ]NOCPP]
+                        // ]NOCPP]
                 );
                 listCopy[i] = newNode;
             } else {
@@ -5483,12 +6074,14 @@ public abstract class TreeBuilder<T> imp
             StackNode<T> node = stack[i];
             int listIndex = findInListOfActiveFormattingElements(node);
             if (listIndex == -1) {
-                StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
+                StackNode<T> newNode = new StackNode<T>(-1);
+                newNode.setValues(node.getFlags(), node.ns,
                         node.name, node.node, node.popName,
                         null
+                        // CPPONLY: , node.getHtmlCreator()
                         // [NOCPP[
                         , node.getLocator()
-                // ]NOCPP]
+                        // ]NOCPP]
                 );
                 stackCopy[i] = newNode;
             } else {
@@ -5496,7 +6089,12 @@ public abstract class TreeBuilder<T> imp
                 stackCopy[i].retain();
             }
         }
-        return new StateSnapshot<T>(stackCopy, listCopy, formPointer, headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk, needToDropLF, quirks);
+        int[] templateModeStackCopy = new int[templateModePtr + 1];
+        System.arraycopy(templateModeStack, 0, templateModeStackCopy, 0,
+                templateModeStackCopy.length);
+        return new StateSnapshot<T>(stackCopy, listCopy, templateModeStackCopy, formPointer,
+                headPointer, mode, originalMode, framesetOk,
+                needToDropLF, quirks);
     }
 
     public boolean snapshotMatches(TreeBuilderState<T> snapshot) {
@@ -5504,12 +6102,14 @@ public abstract class TreeBuilder<T> imp
         int stackLen = snapshot.getStackLength();
         StackNode<T>[] listCopy = snapshot.getListOfActiveFormattingElements();
         int listLen = snapshot.getListOfActiveFormattingElementsLength();
+        int[] templateModeStackCopy = snapshot.getTemplateModeStack();
+        int templateModeStackLen = snapshot.getTemplateModeStackLength();
 
         if (stackLen != currentPtr + 1
                 || listLen != listPtr + 1
+                || templateModeStackLen != templateModePtr + 1
                 || formPointer != snapshot.getFormPointer()
                 || headPointer != snapshot.getHeadPointer()
-                || deepTreeSurrogateParent != snapshot.getDeepTreeSurrogateParent()
                 || mode != snapshot.getMode()
                 || originalMode != snapshot.getOriginalMode()
                 || framesetOk != snapshot.isFramesetOk()
@@ -5535,20 +6135,28 @@ public abstract class TreeBuilder<T> imp
                 return false;
             }
         }
+        for (int i = templateModeStackLen - 1; i >=0; i--) {
+            if (templateModeStackCopy[i] != templateModeStack[i]) {
+                return false;
+            }
+        }
         return true;
     }
 
     @SuppressWarnings("unchecked") public void loadState(
-            TreeBuilderState<T> snapshot, Interner interner)
+            TreeBuilderState<T> snapshot)
             throws SAXException {
+        // CPPONLY: mCurrentHtmlScriptCannotDocumentWriteOrBlock = false;
         StackNode<T>[] stackCopy = snapshot.getStack();
         int stackLen = snapshot.getStackLength();
         StackNode<T>[] listCopy = snapshot.getListOfActiveFormattingElements();
         int listLen = snapshot.getListOfActiveFormattingElementsLength();
-        
+        int[] templateModeStackCopy = snapshot.getTemplateModeStack();
+        int templateModeStackLen = snapshot.getTemplateModeStackLength();
+
         for (int i = 0; i <= listPtr; i++) {
             if (listOfActiveFormattingElements[i] != null) {
-                listOfActiveFormattingElements[i].release();
+                listOfActiveFormattingElements[i].release(this);
             }
         }
         if (listOfActiveFormattingElements.length < listLen) {
@@ -5557,20 +6165,26 @@ public abstract class TreeBuilder<T> imp
         listPtr = listLen - 1;
 
         for (int i = 0; i <= currentPtr; i++) {
-            stack[i].release();
+            stack[i].release(this);
         }
         if (stack.length < stackLen) {
             stack = new StackNode[stackLen];
         }
         currentPtr = stackLen - 1;
 
+        if (templateModeStack.length < templateModeStackLen) {
+            templateModeStack = new int[templateModeStackLen];
+        }
+        templateModePtr = templateModeStackLen - 1;
+
         for (int i = 0; i < listLen; i++) {
             StackNode<T> node = listCopy[i];
             if (node != null) {
-                StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
-                        Portability.newLocalFromLocal(node.name, interner), node.node,
-                        Portability.newLocalFromLocal(node.popName, interner),
-                        node.attributes.cloneAttributes(null)
+                StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
+                        node.name, node.node,
+                        node.popName,
+                        node.attributes.cloneAttributes()
+                        // CPPONLY: , node.getHtmlCreator()
                         // [NOCPP[
                         , node.getLocator()
                 // ]NOCPP]
@@ -5584,13 +6198,14 @@ public abstract class TreeBuilder<T> imp
             StackNode<T> node = stackCopy[i];
             int listIndex = findInArray(node, listCopy);
             if (listIndex == -1) {
-                StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
-                        Portability.newLocalFromLocal(node.name, interner), node.node,
-                        Portability.newLocalFromLocal(node.popName, interner),
+                StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
+                        node.name, node.node,
+                        node.popName,
                         null
+                        // CPPONLY: , node.getHtmlCreator()
                         // [NOCPP[
                         , node.getLocator()
-                // ]NOCPP]       
+                // ]NOCPP]
                 );
                 stack[i] = newNode;
             } else {
@@ -5598,9 +6213,9 @@ public abstract class TreeBuilder<T> imp
                 stack[i].retain();
             }
         }
+        System.arraycopy(templateModeStackCopy, 0, templateModeStack, 0, templateModeStackLen);
         formPointer = snapshot.getFormPointer();
         headPointer = snapshot.getHeadPointer();
-        deepTreeSurrogateParent = snapshot.getDeepTreeSurrogateParent();
         mode = snapshot.getMode();
         originalMode = snapshot.getOriginalMode();
         framesetOk = snapshot.isFramesetOk();
@@ -5618,33 +6233,53 @@ public abstract class TreeBuilder<T> imp
     }
 
     /**
+     * Returns <code>stack[stackPos].node</code> if <code>stackPos</code> is
+     * smaller than Blink's magic limit or the node at Blink's magic limit
+     * otherwise.
+     *
+     * In order to get Blink-compatible handling of excessive deeply-nested
+     * markup, this method must be used to obtain the node that is used as the
+     * parent node of an insertion.
+     *
+     * Blink's magic number is 512, but our counting is off by one compared to
+     * Blink's way of counting, so in order to get the same
+     * externally-observable outcome, we use 511 as our magic number.
+     *
+     * @param stackPos the stack position to attempt to read
+     * @return node at the position capped to Blink's magic number
+     * @throws SAXException
+     */
+    private T nodeFromStackWithBlinkCompat(int stackPos) throws SAXException {
+        // Magic number if off by one relative to Blink's magic number, but the
+        // outcome is the same, because the counting is different by one.
+        if (stackPos > 511) {
+            errDeepTree();
+            return stack[511].node;
+        }
+        return stack[stackPos].node;
+    }
+    /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
      */
+    @Override
     public T getFormPointer() {
         return formPointer;
     }
 
     /**
      * Returns the headPointer.
-     * 
+     *
      * @return the headPointer
      */
+    @Override
     public T getHeadPointer() {
         return headPointer;
     }
-    
-    /**
-     * Returns the deepTreeSurrogateParent.
-     * 
-     * @return the deepTreeSurrogateParent
-     */
-    public T getDeepTreeSurrogateParent() {
-        return deepTreeSurrogateParent;
-    }
 
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
      */
+    @Override
     public StackNode<T>[] getListOfActiveFormattingElements() {
         return listOfActiveFormattingElements;
     }
@@ -5652,51 +6287,65 @@ public abstract class TreeBuilder<T> imp
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
      */
+    @Override
     public StackNode<T>[] getStack() {
         return stack;
     }
 
     /**
+     * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
+     */
+    @Override
+    public int[] getTemplateModeStack() {
+        return templateModeStack;
+    }
+
+    /**
      * Returns the mode.
-     * 
+     *
      * @return the mode
      */
+    @Override
     public int getMode() {
         return mode;
     }
 
     /**
      * Returns the originalMode.
-     * 
+     *
      * @return the originalMode
      */
+    @Override
     public int getOriginalMode() {
         return originalMode;
     }
 
     /**
      * Returns the framesetOk.
-     * 
+     *
      * @return the framesetOk
      */
+    @Override
     public boolean isFramesetOk() {
         return framesetOk;
     }
-    
+
     /**
      * Returns the needToDropLF.
-     * 
+     *
      * @return the needToDropLF
      */
+    @Override
     public boolean isNeedToDropLF() {
         return needToDropLF;
     }
 
     /**
      * Returns the quirks.
-     * 
+     *
      * @return the quirks
      */
+    @Override
     public boolean isQuirks() {
         return quirks;
     }
@@ -5704,6 +6353,7 @@ public abstract class TreeBuilder<T> imp
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
      */
+    @Override
     public int getListOfActiveFormattingElementsLength() {
         return listPtr + 1;
     }
@@ -5711,8 +6361,336 @@ public abstract class TreeBuilder<T> imp
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
      */
+    @Override
     public int getStackLength() {
         return currentPtr + 1;
     }
 
+    /**
+     * @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
+     */
+    @Override
+    public int getTemplateModeStackLength() {
+        return templateModePtr + 1;
+    }
+
+    /**
+     * Complains about an over-deep tree. Theoretically this should just be
+     * a warning, but in practice authors should take this as an error.
+     *
+     * @throws SAXException
+     */
+    private void errDeepTree() throws SAXException {
+        err("The document tree is more than 513 elements deep, which causes Firefox and Chrome to flatten the tree.");
+    }
+
+    /**
+     * Reports a stray start tag.
+     * @param name the name of the stray tag
+     *
+     * @throws SAXException
+     */
+    private void errStrayStartTag(@Local String name) throws SAXException {
+        err("Stray start tag \u201C" + name + "\u201D.");
+    }
+
+    /**
+     * Reports a stray end tag.
+     * @param name the name of the stray tag
+     *
+     * @throws SAXException
+     */
+    private void errStrayEndTag(@Local String name) throws SAXException {
+        err("Stray end tag \u201C" + name + "\u201D.");
+    }
+
+    /**
+     * Reports a state when elements expected to be closed were not.
+     *
+     * @param eltPos the position of the start tag on the stack of the element
+     * being closed.
+     * @param name the name of the end tag
+     *
+     * @throws SAXException
+     */
+    private void errUnclosedElements(int eltPos, @Local String name) throws SAXException {
+        errNoCheck("End tag \u201C" + name + "\u201D seen, but there were open elements.");
+        errListUnclosedStartTags(eltPos);
+    }
+
+    /**
+     * Reports a state when elements expected to be closed ahead of an implied
+     * end tag but were not.
+     *
+     * @param eltPos the position of the start tag on the stack of the element
+     * being closed.
+     * @param name the name of the end tag
+     *
+     * @throws SAXException
+     */
+    private void errUnclosedElementsImplied(int eltPos, String name) throws SAXException {
+        errNoCheck("End tag \u201C" + name + "\u201D implied, but there were open elements.");
+        errListUnclosedStartTags(eltPos);
+    }
+
+    /**
+     * Reports a state when elements expected to be closed ahead of an implied
+     * table cell close.
+     *
+     * @param eltPos the position of the start tag on the stack of the element
+     * being closed.
+     * @throws SAXException
+     */
+    private void errUnclosedElementsCell(int eltPos) throws SAXException {
+        errNoCheck("A table cell was implicitly closed, but there were open elements.");
+        errListUnclosedStartTags(eltPos);
+    }
+
+    private void errStrayDoctype() throws SAXException {
+        err("Stray doctype.");
+    }
+
+    private void errAlmostStandardsDoctype() throws SAXException {
+        if (!forceNoQuirks) {
+            err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+        }
+    }
+
+    private void errQuirkyDoctype() throws SAXException {
+        if (!forceNoQuirks) {
+            err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
+        }
+    }
+
+    private void errNonSpaceInTrailer() throws SAXException {
+        err("Non-space character in page trailer.");
+    }
+
+    private void errNonSpaceAfterFrameset() throws SAXException {
+        err("Non-space after \u201Cframeset\u201D.");
+    }
+
+    private void errNonSpaceInFrameset() throws SAXException {
+        err("Non-space in \u201Cframeset\u201D.");
+    }
+
+    private void errNonSpaceAfterBody() throws SAXException {
+        err("Non-space character after body.");
+    }
+
+    private void errNonSpaceInColgroupInFragment() throws SAXException {
+        err("Non-space in \u201Ccolgroup\u201D when parsing fragment.");
+    }
+
+    private void errNonSpaceInNoscriptInHead() throws SAXException {
+        err("Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D.");
+    }
+
+    private void errFooBetweenHeadAndBody(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("\u201C" + name + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+    }
+
+    private void errStartTagWithoutDoctype() throws SAXException {
+        if (!forceNoQuirks) {
+            err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+        }
+    }
+
+    private void errNoSelectInTableScope() throws SAXException {
+        err("No \u201Cselect\u201D in table scope.");
+    }
+
+    private void errStartSelectWhereEndSelectExpected() throws SAXException {
+        err("\u201Cselect\u201D start tag where end tag expected.");
+    }
+
+    private void errStartTagWithSelectOpen(@Local String name)
+            throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("\u201C" + name
+                + "\u201D start tag with \u201Cselect\u201D open.");
+    }
+
+    private void errBadStartTagInNoscriptInHead(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Bad start tag in \u201C" + name
+                + "\u201D in \u201Cnoscript\u201D in \u201Chead\u201D.");
+    }
+
+    private void errImage() throws SAXException {
+        err("Saw a start tag \u201Cimage\u201D.");
+    }
+
+    private void errFooSeenWhenFooOpen(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Start tag \u201C" + name + "\u201D seen but an element of the same type was already open.");
+    }
+
+    private void errHeadingWhenHeadingOpen() throws SAXException {
+        err("Heading cannot be a child of another heading.");
+    }
+
+    private void errFramesetStart() throws SAXException {
+        err("\u201Cframeset\u201D start tag seen.");
+    }
+
+    private void errNoCellToClose() throws SAXException {
+        err("No cell to close.");
+    }
+
+    private void errStartTagInTable(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Start tag \u201C" + name
+                + "\u201D seen in \u201Ctable\u201D.");
+    }
+
+    private void errFormWhenFormOpen() throws SAXException {
+        err("Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.");
+    }
+
+    private void errTableSeenWhileTableOpen() throws SAXException {
+        err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.");
+    }
+
+    private void errStartTagInTableBody(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("\u201C" + name + "\u201D start tag in table body.");
+    }
+
+    private void errEndTagSeenWithoutDoctype() throws SAXException {
+        if (!forceNoQuirks) {
+            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+        }
+    }
+
+    private void errEndTagAfterBody() throws SAXException {
+        err("Saw an end tag after \u201Cbody\u201D had been closed.");
+    }
+
+    private void errEndTagSeenWithSelectOpen(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("\u201C" + name
+                + "\u201D end tag with \u201Cselect\u201D open.");
+    }
+
+    private void errGarbageInColgroup() throws SAXException {
+        err("Garbage in \u201Ccolgroup\u201D fragment.");
+    }
+
+    private void errEndTagBr() throws SAXException {
+        err("End tag \u201Cbr\u201D.");
+    }
+
+    private void errNoElementToCloseButEndTagSeen(@Local String name)
+            throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("No \u201C" + name + "\u201D element in scope but a \u201C"
+                + name + "\u201D end tag seen.");
+    }
+
+    private void errHtmlStartTagInForeignContext(@Local String name)
+            throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("HTML start tag \u201C" + name
+                + "\u201D in a foreign namespace context.");
+    }
+
+    private void errNoTableRowToClose() throws SAXException {
+        err("No table row to close.");
+    }
+
+    private void errNonSpaceInTable() throws SAXException {
+        err("Misplaced non-space characters inside a table.");
+    }
+
+    private void errUnclosedChildrenInRuby() throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Unclosed children in \u201Cruby\u201D.");
+    }
+
+    private void errStartTagSeenWithoutRuby(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Start tag \u201C"
+                + name
+                + "\u201D seen without a \u201Cruby\u201D element being open.");
+    }
+
+    private void errSelfClosing() throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.");
+    }
+
+    private void errNoCheckUnclosedElementsOnStack() throws SAXException {
+        errNoCheck("Unclosed elements on stack.");
+    }
+
+    private void errEndTagDidNotMatchCurrentOpenElement(@Local String name,
+            @Local String currOpenName) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("End tag \u201C"
+                + name
+                + "\u201D did not match the name of the current open element (\u201C"
+                + currOpenName + "\u201D).");
+    }
+
+    private void errEndTagViolatesNestingRules(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules.");
+    }
+
+    private void errEofWithUnclosedElements() throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("End of file seen and there were open elements.");
+        // just report all remaining unclosed elements
+        errListUnclosedStartTags(0);
+    }
+
+    /**
+     * Reports arriving at/near end of document with unclosed elements remaining.
+     *
+     * @param message
+     *            the message
+     * @throws SAXException
+     */
+    private void errEndWithUnclosedElements(@Local String name) throws SAXException {
+        if (errorHandler == null) {
+            return;
+        }
+        errNoCheck("End tag for  \u201C"
+                + name
+                + "\u201D seen, but there were unclosed elements.");
+        // just report all remaining unclosed elements
+        errListUnclosedStartTags(0);
+    }
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/TreeBuilderState.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/TreeBuilderState.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/TreeBuilderState.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/TreeBuilderState.java	2025-09-16 08:29:41.000000000 +0000
@@ -40,12 +40,19 @@ public interface TreeBuilderState<T> {
 
     /**
      * Returns the listOfActiveFormattingElements.
-     * 
+     *
      * @return the listOfActiveFormattingElements
      */
     public StackNode<T>[] getListOfActiveFormattingElements();
 
     /**
+     * Returns the stack of template insertion modes.
+     *
+     * @return the stack of template insertion modes
+     */
+    public int[] getTemplateModeStack();
+
+    /**
      * Returns the formPointer.
      * 
      * @return the formPointer
@@ -60,13 +67,6 @@ public interface TreeBuilderState<T> {
     public T getHeadPointer();
     
     /**
-     * Returns the deepTreeSurrogateParent.
-     * 
-     * @return the deepTreeSurrogateParent
-     */
-    public T getDeepTreeSurrogateParent();
-
-    /**
      * Returns the mode.
      * 
      * @return the mode
@@ -100,16 +100,23 @@ public interface TreeBuilderState<T> {
      * @return the quirks
      */
     public boolean isQuirks();
-    
+
     /**
      * Return the length of the stack.
      * @return the length of the stack.
      */
     public int getStackLength();
-    
+
     /**
      * Return the length of the list of active formatting elements.
      * @return the length of the list of active formatting elements.
      */
     public int getListOfActiveFormattingElementsLength();
+
+    /**
+     * Return the length of the stack of template insertion modes.
+     *
+     * @return the length of the stack of template insertion modes.
+     */
+    int getTemplateModeStackLength();
 }
\ No newline at end of file
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/UTF16Buffer.java 1.4+r20250916-1/src/nu/validator/htmlparser/impl/UTF16Buffer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/impl/UTF16Buffer.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/impl/UTF16Buffer.java	2025-09-16 08:29:41.000000000 +0000
@@ -51,6 +51,8 @@ public final class UTF16Buffer {
      */
     private int end;
 
+    //[NOCPP[
+    
     /**
      * Constructor for wrapping an existing UTF-16 code unit array.
      * 
@@ -67,6 +69,8 @@ public final class UTF16Buffer {
         this.end = end;
     }
 
+    // ]NOCPP]
+    
     /**
      * Returns the start index.
      * 
@@ -114,6 +118,15 @@ public final class UTF16Buffer {
     }
 
     /**
+     * Returns <code>end - start</code>.
+     *
+     * @return <code>end - start</code>
+     */
+    public int getLength() {
+        return end - start;
+    }
+
+    /**
      * Adjusts the start index to skip over the first character if it is a line
      * feed and the previous character was a carriage return.
      * 
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/Driver.java 1.4+r20250916-1/src/nu/validator/htmlparser/io/Driver.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/Driver.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/io/Driver.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2005, 2006, 2007 Henri Sivonen
- * Copyright (c) 2007-2008 Mozilla Foundation
+ * Copyright (c) 2007-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -31,13 +31,11 @@ import java.nio.charset.UnsupportedChars
 import nu.validator.htmlparser.common.CharacterHandler;
 import nu.validator.htmlparser.common.EncodingDeclarationHandler;
 import nu.validator.htmlparser.common.Heuristics;
-import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.common.TransitionHandler;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 import nu.validator.htmlparser.extra.NormalizationChecker;
 import nu.validator.htmlparser.impl.ErrorReportingTokenizer;
 import nu.validator.htmlparser.impl.Tokenizer;
-import nu.validator.htmlparser.impl.TreeBuilder;
 import nu.validator.htmlparser.impl.UTF16Buffer;
 import nu.validator.htmlparser.rewindable.RewindableInputStream;
 
@@ -56,12 +54,12 @@ public class Driver implements EncodingD
     private Reader reader;
 
     /**
-     * The reference to the rewindable byte stream. <code>null</code> if p
-     * rohibited or no longer needed.
+     * The reference to the rewindable byte stream. <code>null</code> if 
+     * prohibited or no longer needed.
      */
     private RewindableInputStream rewindableInputStream;
 
-    private boolean swallowBom;
+    private boolean swallowBom = true;
 
     private Encoding characterEncoding;
 
@@ -175,12 +173,29 @@ public class Driver implements EncodingD
      *             if the stream threw
      */
     public void tokenize(InputSource is) throws SAXException, IOException {
+        int bufferSize = 2048;
+        tokenize(is, bufferSize);
+    }
+    /**
+     * Runs the tokenization. This is the main entry point.
+     *
+     * @param is
+     *            the input source
+     * @param bufferSize
+     *            the size of the buffer to feed to the tokenizer
+     * @throws SAXException
+     *             on fatal error (if configured to treat XML violations as
+     *             fatal) or if the token handler threw
+     * @throws IOException
+     *             if the stream threw
+     */
+    public void tokenize(InputSource is, int bufferSize)
+            throws SAXException, IOException {
         if (is == null) {
             throw new IllegalArgumentException("InputSource was null.");
         }
         tokenizer.start();
         confidence = Confidence.TENTATIVE;
-        swallowBom = true;
         rewindableInputStream = null;
         tokenizer.initLocation(is.getPublicId(), is.getSystemId());
         this.reader = is.getCharacterStream();
@@ -198,6 +213,11 @@ public class Driver implements EncodingD
                 this.reader = new HtmlInputStreamReader(inputStream,
                         tokenizer.getErrorHandler(), tokenizer, this, heuristics);
             } else {
+                if (this.characterEncoding != Encoding.UTF8) {
+                    errorWithoutLocation("Legacy encoding \u201C"
+                            + this.characterEncoding.getCanonName()
+                            + "\u201D used. Documents must use UTF-8.");
+                }
                 becomeConfident();
                 this.reader = new HtmlInputStreamReader(inputStream,
                         tokenizer.getErrorHandler(), tokenizer, this, this.characterEncoding);
@@ -213,11 +233,7 @@ public class Driver implements EncodingD
                         CharacterHandler ch = characterHandlers[i];
                         ch.start();
                     }
-                    runStates();
-                    if (confidence == Confidence.TENTATIVE
-                            && !tokenizer.isAlreadyComplainedAboutNonAscii()) {
-                        warnWithoutLocation("The character encoding of the document was not declared.");
-                    }
+                    runStates(bufferSize);
                     break;
                 } catch (ReparseException e) {
                     if (rewindableInputStream == null) {
@@ -267,12 +283,12 @@ public class Driver implements EncodingD
         }
     }
 
-    void dontSwallowBom() {
+    public void dontSwallowBom() {
         swallowBom = false;
     }
 
-    private void runStates() throws SAXException, IOException {
-        char[] buffer = new char[2048];
+    private void runStates(int bufferSize) throws SAXException, IOException {
+        char[] buffer = new char[bufferSize];
         UTF16Buffer bufr = new UTF16Buffer(buffer, 0, 0);
         boolean lastWasCR = false;
         int len = -1;
@@ -417,14 +433,14 @@ public class Driver implements EncodingD
      *            the message
      * @throws SAXException
      */
-    protected void warnWithoutLocation(String message) throws SAXException {
+    protected void errorWithoutLocation(String message) throws SAXException {
         ErrorHandler errorHandler = tokenizer.getErrorHandler();
         if (errorHandler == null) {
             return;
         }
         SAXParseException spe = new SAXParseException(message, null,
                 tokenizer.getSystemId(), -1, -1);
-        errorHandler.warning(spe);
+        errorHandler.error(spe);
     }
 
     /**
@@ -556,15 +572,6 @@ public class Driver implements EncodingD
     }
 
     /**
-     * @param html4ModeCompatibleWithXhtml1Schemata
-     * @see nu.validator.htmlparser.impl.Tokenizer#setHtml4ModeCompatibleWithXhtml1Schemata(boolean)
-     */
-    public void setHtml4ModeCompatibleWithXhtml1Schemata(
-            boolean html4ModeCompatibleWithXhtml1Schemata) {
-        tokenizer.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
-    }
-
-    /**
      * @param mappingLangToXmlLang
      * @see nu.validator.htmlparser.impl.Tokenizer#setMappingLangToXmlLang(boolean)
      */
@@ -589,7 +596,7 @@ public class Driver implements EncodingD
     }
 
     public String getCharacterEncoding() throws SAXException {
-        return characterEncoding.getCanonName();
+        return characterEncoding == null ? null : characterEncoding.getCanonName();
     }
 
     public Locator getDocumentLocator() {
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/Encoding.java 1.4+r20250916-1/src/nu/validator/htmlparser/io/Encoding.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/Encoding.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/io/Encoding.java	2025-09-16 08:29:41.000000000 +0000
@@ -64,15 +64,238 @@ public class Encoding {
             "xutf32lebom", "xutf16oppositeendian", "xutf16platformendian",
             "xutf32oppositeendian", "xutf32platformendian" };
 
-    private static String[] NOT_OBSCURE = { "big5", "big5hkscs", "eucjp",
-            "euckr", "gb18030", "gbk", "iso2022jp", "iso2022kr", "iso88591",
-            "iso885913", "iso885915", "iso88592", "iso88593", "iso88594",
-            "iso88595", "iso88596", "iso88597", "iso88598", "iso88599",
-            "koi8r", "shiftjis", "tis620", "usascii", "utf16", "utf16be",
-            "utf16le", "utf8", "windows1250", "windows1251", "windows1252",
-            "windows1253", "windows1254", "windows1255", "windows1256",
-            "windows1257", "windows1258" };
-
+    /* From the table at https://encoding.spec.whatwg.org/#names-and-labels,
+     * everything in the Labels column, sorted */
+    private static String[] NOT_OBSCURE = { //
+            "866", //
+            "ansi_x3.4-1968", //
+            "arabic", //
+            "ascii", //
+            "asmo-708", //
+            "big5", //
+            "big5-hkscs", //
+            "chinese", //
+            "cn-big5", //
+            "cp1250", //
+            "cp1251", //
+            "cp1252", //
+            "cp1253", //
+            "cp1254", //
+            "cp1255", //
+            "cp1256", //
+            "cp1257", //
+            "cp1258", //
+            "cp819", //
+            "cp866", //
+            "csbig5", //
+            "cseuckr", //
+            "cseucpkdfmtjapanese", //
+            "csgb2312", //
+            "csibm866", //
+            "csiso2022jp", //
+            "csiso2022kr", //
+            "csiso58gb231280", //
+            "csiso88596e", //
+            "csiso88596i", //
+            "csiso88598e", //
+            "csiso88598i", //
+            "csisolatin1", //
+            "csisolatin2", //
+            "csisolatin3", //
+            "csisolatin4", //
+            "csisolatin5", //
+            "csisolatin6", //
+            "csisolatin9", //
+            "csisolatinarabic", //
+            "csisolatincyrillic", //
+            "csisolatingreek", //
+            "csisolatinhebrew", //
+            "cskoi8r", //
+            "csksc56011987", //
+            "csmacintosh", //
+            "csshiftjis", //
+            "csunicode", //
+            "cyrillic", //
+            "dos-874", //
+            "ecma-114", //
+            "ecma-118", //
+            "elot_928", //
+            "euc-jp", //
+            "euc-kr", //
+            "gb18030", //
+            "gb2312", //
+            "gb_2312", //
+            "gb_2312-80", //
+            "gbk", //
+            "greek", //
+            "greek8", //
+            "hebrew", //
+            "hz-gb-2312", //
+            "ibm819", //
+            "ibm866", //
+            "iso-10646-ucs-2", //
+            "iso-2022-cn", //
+            "iso-2022-cn-ext", //
+            "iso-2022-jp", //
+            "iso-2022-kr", //
+            "iso-8859-1", //
+            "iso-8859-10", //
+            "iso-8859-11", //
+            "iso-8859-13", //
+            "iso-8859-14", //
+            "iso-8859-15", //
+            "iso-8859-16", //
+            "iso-8859-2", //
+            "iso-8859-3", //
+            "iso-8859-4", //
+            "iso-8859-5", //
+            "iso-8859-6", //
+            "iso-8859-6-e", //
+            "iso-8859-6-i", //
+            "iso-8859-7", //
+            "iso-8859-8", //
+            "iso-8859-8-e", //
+            "iso-8859-8-i", //
+            "iso-8859-9", //
+            "iso-ir-100", //
+            "iso-ir-101", //
+            "iso-ir-109", //
+            "iso-ir-110", //
+            "iso-ir-126", //
+            "iso-ir-127", //
+            "iso-ir-138", //
+            "iso-ir-144", //
+            "iso-ir-148", //
+            "iso-ir-149", //
+            "iso-ir-157", //
+            "iso-ir-58", //
+            "iso8859-1", //
+            "iso8859-10", //
+            "iso8859-11", //
+            "iso8859-13", //
+            "iso8859-14", //
+            "iso8859-15", //
+            "iso8859-2", //
+            "iso8859-3", //
+            "iso8859-4", //
+            "iso8859-5", //
+            "iso8859-6", //
+            "iso8859-7", //
+            "iso8859-8", //
+            "iso8859-9", //
+            "iso88591", //
+            "iso885910", //
+            "iso885911", //
+            "iso885913", //
+            "iso885914", //
+            "iso885915", //
+            "iso88592", //
+            "iso88593", //
+            "iso88594", //
+            "iso88595", //
+            "iso88596", //
+            "iso88597", //
+            "iso88598", //
+            "iso88599", //
+            "iso_8859-1", //
+            "iso_8859-15", //
+            "iso_8859-1:1987", //
+            "iso_8859-2", //
+            "iso_8859-2:1987", //
+            "iso_8859-3", //
+            "iso_8859-3:1988", //
+            "iso_8859-4", //
+            "iso_8859-4:1988", //
+            "iso_8859-5", //
+            "iso_8859-5:1988", //
+            "iso_8859-6", //
+            "iso_8859-6:1987", //
+            "iso_8859-7", //
+            "iso_8859-7:1987", //
+            "iso_8859-8", //
+            "iso_8859-8:1988", //
+            "iso_8859-9", //
+            "iso_8859-9:1989", //
+            "koi", //
+            "koi8", //
+            "koi8-r", //
+            "koi8-ru", //
+            "koi8-u", //
+            "koi8_r", //
+            "korean", //
+            "ks_c_5601-1987", //
+            "ks_c_5601-1989", //
+            "ksc5601", //
+            "ksc_5601", //
+            "l1", //
+            "l2", //
+            "l3", //
+            "l4", //
+            "l5", //
+            "l6", //
+            "l9", //
+            "latin1", //
+            "latin2", //
+            "latin3", //
+            "latin4", //
+            "latin5", //
+            "latin6", //
+            "logical", //
+            "mac", //
+            "macintosh", //
+            "ms932", //
+            "ms_kanji", //
+            "replacement", //
+            "shift-jis", //
+            "shift_jis", //
+            "sjis", //
+            "sun_eu_greek", //
+            "tis-620", //
+            "ucs-2", //
+            "unicode", //
+            "unicode-1-1-utf-8", //
+            "unicode11utf8", //
+            "unicode20utf8", //
+            "unicodefeff", //
+            "unicodefffe", //
+            "us-ascii", //
+            "utf-16", //
+            "utf-16be", //
+            "utf-16le", //
+            "utf-8", //
+            "utf8", //
+            "visual", //
+            "windows-1250", //
+            "windows-1251", //
+            "windows-1252", //
+            "windows-1253", //
+            "windows-1254", //
+            "windows-1255", //
+            "windows-1256", //
+            "windows-1257", //
+            "windows-1258", //
+            "windows-31j", //
+            "windows-874", //
+            "windows-949", //
+            "x-cp1250", //
+            "x-cp1251", //
+            "x-cp1252", //
+            "x-cp1253", //
+            "x-cp1254", //
+            "x-cp1255", //
+            "x-cp1256", //
+            "x-cp1257", //
+            "x-cp1258", //
+            "x-euc-jp", //
+            "x-gbk", //
+            "x-mac-cyrillic", //
+            "x-mac-roman", //
+            "x-mac-ukrainian", //
+            "x-sjis", //
+            "x-unicode20utf8", //
+            "x-user-defined", //
+            "x-x-big5", //
+    };
     private static Map<String, Encoding> encodingByCookedName = new HashMap<String, Encoding>();
 
     private final String canonName;
@@ -106,11 +329,12 @@ public class Encoding {
             Charset cs = entry.getValue();
             String name = toNameKey(cs.name());
             String canonName = toAsciiLowerCase(cs.name());
-            if (!isBanned(name)) {
+            if (!isBanned(stripDashAndUnderscore(name))) {
                 name = name.intern();
                 boolean asciiSuperset = asciiMapsToBasicLatin(testBuf, cs);
                 Encoding enc = new Encoding(canonName.intern(), cs,
-                        asciiSuperset, isObscure(name), isShouldNot(name),
+                        asciiSuperset, isObscure(name),
+                        isShouldNot(stripDashAndUnderscore(name)),
                         isLikelyEbcdic(name, asciiSuperset));
                 encodings.add(enc);
                 Set<String> aliases = cs.aliases();
@@ -254,9 +478,7 @@ public class Encoding {
             if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
             }
-            if (!((c >= '\t' && c <= '\r') || (c >= '\u0020' && c <= '\u002F')
-                    || (c >= '\u003A' && c <= '\u0040')
-                    || (c >= '\u005B' && c <= '\u0060') || (c >= '\u007B' && c <= '\u007E'))) {
+            if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')) {
                 buf[j] = c;
                 j++;
             }
@@ -264,6 +486,20 @@ public class Encoding {
         return new String(buf, 0, j);
     }
 
+    public static String stripDashAndUnderscore(String str) {
+        if (str == null) {
+            return null;
+        }
+        char[] buf = new char[str.length()];
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c == '-' || c == '_') {
+                buf[i] = c;
+            }
+        }
+        return new String(buf);
+    }
+
     public static String toAsciiLowerCase(String str) {
         if (str == null) {
             return null;
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java 1.4+r20250916-1/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/io/HtmlInputStreamReader.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2013-2020 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -41,6 +42,7 @@ import nu.validator.htmlparser.impl.Toke
 
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
@@ -57,9 +59,9 @@ import org.xml.sax.SAXParseException;
  * @author hsivonen
  */
 public final class HtmlInputStreamReader extends Reader implements
-        ByteReadable, Locator {
+        ByteReadable, Locator, Locator2 {
 
-    private static final int SNIFFING_LIMIT = 1024;
+    private int sniffingLimit = 1024;
 
     private final InputStream inputStream;
 
@@ -85,11 +87,9 @@ public final class HtmlInputStreamReader
 
     private boolean charsetBoundaryPassed = false;
 
-    private final byte[] byteArray = new byte[4096]; // Length must be >=
+    private byte[] byteArray = new byte[4096]; // Length must be >= sniffingLimit
 
-    // SNIFFING_LIMIT
-
-    private final ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
+    private ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
 
     private boolean needToNotifyTokenizer = false;
 
@@ -110,22 +110,39 @@ public final class HtmlInputStreamReader
     /**
      * @param inputStream
      * @param errorHandler
-     * @param locator
+     * @param tokenizer
+     * @param driver
+     * @param heuristics
+     * @param sniffingLimit
      * @throws IOException
      * @throws SAXException
      */
     public HtmlInputStreamReader(InputStream inputStream,
             ErrorHandler errorHandler, Tokenizer tokenizer, Driver driver,
-            Heuristics heuristics) throws SAXException, IOException {
+            Heuristics heuristics, int sniffingLimit)
+            throws SAXException, IOException {
         this.inputStream = inputStream;
         this.errorHandler = errorHandler;
         this.tokenizer = tokenizer;
         this.driver = driver;
         this.sniffing = true;
+        if (sniffingLimit != -1) {
+            this.sniffingLimit = sniffingLimit;
+            this.byteArray = new byte[sniffingLimit];
+            this.byteBuffer = ByteBuffer.wrap(byteArray);
+        }
         Encoding encoding = (new BomSniffer(this)).sniff();
         if (encoding == null) {
             position = 0;
             encoding = (new MetaSniffer(errorHandler, this)).sniff(this);
+            boolean declared = true;
+            if (encoding == null) {
+                declared = false;
+            } else if (encoding != Encoding.UTF8) {
+                err("Legacy encoding \u201C"
+                        + encoding.getCanonName()
+                        + "\u201D used. Documents must use UTF-8.");
+            }
             if (encoding == null
                     && (heuristics == Heuristics.CHARDET || heuristics == Heuristics.ALL)) {
                 encoding = (new ChardetSniffer(byteArray, limit)).sniff();
@@ -139,6 +156,9 @@ public final class HtmlInputStreamReader
             if (encoding == null) {
                 encoding = Encoding.WINDOWS1252;
             }
+            if (!declared) {
+                err("The character encoding was not declared. Proceeding using \u201C" + encoding.getCanonName() + "\u201D.");
+            }
             if (driver != null) {
                 driver.setEncoding(encoding, Confidence.TENTATIVE);
             }
@@ -148,6 +168,9 @@ public final class HtmlInputStreamReader
                     driver.setEncoding(Encoding.UTF8, Confidence.CERTAIN);
                 }
             } else {
+                err("Legacy encoding \u201C"
+                        + encoding.getCanonName()
+                        + "\u201D used. Documents must use UTF-8.");
                 if (driver != null) {
                     driver.setEncoding(Encoding.UTF16, Confidence.CERTAIN);
                 }
@@ -162,6 +185,12 @@ public final class HtmlInputStreamReader
         initDecoder();
     }
 
+    public HtmlInputStreamReader(InputStream inputStream,
+            ErrorHandler errorHandler, Tokenizer tokenizer, Driver driver,
+            Heuristics heuristics) throws SAXException, IOException {
+        this(inputStream, errorHandler, tokenizer, driver, heuristics, -1);
+    }
+
     /**
      * 
      */
@@ -221,7 +250,7 @@ public final class HtmlInputStreamReader
                 if (charsetBoundaryPassed) {
                     readLen = byteArray.length - oldLimit;
                 } else {
-                    readLen = SNIFFING_LIMIT - oldLimit;
+                    readLen = sniffingLimit - oldLimit;
                 }
                 int num = inputStream.read(byteArray, oldLimit, readLen);
                 if (num == -1) {
@@ -245,7 +274,7 @@ public final class HtmlInputStreamReader
                 } else if (cr == CoderResult.UNDERFLOW) {
                     int remaining = byteBuffer.remaining();
                     if (!charsetBoundaryPassed) {
-                        if (bytesRead + remaining >= SNIFFING_LIMIT) {
+                        if (bytesRead + remaining >= sniffingLimit) {
                             needToNotifyTokenizer = true;
                             charsetBoundaryPassed = true;
                         }
@@ -282,9 +311,12 @@ public final class HtmlInputStreamReader
                     } else {
                         // The usual stuff. Want more bytes next time.
                         shouldReadBytes = true;
-                        // return -1 if zero
                         int cPos = charBuffer.position();
-                        return cPos == 0 ? -1 : cPos;
+                        if (cPos == 0) {
+                            // No output. Read more bytes right away
+                            break;
+                        }
+                        return cPos;
                     }
                 } else {
                     // The result is in error. No need to test.
@@ -370,12 +402,12 @@ public final class HtmlInputStreamReader
             throw new IllegalStateException(
                     "readByte() called when not in the sniffing state.");
         }
-        if (position == SNIFFING_LIMIT) {
+        if (position == sniffingLimit) {
             return -1;
         } else if (position < limit) {
             return byteArray[position++] & 0xFF;
         } else {
-            int num = inputStream.read(byteArray, limit, SNIFFING_LIMIT - limit);
+            int num = inputStream.read(byteArray, limit, sniffingLimit - limit);
             if (num == -1) {
                 return -1;
             } else {
@@ -434,6 +466,20 @@ public final class HtmlInputStreamReader
         return null;
     }
 
+    public String getXMLVersion() {
+        if (tokenizer != null) {
+            return tokenizer.getXMLVersion();
+        }
+        return null;
+    }
+
+    public String getEncoding() {
+        if (tokenizer != null) {
+            return tokenizer.getEncoding();
+        }
+        return null;
+    }
+
     /**
      * @param string
      * @throws SAXException
@@ -447,6 +493,18 @@ public final class HtmlInputStreamReader
             }
         } catch (SAXException e) {
             throw (IOException) new IOException(e.getMessage()).initCause(e);
+        }
+    }
+
+    private void warn(String message) throws IOException {
+        // TODO remove wrapping when changing read() to take a CharBuffer
+        try {
+            if (errorHandler != null) {
+                SAXParseException spe = new SAXParseException(message, this);
+                errorHandler.warning(spe);
+            }
+        } catch (SAXException e) {
+            throw (IOException) new IOException(e.getMessage()).initCause(e);
         }
     }
 
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/MetaSniffer.java 1.4+r20250916-1/src/nu/validator/htmlparser/io/MetaSniffer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/io/MetaSniffer.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/io/MetaSniffer.java	2025-09-16 08:29:41.000000000 +0000
@@ -30,10 +30,11 @@ import nu.validator.htmlparser.impl.Meta
 
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-public class MetaSniffer extends MetaScanner implements Locator {
+public class MetaSniffer extends MetaScanner implements Locator, Locator2 {
     
     private Encoding characterEncoding = null;
 
@@ -142,6 +143,20 @@ public class MetaSniffer extends MetaSca
         }
         return null;
     }
+
+    public String getXMLVersion() {
+        if (locator != null) {
+            return ((Locator2)locator).getXMLVersion();
+        }
+        return null;
+    }
+
+    public String getEncoding() {
+        if (locator != null) {
+            return ((Locator2)locator).getEncoding();
+        }
+        return null;
+    }
     
     protected boolean tryCharset(String encoding) throws SAXException {
         encoding = Encoding.toAsciiLowerCase(encoding);
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/HtmlParser.java 1.4+r20250916-1/src/nu/validator/htmlparser/sax/HtmlParser.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/HtmlParser.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/sax/HtmlParser.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2007-2010 Mozilla Foundation
+ * Copyright (c) 2007-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -31,7 +31,6 @@ import java.util.List;
 import java.util.HashMap;
 
 import nu.validator.htmlparser.common.CharacterHandler;
-import nu.validator.htmlparser.common.DoctypeExpectation;
 import nu.validator.htmlparser.common.DocumentModeHandler;
 import nu.validator.htmlparser.common.Heuristics;
 import nu.validator.htmlparser.common.TokenHandler;
@@ -108,8 +107,6 @@ public class HtmlParser implements XMLRe
 
     private DocumentModeHandler documentModeHandler = null;
 
-    private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML;
-
     private boolean checkingNormalization = false;
 
     private boolean scriptingEnabled = false;
@@ -126,8 +123,6 @@ public class HtmlParser implements XMLRe
 
     private XmlViolationPolicy streamabilityViolationPolicy = XmlViolationPolicy.ALLOW;
     
-    private boolean html4ModeCompatibleWithXhtml1Schemata = false;
-
     private boolean mappingLangToXmlLang = false;
 
     private XmlViolationPolicy xmlnsPolicy = XmlViolationPolicy.FATAL;
@@ -193,14 +188,12 @@ public class HtmlParser implements XMLRe
             this.driver.setCommentPolicy(commentPolicy);
             this.driver.setContentNonXmlCharPolicy(contentNonXmlCharPolicy);
             this.driver.setContentSpacePolicy(contentSpacePolicy);
-            this.driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
             this.driver.setMappingLangToXmlLang(mappingLangToXmlLang);
             this.driver.setXmlnsPolicy(xmlnsPolicy);
             this.driver.setHeuristics(heuristics);
             for (CharacterHandler characterHandler : characterHandlers) {
                 this.driver.addCharacterHandler(characterHandler);
             }
-            this.treeBuilder.setDoctypeExpectation(doctypeExpectation);
             this.treeBuilder.setDocumentModeHandler(documentModeHandler);
             this.treeBuilder.setIgnoringComments(lexicalHandler == null);
             this.treeBuilder.setScriptingEnabled(scriptingEnabled);
@@ -279,8 +272,6 @@ public class HtmlParser implements XMLRe
      * <dd><code>false</code></dd>
      * <dt><code>http://xml.org/sax/features/xml-1.1</code></dt>
      * <dd><code>false</code></dd>
-     * <dt><code>http://validator.nu/features/html4-mode-compatible-with-xhtml1-schemata</code></dt>
-     * <dd><code>isHtml4ModeCompatibleWithXhtml1Schemata</code></dd>
      * <dt><code>http://validator.nu/features/mapping-lang-to-xml-lang</code></dt>
      * <dd><code>isMappingLangToXmlLang</code></dd>
      * <dt><code>http://validator.nu/features/scripting-enabled</code></dt>
@@ -325,8 +316,6 @@ public class HtmlParser implements XMLRe
             return false;
         } else if ("http://xml.org/sax/features/xml-1.1".equals(name)) {
             return false;
-        } else if ("http://validator.nu/features/html4-mode-compatible-with-xhtml1-schemata".equals(name)) {
-            return isHtml4ModeCompatibleWithXhtml1Schemata();
         } else if ("http://validator.nu/features/mapping-lang-to-xml-lang".equals(name)) {
             return isMappingLangToXmlLang();
         } else if ("http://validator.nu/features/scripting-enabled".equals(name)) {
@@ -362,8 +351,6 @@ public class HtmlParser implements XMLRe
      * <dd><code>getStreamabilityViolationPolicy</code></dd>
      * <dt><code>http://validator.nu/properties/document-mode-handler</code></dt>
      * <dd><code>getDocumentModeHandler</code></dd>
-     * <dt><code>http://validator.nu/properties/doctype-expectation</code></dt>
-     * <dd><code>getDoctypeExpectation</code></dd>
      * <dt><code>http://xml.org/sax/features/unicode-normalization-checking</code></dt>
      * </dl>
      * 
@@ -401,8 +388,6 @@ public class HtmlParser implements XMLRe
             return getStreamabilityViolationPolicy();
         } else if ("http://validator.nu/properties/document-mode-handler".equals(name)) {
             return getDocumentModeHandler();
-        } else if ("http://validator.nu/properties/doctype-expectation".equals(name)) {
-            return getDoctypeExpectation();
         } else if ("http://validator.nu/properties/xml-policy".equals(name)) {
             throw new SAXNotSupportedException(
                     "Cannot get a convenience setter.");
@@ -417,10 +402,17 @@ public class HtmlParser implements XMLRe
      * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
      */
     public void parse(InputSource input) throws IOException, SAXException {
+        parse(input, -1);
+    }
+
+    /**
+     * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
+     */
+    public void parse(InputSource input, int bufferSize) throws IOException, SAXException {
         lazyInit();
         try {
             treeBuilder.setFragmentContext(null);
-            tokenize(input);
+            tokenize(input, bufferSize);
         } finally {
             if (saxTreeBuilder != null) {
                 Document document = saxTreeBuilder.getDocument();
@@ -432,19 +424,78 @@ public class HtmlParser implements XMLRe
     }
 
     /**
-     * Parses a fragment.
+     * Parses a fragment with HTML context.
      * 
      * @param input the input to parse
-     * @param context the name of the context element
+     * @param context the name of the context element (HTML namespace assumed)
      * @throws IOException
      * @throws SAXException
      */
     public void parseFragment(InputSource input, String context)
             throws IOException, SAXException {
+            parseFragment(input, context, -1);
+    }
+    /**
+     * Parses a fragment with HTML context.
+     *
+     * @param input the input to parse
+     * @param context the name of the context element (HTML namespace assumed)
+     * @param bufferSize the size of the buffer to feed to the tokenizer
+     * @throws IOException
+     * @throws SAXException
+     */
+    public void parseFragment(InputSource input, String context, int bufferSize)
+            throws IOException, SAXException {
         lazyInit();
         try {
             treeBuilder.setFragmentContext(context.intern());
-            tokenize(input);
+            if (bufferSize == -1) {
+                tokenize(input);
+            } else {
+                tokenize(input, bufferSize);
+            }
+        } finally {
+            if (saxTreeBuilder != null) {
+                DocumentFragment fragment = saxTreeBuilder.getDocumentFragment();
+                new TreeParser(contentHandler, lexicalHandler).parse(fragment);
+            }
+        }
+    }
+    
+    /**
+     * Parses a fragment.
+     * 
+     * @param input the input to parse
+     * @param contextLocal the local name of the context element
+     * @param contextNamespace the namespace of the context element
+     * @throws IOException
+     * @throws SAXException
+     */
+    public void parseFragment(InputSource input, String contextLocal, String contextNamespace)
+            throws IOException, SAXException {
+            parseFragment(input, contextLocal, contextNamespace, -1);
+    }
+    /**
+     * Parses a fragment.
+     *
+     * @param input the input to parse
+     * @param contextLocal the local name of the context element
+     * @param contextNamespace the namespace of the context element
+     * @param bufferSize the size of the buffer to feed to the tokenizer
+     * @throws IOException
+     * @throws SAXException
+     */
+    public void parseFragment(InputSource input, String contextLocal,
+            String contextNamespace, int bufferSize)
+            throws IOException, SAXException {
+        lazyInit();
+        try {
+            treeBuilder.setFragmentContext(contextLocal.intern(), contextNamespace.intern(), null, false);
+            if (bufferSize == -1) {
+                tokenize(input);
+            } else {
+                tokenize(input, bufferSize);
+            }
         } finally {
             if (saxTreeBuilder != null) {
                 DocumentFragment fragment = saxTreeBuilder.getDocumentFragment();
@@ -460,6 +511,10 @@ public class HtmlParser implements XMLRe
      * @throws MalformedURLException
      */
     private void tokenize(InputSource is) throws SAXException, IOException, MalformedURLException {
+        tokenize(is, -1);
+    }
+    private void tokenize(InputSource is, int bufferSize) throws SAXException,
+            IOException, MalformedURLException {
         if (is == null) {
             throw new IllegalArgumentException("Null input.");            
         }
@@ -477,7 +532,11 @@ public class HtmlParser implements XMLRe
                 is.setByteStream(new URL(systemId).openStream());
             }
         }
-        driver.tokenize(is);
+        if (bufferSize == -1) {
+            driver.tokenize(is);
+        } else {
+            driver.tokenize(is, bufferSize);
+        }
     }
 
     /**
@@ -561,8 +620,6 @@ public class HtmlParser implements XMLRe
      * <dl>
      * <dt><code>http://xml.org/sax/features/unicode-normalization-checking</code></dt>
      * <dd><code>setCheckingNormalization</code></dd>
-     * <dt><code>http://validator.nu/features/html4-mode-compatible-with-xhtml1-schemata</code></dt>
-     * <dd><code>setHtml4ModeCompatibleWithXhtml1Schemata</code></dd>
      * <dt><code>http://validator.nu/features/mapping-lang-to-xml-lang</code></dt>
      * <dd><code>setMappingLangToXmlLang</code></dd>
      * <dt><code>http://validator.nu/features/scripting-enabled</code></dt>
@@ -631,8 +688,6 @@ public class HtmlParser implements XMLRe
             if (value) {
                 throw new SAXNotSupportedException("Cannot set " + name + ".");
             }
-        } else if ("http://validator.nu/features/html4-mode-compatible-with-xhtml1-schemata".equals(name)) {
-            setHtml4ModeCompatibleWithXhtml1Schemata(value);
         } else if ("http://validator.nu/features/mapping-lang-to-xml-lang".equals(name)) {
             setMappingLangToXmlLang(value);
         } else if ("http://validator.nu/features/scripting-enabled".equals(name)) {
@@ -663,8 +718,6 @@ public class HtmlParser implements XMLRe
      * <dd><code>setStreamabilityViolationPolicy</code></dd>
      * <dt><code>http://validator.nu/properties/document-mode-handler</code></dt>
      * <dd><code>setDocumentModeHandler</code></dd>
-     * <dt><code>http://validator.nu/properties/doctype-expectation</code></dt>
-     * <dd><code>setDoctypeExpectation</code></dd>
      * <dt><code>http://validator.nu/properties/xml-policy</code></dt>
      * <dd><code>setXmlPolicy</code></dd>
      * </dl>
@@ -700,8 +753,6 @@ public class HtmlParser implements XMLRe
             setStreamabilityViolationPolicy((XmlViolationPolicy) value);
         } else if ("http://validator.nu/properties/document-mode-handler".equals(name)) {
             setDocumentModeHandler((DocumentModeHandler) value);
-        } else if ("http://validator.nu/properties/doctype-expectation".equals(name)) {
-            setDoctypeExpectation((DoctypeExpectation) value);
         } else if ("http://validator.nu/properties/xml-policy".equals(name)) {
             setXmlPolicy((XmlViolationPolicy) value);
         } else if ("http://validator.nu/properties/heuristics".equals(name)) {
@@ -790,29 +841,6 @@ public class HtmlParser implements XMLRe
     }
 
     /**
-     * Returns the doctype expectation.
-     * 
-     * @return the doctypeExpectation
-     */
-    public DoctypeExpectation getDoctypeExpectation() {
-        return doctypeExpectation;
-    }
-
-    /**
-     * Sets the doctype expectation.
-     * 
-     * @param doctypeExpectation
-     *            the doctypeExpectation to set
-     * @see nu.validator.htmlparser.impl.TreeBuilder#setDoctypeExpectation(nu.validator.htmlparser.common.DoctypeExpectation)
-     */
-    public void setDoctypeExpectation(DoctypeExpectation doctypeExpectation) {
-        this.doctypeExpectation = doctypeExpectation;
-        if (treeBuilder != null) {
-            treeBuilder.setDoctypeExpectation(doctypeExpectation);
-        }
-    }
-
-    /**
      * Returns the document mode handler.
      * 
      * @return the documentModeHandler
@@ -854,19 +882,6 @@ public class HtmlParser implements XMLRe
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * @param html4ModeCompatibleWithXhtml1Schemata
-     */
-    public void setHtml4ModeCompatibleWithXhtml1Schemata(
-            boolean html4ModeCompatibleWithXhtml1Schemata) {
-        this.html4ModeCompatibleWithXhtml1Schemata = html4ModeCompatibleWithXhtml1Schemata;
-        if (driver != null) {
-            driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
-        }
-    }
-
-    /**
      * Returns the <code>Locator</code> during parse.
      * @return the <code>Locator</code>
      */
@@ -875,16 +890,6 @@ public class HtmlParser implements XMLRe
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * 
-     * @return the html4ModeCompatibleWithXhtml1Schemata
-     */
-    public boolean isHtml4ModeCompatibleWithXhtml1Schemata() {
-        return html4ModeCompatibleWithXhtml1Schemata;
-    }
-
-    /**
      * Whether <code>lang</code> is mapped to <code>xml:lang</code>.
      * @param mappingLangToXmlLang
      * @see nu.validator.htmlparser.impl.Tokenizer#setMappingLangToXmlLang(boolean)
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/SAXStreamer.java 1.4+r20250916-1/src/nu/validator/htmlparser/sax/SAXStreamer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/SAXStreamer.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/sax/SAXStreamer.java	2025-09-16 08:29:41.000000000 +0000
@@ -2,52 +2,50 @@
  * Copyright (c) 2007 Henri Sivonen
  * Copyright (c) 2008-2009 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.sax;
 
-import nu.validator.htmlparser.impl.HtmlAttributes;
-import nu.validator.htmlparser.impl.TreeBuilder;
-
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.ext.LexicalHandler;
 
-class SAXStreamer extends TreeBuilder<Attributes>{
+import nu.validator.htmlparser.impl.HtmlAttributes;
+import nu.validator.htmlparser.impl.TreeBuilder;
 
-    private static final char[] ISINDEX_PROMPT = "This is a searchable index. Enter search keywords: ".toCharArray();
+class SAXStreamer extends TreeBuilder<Attributes>{
 
     private ContentHandler contentHandler = null;
     private LexicalHandler lexicalHandler = null;
-    
+
     SAXStreamer() {
         super();
     }
-    
+
     @Override
     protected void addAttributesToElement(Attributes element, HtmlAttributes attributes) throws SAXException {
         Attributes existingAttrs = element;
         for (int i = 0; i < attributes.getLength(); i++) {
-            String qName = attributes.getQName(i);
+            String qName = attributes.getQNameNoBoundsCheck(i);
             if (existingAttrs.getIndex(qName) < 0) {
                 fatal();
             }
@@ -59,14 +57,6 @@ class SAXStreamer extends TreeBuilder<At
         contentHandler.characters(buf, start, length);
     }
 
-    /**
-     * @see nu.validator.htmlparser.impl.TreeBuilder#appendIsindexPrompt(java.lang.Object)
-     */
-    @Override protected void appendIsindexPrompt(Attributes parent)
-            throws SAXException {
-        contentHandler.characters(ISINDEX_PROMPT, 0, ISINDEX_PROMPT.length);
-    }
-
     @Override
     protected void appendChildrenToNewParent(Attributes oldParent, Attributes newParent) throws SAXException {
         fatal();
@@ -88,7 +78,7 @@ class SAXStreamer extends TreeBuilder<At
     }
 
     @Override
-    protected Attributes createElement(String ns, String name, HtmlAttributes attributes) throws SAXException {
+    protected Attributes createElement(String ns, String name, HtmlAttributes attributes, Attributes intendedParent) throws SAXException {
         return attributes;
     }
 
@@ -110,7 +100,7 @@ class SAXStreamer extends TreeBuilder<At
     protected boolean hasChildren(Attributes element) throws SAXException {
         return false;
     }
-    
+
     public void setContentHandler(ContentHandler handler) {
         contentHandler = handler;
     }
@@ -175,6 +165,13 @@ class SAXStreamer extends TreeBuilder<At
         throw spe;
     }
 
+    @Override
+    protected Attributes createAndInsertFosterParentedElement(String ns, String name,
+            HtmlAttributes attributes, Attributes table, Attributes stackParent) throws SAXException {
+        fatal();
+        throw new RuntimeException("Unreachable");
+    }
+
     @Override protected void insertFosterParentedCharacters(char[] buf,
             int start, int length, Attributes table, Attributes stackParent)
             throws SAXException {
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/SAXTreeBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/sax/SAXTreeBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/SAXTreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/sax/SAXTreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -2,27 +2,29 @@
  * Copyright (c) 2007 Henri Sivonen
  * Copyright (c) 2008-2010 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.sax;
 
+import org.xml.sax.SAXException;
+
 import nu.validator.htmlparser.impl.HtmlAttributes;
 import nu.validator.htmlparser.impl.TreeBuilder;
 import nu.validator.saxtree.Characters;
@@ -34,22 +36,18 @@ import nu.validator.saxtree.Element;
 import nu.validator.saxtree.Node;
 import nu.validator.saxtree.ParentNode;
 
-import org.xml.sax.SAXException;
-
 class SAXTreeBuilder extends TreeBuilder<Element> {
 
-    private static final char[] ISINDEX_PROMPT = "This is a searchable index. Enter search keywords: ".toCharArray();
-
     private Document document;
 
     private Node cachedTable = null;
-    
+
     private Node cachedTablePreviousSibling = null;
-    
+
     SAXTreeBuilder() {
         super();
     }
-    
+
     @Override
     protected void appendComment(Element parent, char[] buf, int start, int length) {
         parent.appendChild(new Comment(tokenizer, buf, start, length));
@@ -65,14 +63,6 @@ class SAXTreeBuilder extends TreeBuilder
         parent.appendChild(new Characters(tokenizer, buf, start, length));
     }
 
-    /**
-     * @see nu.validator.htmlparser.impl.TreeBuilder#appendIsindexPrompt(java.lang.Object)
-     */
-    @Override protected void appendIsindexPrompt(Element parent)
-            throws SAXException {
-        parent.appendChild(new Characters(tokenizer, ISINDEX_PROMPT, 0, ISINDEX_PROMPT.length));
-    }
-
     @Override
     protected boolean hasChildren(Element element) {
         return element.getFirstChild() != null;
@@ -105,10 +95,10 @@ class SAXTreeBuilder extends TreeBuilder
          dtd.setEndLocator(tokenizer);
          document.appendChild(dtd);
     }
-    
+
     /**
      * Returns the document.
-     * 
+     *
      * @return the document
      */
     Document getDocument() {
@@ -116,7 +106,7 @@ class SAXTreeBuilder extends TreeBuilder
         document = null;
         return rv;
     }
-    
+
     DocumentFragment getDocumentFragment() {
         DocumentFragment rv = new DocumentFragment();
         rv.appendChildren(document.getFirstChild());
@@ -125,7 +115,7 @@ class SAXTreeBuilder extends TreeBuilder
     }
 
     /**
-     * @throws SAXException 
+     * @throws SAXException
      * @see nu.validator.htmlparser.impl.TreeBuilder#end()
      */
     @Override
@@ -151,10 +141,26 @@ class SAXTreeBuilder extends TreeBuilder
     }
 
     @Override
-    protected Element createElement(String ns, String name, HtmlAttributes attributes) throws SAXException {
+    protected Element createElement(String ns, String name, HtmlAttributes attributes,
+            Element intendedParent) throws SAXException {
         return new Element(tokenizer, ns, name, name, attributes, true, null);
     }
 
+    @Override
+    protected Element createAndInsertFosterParentedElement(String ns, String name,
+            HtmlAttributes attributes, Element table, Element stackParent) throws SAXException {
+        ParentNode parent = table.getParentNode();
+        Element child = createElement(ns, name, attributes, parent != null ? (Element) parent : stackParent);
+        if (parent != null) { // always an element if not null
+            parent.insertBetween(child, previousSibling(table), table);
+            cachedTablePreviousSibling = child;
+        } else {
+            stackParent.appendChild(child);
+        }
+
+        return child;
+    }
+
     @Override protected void insertFosterParentedCharacters(char[] buf,
             int start, int length, Element table, Element stackParent) throws SAXException {
         Node child = new Characters(tokenizer, buf, start, length);
@@ -164,7 +170,7 @@ class SAXTreeBuilder extends TreeBuilder
             cachedTablePreviousSibling = child;
         } else {
             stackParent.appendChild(child);
-        }        
+        }
     }
 
     @Override protected void insertFosterParentedChild(Element child,
@@ -180,7 +186,7 @@ class SAXTreeBuilder extends TreeBuilder
 
     private Node previousSibling(Node table) {
         if (table == cachedTable) {
-            return cachedTablePreviousSibling;   
+            return cachedTablePreviousSibling;
         } else {
             cachedTable = table;
             return (cachedTablePreviousSibling = table.getPreviousSibling());
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/XmlSerializer.java 1.4+r20250916-1/src/nu/validator/htmlparser/sax/XmlSerializer.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/sax/XmlSerializer.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/sax/XmlSerializer.java	2025-09-16 08:29:41.000000000 +0000
@@ -155,7 +155,7 @@ public class XmlSerializer implements Co
                 "xlink");
         WELL_KNOWN_ATTRIBUTE_PREFIXES.put(
                 "http://www.w3.org/2001/XMLSchema-instance", "xsi");
-        WELL_KNOWN_ATTRIBUTE_PREFIXES.put("http://www.w3org/1999/xlink",
+        WELL_KNOWN_ATTRIBUTE_PREFIXES.put("http://www.w3.org/1999/xlink",
                 "xlink");
     }
 
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/xom/HtmlBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/xom/HtmlBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/xom/HtmlBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/xom/HtmlBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2007-2008 Mozilla Foundation
+ * Copyright (c) 2007-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -35,7 +35,6 @@ import java.util.LinkedList;
 import java.util.List;
 
 import nu.validator.htmlparser.common.CharacterHandler;
-import nu.validator.htmlparser.common.DoctypeExpectation;
 import nu.validator.htmlparser.common.DocumentModeHandler;
 import nu.validator.htmlparser.common.Heuristics;
 import nu.validator.htmlparser.common.TokenHandler;
@@ -96,8 +95,6 @@ public class HtmlBuilder extends Builder
 
     private DocumentModeHandler documentModeHandler = null;
 
-    private DoctypeExpectation doctypeExpectation = DoctypeExpectation.HTML;
-
     private boolean checkingNormalization = false;
 
     private boolean scriptingEnabled = false;
@@ -114,8 +111,6 @@ public class HtmlBuilder extends Builder
 
     private XmlViolationPolicy streamabilityViolationPolicy = XmlViolationPolicy.ALLOW;
     
-    private boolean html4ModeCompatibleWithXhtml1Schemata = false;
-
     private boolean mappingLangToXmlLang = false;
 
     private XmlViolationPolicy xmlnsPolicy = XmlViolationPolicy.FATAL;
@@ -161,7 +156,6 @@ public class HtmlBuilder extends Builder
         this.simpleNodeFactory = nodeFactory;
         this.treeBuilder = new XOMTreeBuilder(nodeFactory);
         this.driver = null;
-        this.driver.setXmlnsPolicy(XmlViolationPolicy.ALTER_INFOSET);
         setXmlPolicy(xmlPolicy);
     }
 
@@ -188,14 +182,12 @@ public class HtmlBuilder extends Builder
             this.driver.setCommentPolicy(commentPolicy);
             this.driver.setContentNonXmlCharPolicy(contentNonXmlCharPolicy);
             this.driver.setContentSpacePolicy(contentSpacePolicy);
-            this.driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
             this.driver.setMappingLangToXmlLang(mappingLangToXmlLang);
             this.driver.setXmlnsPolicy(xmlnsPolicy);
             this.driver.setHeuristics(heuristics);
             for (CharacterHandler characterHandler : characterHandlers) {
                 this.driver.addCharacterHandler(characterHandler);
             }
-            this.treeBuilder.setDoctypeExpectation(doctypeExpectation);
             this.treeBuilder.setDocumentModeHandler(documentModeHandler);
             this.treeBuilder.setScriptingEnabled(scriptingEnabled);
             this.treeBuilder.setReportingDoctype(reportingDoctype);
@@ -251,9 +243,10 @@ public class HtmlBuilder extends Builder
     }
 
     /**
-     * Parse a fragment from SAX <code>InputSource</code>.
+     * Parse a fragment from SAX <code>InputSource</code> assuming an HTML
+     * context.
      * @param is the <code>InputSource</code>
-     * @param context the name of the context element
+     * @param context the name of the context element (HTML namespace assumed)
      * @return the fragment
      * @throws ParsingException in case of an XML violation
      * @throws IOException if IO goes wrang
@@ -266,6 +259,22 @@ public class HtmlBuilder extends Builder
         return treeBuilder.getDocumentFragment();
     }
 
+    /**
+     * Parse a fragment from SAX <code>InputSource</code>.
+     * @param is the <code>InputSource</code>
+     * @param contextLocal the local name of the context element
+     * @parem contextNamespace the namespace of the context element
+     * @return the fragment
+     * @throws ParsingException in case of an XML violation
+     * @throws IOException if IO goes wrang
+     */
+    public Nodes buildFragment(InputSource is, String contextLocal, String contextNamespace)
+            throws IOException, ParsingException {
+        lazyInit();
+        treeBuilder.setFragmentContext(contextLocal.intern(), contextNamespace.intern(), null, false);
+        tokenize(is);
+        return treeBuilder.getDocumentFragment();
+    }
     
     /**
      * Parse from <code>File</code>.
@@ -479,29 +488,6 @@ public class HtmlBuilder extends Builder
     }
 
     /**
-     * Returns the doctype expectation.
-     * 
-     * @return the doctypeExpectation
-     */
-    public DoctypeExpectation getDoctypeExpectation() {
-        return doctypeExpectation;
-    }
-
-    /**
-     * Sets the doctype expectation.
-     * 
-     * @param doctypeExpectation
-     *            the doctypeExpectation to set
-     * @see nu.validator.htmlparser.impl.TreeBuilder#setDoctypeExpectation(nu.validator.htmlparser.common.DoctypeExpectation)
-     */
-    public void setDoctypeExpectation(DoctypeExpectation doctypeExpectation) {
-        this.doctypeExpectation = doctypeExpectation;
-        if (treeBuilder != null) {
-            treeBuilder.setDoctypeExpectation(doctypeExpectation);
-        }
-    }
-
-    /**
      * Returns the document mode handler.
      * 
      * @return the documentModeHandler
@@ -543,19 +529,6 @@ public class HtmlBuilder extends Builder
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * @param html4ModeCompatibleWithXhtml1Schemata
-     */
-    public void setHtml4ModeCompatibleWithXhtml1Schemata(
-            boolean html4ModeCompatibleWithXhtml1Schemata) {
-        this.html4ModeCompatibleWithXhtml1Schemata = html4ModeCompatibleWithXhtml1Schemata;
-        if (driver != null) {
-            driver.setHtml4ModeCompatibleWithXhtml1Schemata(html4ModeCompatibleWithXhtml1Schemata);
-        }
-    }
-
-    /**
      * Returns the <code>Locator</code> during parse.
      * @return the <code>Locator</code>
      */
@@ -564,16 +537,6 @@ public class HtmlBuilder extends Builder
     }
 
     /**
-     * Whether the HTML 4 mode reports boolean attributes in a way that repeats
-     * the name in the value.
-     * 
-     * @return the html4ModeCompatibleWithXhtml1Schemata
-     */
-    public boolean isHtml4ModeCompatibleWithXhtml1Schemata() {
-        return html4ModeCompatibleWithXhtml1Schemata;
-    }
-
-    /**
      * Whether <code>lang</code> is mapped to <code>xml:lang</code>.
      * @param mappingLangToXmlLang
      * @see nu.validator.htmlparser.impl.Tokenizer#setMappingLangToXmlLang(boolean)
diff -pruN 1.4+r1.3.1-3/src/nu/validator/htmlparser/xom/XOMTreeBuilder.java 1.4+r20250916-1/src/nu/validator/htmlparser/xom/XOMTreeBuilder.java
--- 1.4+r1.3.1-3/src/nu/validator/htmlparser/xom/XOMTreeBuilder.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/htmlparser/xom/XOMTreeBuilder.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
- * Copyright (c) 2008-2010 Mozilla Foundation
+ * Copyright (c) 2008-2017 Mozilla Foundation
  *
  * Permission is hereby granted, free of charge, to any person obtaining a 
  * copy of this software and associated documentation files (the "Software"), 
@@ -57,12 +57,14 @@ class XOMTreeBuilder extends CoalescingT
             throws SAXException {
         try {
             for (int i = 0; i < attributes.getLength(); i++) {
-                String localName = attributes.getLocalName(i);
-                String uri = attributes.getURI(i);
+                String localName = attributes.getLocalNameNoBoundsCheck(i);
+                String uri = attributes.getURINoBoundsCheck(i);
                 if (element.getAttribute(localName, uri) == null) {
-                    element.addAttribute(nodeFactory.makeAttribute(localName,
-                            uri, attributes.getValue(i),
-                            attributes.getType(i) == "ID" ? Attribute.Type.ID
+                    element.addAttribute(nodeFactory.makeAttribute(
+                            localName,
+                            uri,
+                            attributes.getValueNoBoundsCheck(i),
+                            attributes.getTypeNoBoundsCheck(i) == "ID" ? Attribute.Type.ID
                                     : Attribute.Type.CDATA));
                 }
             }
@@ -126,16 +128,16 @@ class XOMTreeBuilder extends CoalescingT
     }
 
     @Override
-    protected Element createElement(String ns, String name, HtmlAttributes attributes)
-            throws SAXException {
+ protected Element createElement(String ns, String name,
+            HtmlAttributes attributes, Element intendedParent) throws SAXException {
         try {
-            Element rv = nodeFactory.makeElement(name,
-                    ns);
+            Element rv = nodeFactory.makeElement(name, ns);
             for (int i = 0; i < attributes.getLength(); i++) {
                 rv.addAttribute(nodeFactory.makeAttribute(
-                        attributes.getLocalName(i), attributes.getURI(i),
-                        attributes.getValue(i),
-                        attributes.getType(i) == "ID" ? Attribute.Type.ID
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getURINoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i),
+                        attributes.getTypeNoBoundsCheck(i) == "ID" ? Attribute.Type.ID
                                 : Attribute.Type.CDATA));
             }
             return rv;
@@ -146,16 +148,17 @@ class XOMTreeBuilder extends CoalescingT
     }
 
     @Override
-    protected Element createHtmlElementSetAsRoot(HtmlAttributes attributes)
-            throws SAXException {
+ protected Element createHtmlElementSetAsRoot(
+            HtmlAttributes attributes) throws SAXException {
         try {
             Element rv = nodeFactory.makeElement("html",
                     "http://www.w3.org/1999/xhtml");
             for (int i = 0; i < attributes.getLength(); i++) {
                 rv.addAttribute(nodeFactory.makeAttribute(
-                        attributes.getLocalName(i), attributes.getURI(i),
-                        attributes.getValue(i),
-                        attributes.getType(i) == "ID" ? Attribute.Type.ID
+                        attributes.getLocalNameNoBoundsCheck(i),
+                        attributes.getURINoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i),
+                        attributes.getTypeNoBoundsCheck(i) == "ID" ? Attribute.Type.ID
                                 : Attribute.Type.CDATA));
             }
             document.setRootElement(rv);
@@ -220,15 +223,16 @@ class XOMTreeBuilder extends CoalescingT
      */
     @Override
     protected Element createElement(String ns, String name,
-            HtmlAttributes attributes, Element form) throws SAXException {
+            HtmlAttributes attributes, Element form, Element intendedParent) throws SAXException {
         try {
             Element rv = nodeFactory.makeElement(name,
-                    ns, form);
+ ns, form);
             for (int i = 0; i < attributes.getLength(); i++) {
                 rv.addAttribute(nodeFactory.makeAttribute(
-                        attributes.getLocalName(i), attributes.getURI(i),
-                        attributes.getValue(i),
-                        attributes.getType(i) == "ID" ? Attribute.Type.ID
+                        attributes.getLocalName(i),
+                        attributes.getURINoBoundsCheck(i),
+                        attributes.getValueNoBoundsCheck(i),
+                        attributes.getTypeNoBoundsCheck(i) == "ID" ? Attribute.Type.ID
                                 : Attribute.Type.CDATA));
             }
             return rv;
@@ -254,7 +258,7 @@ class XOMTreeBuilder extends CoalescingT
      */
     @Override
     protected void documentMode(DocumentMode mode, String publicIdentifier,
-            String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
+            String systemIdentifier)
             throws SAXException {
         if (document instanceof Mode) {
             Mode modal = (Mode) document;
@@ -262,6 +266,25 @@ class XOMTreeBuilder extends CoalescingT
         }
     }
 
+    @Override
+    protected Element createAndInsertFosterParentedElement(String ns, String name,
+            HtmlAttributes attributes, Element table, Element stackParent) throws SAXException {
+        try {
+            Node parent = table.getParent();
+            Element child = createElement(ns, name, attributes, parent != null ? (Element) parent : stackParent);
+            if (parent != null) { // always an element if not null
+                ((ParentNode) parent).insertChild(child, indexOfTable(table, stackParent));
+                cachedTableIndex++;
+            } else {
+                stackParent.appendChild(child);
+            }
+            return child;
+        } catch (XMLException e) {
+            fatal(e);
+            throw new RuntimeException("Unreachable");
+        }
+    }
+
     @Override protected void insertFosterParentedCharacters(String text,
             Element table, Element stackParent) throws SAXException {
         try {
diff -pruN 1.4+r1.3.1-3/src/nu/validator/saxtree/DocumentFragment.java 1.4+r20250916-1/src/nu/validator/saxtree/DocumentFragment.java
--- 1.4+r1.3.1-3/src/nu/validator/saxtree/DocumentFragment.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/saxtree/DocumentFragment.java	2025-09-16 08:29:41.000000000 +0000
@@ -23,7 +23,7 @@
 
 package nu.validator.saxtree;
 
-import org.xml.sax.helpers.LocatorImpl;
+import nu.validator.htmlparser.impl.LocatorImpl;
 
 /**
  * A document fragment.
diff -pruN 1.4+r1.3.1-3/src/nu/validator/saxtree/LocatorImpl.java 1.4+r20250916-1/src/nu/validator/saxtree/LocatorImpl.java
--- 1.4+r1.3.1-3/src/nu/validator/saxtree/LocatorImpl.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/saxtree/LocatorImpl.java	2025-09-16 08:29:41.000000000 +0000
@@ -24,13 +24,14 @@
 package nu.validator.saxtree;
 
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 
 /**
  * A locator implementation.
  * @version $Id$
  * @author hsivonen
  */
-public final class LocatorImpl implements Locator {
+public final class LocatorImpl implements Locator, Locator2 {
 
     /**
      * The system id.
@@ -43,6 +44,11 @@ public final class LocatorImpl implement
     private final String publicId;
     
     /**
+     * The encoding.
+     */
+    private final String encoding;
+    
+    /**
      * The column.
      */
     private final int column;
@@ -62,11 +68,17 @@ public final class LocatorImpl implement
             this.publicId = null;
             this.column = -1;
             this.line = -1;
+            this.encoding = null;
         } else {
             this.systemId = locator.getSystemId();
             this.publicId = locator.getPublicId();
             this.column = locator.getColumnNumber();
             this.line = locator.getLineNumber();
+            if (locator instanceof Locator2) {
+                this.encoding = ((Locator2)locator).getEncoding();
+            } else {
+                this.encoding = null;
+            }
         }
     }
     
@@ -101,4 +113,21 @@ public final class LocatorImpl implement
     public String getSystemId() {
         return systemId;
     }
+
+    /**
+     * 
+     * @see org.xml.sax.ext.Locator2#getXMLVersion()
+     */
+    public String getXMLVersion() {
+        return "1.0";
+    }
+
+    /**
+     * 
+     * @see org.xml.sax.ext.Locator2#getEncoding()
+     */
+    public String getEncoding() {
+        return encoding;
+    }
+
 }
diff -pruN 1.4+r1.3.1-3/src/nu/validator/saxtree/Node.java 1.4+r20250916-1/src/nu/validator/saxtree/Node.java
--- 1.4+r1.3.1-3/src/nu/validator/saxtree/Node.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/saxtree/Node.java	2025-09-16 08:29:41.000000000 +0000
@@ -27,6 +27,7 @@ import java.util.List;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 import org.xml.sax.SAXException;
 
 /**
@@ -34,7 +35,7 @@ import org.xml.sax.SAXException;
  * @version $Id$
  * @author hsivonen
  */
-public abstract class Node implements Locator {
+public abstract class Node implements Locator, Locator2 {
 
     /**
      * The system id.
@@ -45,6 +46,11 @@ public abstract class Node implements Lo
      * The public id.
      */
     private final String publicId;
+
+    /**
+     * The encoding.
+     */
+    private final String encoding;
     
     /**
      * The column.
@@ -75,6 +81,7 @@ public abstract class Node implements Lo
         if (locator == null) {
             this.systemId = null;
             this.publicId = null;
+            this.encoding = null;
             this.column = -1;
             this.line = -1;
         } else {
@@ -82,6 +89,11 @@ public abstract class Node implements Lo
             this.publicId = locator.getPublicId();
             this.column = locator.getColumnNumber();
             this.line = locator.getLineNumber();
+            if (locator instanceof Locator2) {
+                this.encoding = ((Locator2)locator).getEncoding();
+            } else {
+                this.encoding = null;
+            }
         }
     }
     
@@ -118,6 +130,20 @@ public abstract class Node implements Lo
     }
 
     /**
+     * @see org.xml.sax.ext.Locator2#getXMLVersion()
+     */
+    public String getXMLVersion() {
+        return "1.0";
+    }
+
+    /**
+     * @see org.xml.sax.ext.Locator2#getEncoding
+     */
+    public String getEncoding() {
+        return encoding;
+    }
+
+    /**
      * Visit the node.
      * 
      * @param treeParser the visitor
diff -pruN 1.4+r1.3.1-3/src/nu/validator/saxtree/TreeParser.java 1.4+r20250916-1/src/nu/validator/saxtree/TreeParser.java
--- 1.4+r1.3.1-3/src/nu/validator/saxtree/TreeParser.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/src/nu/validator/saxtree/TreeParser.java	2025-09-16 08:29:41.000000000 +0000
@@ -26,6 +26,7 @@ package nu.validator.saxtree;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.Locator;
+import org.xml.sax.ext.Locator2;
 import org.xml.sax.SAXException;
 import org.xml.sax.ext.LexicalHandler;
 
@@ -34,7 +35,7 @@ import org.xml.sax.ext.LexicalHandler;
  * @version $Id$
  * @author hsivonen
  */
-public final class TreeParser implements Locator {
+public final class TreeParser implements Locator, Locator2 {
     
     /**
      * The content handler.
@@ -283,7 +284,6 @@ public final class TreeParser implements
         if (locatorDelegate == null) {
             return null;
         } else {
-
             return locatorDelegate.getPublicId();
         }
     }
@@ -298,4 +298,26 @@ public final class TreeParser implements
             return locatorDelegate.getSystemId();
         }
     }
+
+    /**
+     * @see org.xml.sax.Locator#getSystemId()
+     */
+    public String getXMLVersion() {
+        if (!(locatorDelegate instanceof Locator2)) {
+            return null;
+        } else {
+            return ((Locator2)locatorDelegate).getXMLVersion();
+        }
+    }
+
+    /**
+     * @see org.xml.sax.Locator#getSystemId()
+     */
+    public String getEncoding() {
+        if (!(locatorDelegate instanceof Locator2)) {
+            return null;
+        } else {
+            return ((Locator2)locatorDelegate).getEncoding();
+        }
+    }
 }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/EncodingTester.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/EncodingTester.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/EncodingTester.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/EncodingTester.java	2025-09-16 08:29:41.000000000 +0000
@@ -36,6 +36,10 @@ import org.xml.sax.SAXException;
 
 public class EncodingTester {
 
+    static int exitStatus = 0;
+
+    protected static int SNIFFING_LIMIT = 16384;
+
     private final InputStream aggregateStream;
 
     private final StringBuilder builder = new StringBuilder();
@@ -47,22 +51,24 @@ public class EncodingTester {
         this.aggregateStream = aggregateStream;
     }
 
-    private void runTests() throws IOException, SAXException {
+    void runTests() throws IOException, SAXException {
         while (runTest()) {
             // spin
         }
     }
 
+    @SuppressWarnings("resource")
     private boolean runTest() throws IOException, SAXException {
         if (skipLabel()) {
             return false;
         }
         UntilHashInputStream stream = new UntilHashInputStream(aggregateStream);
         HtmlInputStreamReader reader = new HtmlInputStreamReader(stream, null,
-                null, null, Heuristics.NONE);
+                null, null, Heuristics.NONE, SNIFFING_LIMIT);
         Charset charset = reader.getCharset();
         stream.close();
         if (skipLabel()) {
+            exitStatus = 1;
             System.err.println("Premature end of test data.");
             return false;
         }
@@ -73,6 +79,7 @@ public class EncodingTester {
                 case '\n':
                     break loop;
                 case -1:
+                    exitStatus = 1;
                     System.err.println("Premature end of test data.");
                     return false;
                 default:
@@ -82,9 +89,9 @@ public class EncodingTester {
         String sniffed = charset.name();
         String expected = Encoding.forName(builder.toString()).newDecoder().charset().name();
         if (expected.equalsIgnoreCase(sniffed)) {
-            System.err.println("Success.");
             // System.err.println(stream);
         } else {
+            exitStatus = 1;
             System.err.println("Failure. Expected: " + expected + " got "
                     + sniffed + ".");
             System.err.println(stream);
@@ -118,6 +125,7 @@ public class EncodingTester {
                     args[i]));
             tester.runTests();
         }
+        System.exit(exitStatus);
     }
 
 }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/Html5libTest.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/Html5libTest.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/Html5libTest.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/Html5libTest.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2020 Mozilla Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package nu.validator.htmlparser.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.function.Consumer;
+
+public class Html5libTest {
+
+    private final Path testDir;
+
+    public Html5libTest() throws URISyntaxException {
+        this.testDir = Paths.get(
+                Html5libTest.class.getResource("/html5lib-tests").toURI());
+    }
+
+    public void testEncoding() throws Exception {
+        Files.walkFileTree(testDir.resolve("encoding"), //
+                new TestVisitor(true, ".dat", file -> //
+                new EncodingTester(Files.newInputStream(file)).runTests()));
+        if (EncodingTester.exitStatus != 0) {
+            assert false : "Encoding test failed";
+        }
+    }
+
+    public void testTokenizer() throws Exception {
+        Files.walkFileTree(testDir.resolve("tokenizer"),
+                new TestVisitor(true, ".test", file -> //
+                new TokenizerTester(getDoubleEscapedInput(file)).runTests()));
+        if (TokenizerTester.exitStatus != 0) {
+            assert false : "Tokenizer test failed";
+        }
+    }
+
+    public void testTree() throws Exception {
+        Files.walkFileTree(testDir.resolve("tree-construction"),
+                new TestVisitor(true, ".dat", file -> //
+                new TreeTester(Files.newInputStream(file)).runTests()));
+        if (TreeTester.exitStatus != 0) {
+            assert false : "Tree test failed";
+        }
+    }
+
+    private ByteArrayInputStream getDoubleEscapedInput(Path file)
+            throws IOException {
+        byte[] fileBytes = Files.readAllBytes(file);
+        String fileContent = new String(fileBytes, StandardCharsets.UTF_8);
+        String unescapedContent = fileContent.replace("\\\\u", "\\u");
+        byte[] newBytes = unescapedContent.getBytes(StandardCharsets.UTF_8);
+        return new ByteArrayInputStream(newBytes);
+    }
+
+    private interface TestConsumer extends Consumer<Path> {
+
+        @Override
+        default void accept(Path t) {
+            try {
+                acceptTest(t);
+            } catch (Throwable e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        void acceptTest(Path t) throws Throwable;
+
+    }
+
+    private static class TestVisitor extends SimpleFileVisitor<Path> {
+
+        private final boolean skipScripted;
+
+        private final String requiredTestExtension;
+
+        private final TestConsumer runner;
+
+        private TestVisitor(boolean skipScripted, String requiredTestExtension,
+                TestConsumer runner) {
+            this.skipScripted = skipScripted;
+            this.requiredTestExtension = requiredTestExtension;
+            this.runner = runner;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir,
+                BasicFileAttributes attrs) throws IOException {
+            if (skipScripted
+                    && dir.getFileName().equals(Paths.get("scripted"))) {
+                return FileVisitResult.SKIP_SUBTREE;
+            }
+
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                throws IOException {
+            if (file.getFileName().toString().endsWith(requiredTestExtension)) {
+                runner.accept(file);
+            }
+            return FileVisitResult.CONTINUE;
+        }
+    }
+
+}
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/JSONArrayTokenHandler.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/JSONArrayTokenHandler.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/JSONArrayTokenHandler.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/JSONArrayTokenHandler.java	2025-09-16 08:29:41.000000000 +0000
@@ -2,32 +2,27 @@
  * Copyright (c) 2007 Henri Sivonen
  * Copyright (c) 2008 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 package nu.validator.htmlparser.test;
 
-import nu.validator.htmlparser.common.TokenHandler;
-import nu.validator.htmlparser.impl.ElementName;
-import nu.validator.htmlparser.impl.HtmlAttributes;
-import nu.validator.htmlparser.impl.Tokenizer;
-
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
@@ -38,6 +33,11 @@ import com.sdicons.json.model.JSONNull;
 import com.sdicons.json.model.JSONObject;
 import com.sdicons.json.model.JSONString;
 
+import nu.validator.htmlparser.common.TokenHandler;
+import nu.validator.htmlparser.impl.ElementName;
+import nu.validator.htmlparser.impl.HtmlAttributes;
+import nu.validator.htmlparser.impl.Tokenizer;
+
 public class JSONArrayTokenHandler implements TokenHandler, ErrorHandler {
 
     private static final JSONString DOCTYPE = new JSONString("DOCTYPE");
@@ -54,6 +54,8 @@ public class JSONArrayTokenHandler imple
 
     private static final char[] REPLACEMENT_CHARACTER = { '\uFFFD' };
 
+    private static final char[] NULL = { '\u0000' };
+
     private final StringBuilder builder = new StringBuilder();
 
     private JSONArray array = null;
@@ -61,7 +63,7 @@ public class JSONArrayTokenHandler imple
     private int contentModelFlag;
 
     private String contentModelElement;
-    
+
     public void setContentModelFlag(int contentModelFlag, String contentModelElement) {
         this.contentModelFlag = contentModelFlag;
         this.contentModelElement = contentModelElement;
@@ -94,7 +96,7 @@ public class JSONArrayTokenHandler imple
         flushCharacters();
         JSONArray token = new JSONArray();
         token.getValue().add(DOCTYPE);
-        token.getValue().add(new JSONString(name));
+        token.getValue().add(name == null ? JSONNull.NULL : new JSONString(name));
         token.getValue().add(publicIdentifier == null ? JSONNull.NULL : new JSONString(publicIdentifier));
         token.getValue().add(systemIdentifier == null ? JSONNull.NULL : new JSONString(systemIdentifier));
         token.getValue().add(new JSONBoolean(!forceQuirks));
@@ -102,7 +104,7 @@ public class JSONArrayTokenHandler imple
     }
 
     public void endTag(ElementName eltName) throws SAXException {
-        String name = eltName.name;
+        String name = eltName.getName();
         flushCharacters();
         JSONArray token = new JSONArray();
         token.getValue().add(END_TAG);
@@ -121,20 +123,21 @@ public class JSONArrayTokenHandler imple
         }
     }
 
-    public void startTag(ElementName eltName, HtmlAttributes attributes, boolean selfClosing)
-            throws SAXException {
-        String name = eltName.name;
+    public void startTag(ElementName eltName, HtmlAttributes attributes,
+            boolean selfClosing) throws SAXException {
+        String name = eltName.getName();
         flushCharacters();
         JSONArray token = new JSONArray();
         token.getValue().add(START_TAG);
         token.getValue().add(new JSONString(name));
         JSONObject attrs = new JSONObject();
         for (int i = 0; i < attributes.getLength(); i++) {
-            attrs.getValue().put(attributes.getQName(i), new JSONString(attributes.getValue(i)));
+            attrs.getValue().put(attributes.getQNameNoBoundsCheck(i),
+                    new JSONString(attributes.getValueNoBoundsCheck(i)));
         }
         token.getValue().add(attrs);
         if (selfClosing) {
-            token.getValue().add(JSONBoolean.TRUE);            
+            token.getValue().add(JSONBoolean.TRUE);
         }
         array.getValue().add(token);
     }
@@ -144,8 +147,8 @@ public class JSONArrayTokenHandler imple
     }
 
     public void error(SAXParseException exception) throws SAXException {
-        flushCharacters();
-        array.getValue().add(PARSE_ERROR);
+//        flushCharacters();
+//        array.getValue().add(PARSE_ERROR);
     }
 
     public void fatalError(SAXParseException exception) throws SAXException {
@@ -157,7 +160,7 @@ public class JSONArrayTokenHandler imple
 
     /**
      * Returns the array.
-     * 
+     *
      * @return the array
      */
     public JSONArray getArray() {
@@ -165,7 +168,7 @@ public class JSONArrayTokenHandler imple
     }
 
     public void endTokenization() throws SAXException {
-        
+
     }
 
     @Override public void zeroOriginatingReplacementCharacter()
@@ -173,8 +176,17 @@ public class JSONArrayTokenHandler imple
         builder.append(REPLACEMENT_CHARACTER, 0, 1);
     }
 
+    @Override public void zeroOrReplacementCharacter()
+            throws SAXException {
+        builder.append(NULL, 0, 1);
+    }
+
     @Override public boolean cdataSectionAllowed() throws SAXException {
         return false;
     }
-    
+
+    @Override public void ensureBufferSpace(int inputLength)
+            throws SAXException {
+    }
+
 }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TokenPrinter.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TokenPrinter.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TokenPrinter.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TokenPrinter.java	2025-09-16 08:29:41.000000000 +0000
@@ -2,22 +2,22 @@
  * Copyright (c) 2007 Henri Sivonen
  * Copyright (c) 2008 Mozilla Foundation
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
@@ -29,6 +29,11 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
 import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.impl.ElementName;
 import nu.validator.htmlparser.impl.ErrorReportingTokenizer;
@@ -36,15 +41,10 @@ import nu.validator.htmlparser.impl.Html
 import nu.validator.htmlparser.impl.Tokenizer;
 import nu.validator.htmlparser.io.Driver;
 
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
 public class TokenPrinter implements TokenHandler, ErrorHandler {
 
     private final Writer writer;
-    
+
     public void characters(char[] buf, int start, int length)
             throws SAXException {
         try {
@@ -52,15 +52,15 @@ public class TokenPrinter implements Tok
         writer.write('-');
         for (int i = start; i < start + length; i++) {
             if (!lineStarted) {
-                writer.write("\n-");                
+                writer.write("\n-");
                 lineStarted = true;
             }
             char c = buf[i];
             if (c == '\n') {
-                writer.write("\\n");                                
-                lineStarted = false;                
+                writer.write("\\n");
+                lineStarted = false;
             } else {
-                writer.write(c);                
+                writer.write(c);
             }
         }
         writer.write('\n');
@@ -94,7 +94,7 @@ public class TokenPrinter implements Tok
     public void endTag(ElementName eltName) throws SAXException {
         try {
             writer.write(')');
-            writer.write(eltName.name);
+            writer.write(eltName.getName());
             writer.write('\n');
         } catch (IOException e) {
             throw new SAXException(e);
@@ -106,7 +106,7 @@ public class TokenPrinter implements Tok
         writer.write("E\n");
     } catch (IOException e) {
         throw new SAXException(e);
-    }        
+    }
     }
 
     public void startTokenization(Tokenizer self) throws SAXException {
@@ -117,14 +117,14 @@ public class TokenPrinter implements Tok
             throws SAXException {
         try {
             writer.write('(');
-            writer.write(eltName.name);
+            writer.write(eltName.getName());
             writer.write('\n');
             for (int i = 0; i < attributes.getLength(); i++) {
                 writer.write('A');
-                writer.write(attributes.getQName(i));
+                writer.write(attributes.getQNameNoBoundsCheck(i));
                 writer.write(' ');
-                writer.write(attributes.getValue(i));
-                writer.write('\n');                
+                writer.write(attributes.getValueNoBoundsCheck(i));
+                writer.write('\n');
             }
         } catch (IOException e) {
             throw new SAXException(e);
@@ -136,7 +136,7 @@ public class TokenPrinter implements Tok
     }
 
     public static void main(String[] args) throws SAXException, IOException {
-        TokenPrinter printer = new TokenPrinter(new OutputStreamWriter(System.out, "UTF-8")); 
+        TokenPrinter printer = new TokenPrinter(new OutputStreamWriter(System.out, "UTF-8"));
         Driver tokenizer = new Driver(new ErrorReportingTokenizer(printer));
         tokenizer.setErrorHandler(printer);
         File file = new File(args[0]);
@@ -159,7 +159,7 @@ public class TokenPrinter implements Tok
             writer.write("\n");
         } catch (IOException e) {
             throw new SAXException(e);
-        }        
+        }
     }
 
     public void fatalError(SAXParseException exception) throws SAXException {
@@ -169,7 +169,7 @@ public class TokenPrinter implements Tok
             writer.write("\n");
         } catch (IOException e) {
             throw new SAXException(e);
-        }        
+        }
     }
 
     public void warning(SAXParseException exception) throws SAXException {
@@ -179,7 +179,7 @@ public class TokenPrinter implements Tok
             writer.write("\n");
         } catch (IOException e) {
             throw new SAXException(e);
-        }        
+        }
     }
 
     public void endTokenization() throws SAXException {
@@ -188,7 +188,7 @@ public class TokenPrinter implements Tok
             writer.close();
         } catch (IOException e) {
             throw new SAXException(e);
-        }        
+        }
     }
 
     @Override public void zeroOriginatingReplacementCharacter()
@@ -197,10 +197,19 @@ public class TokenPrinter implements Tok
             writer.write("0\n");
         } catch (IOException e) {
             throw new SAXException(e);
-        }        
+        }
+    }
+
+    @Override public void zeroOrReplacementCharacter()
+            throws SAXException {
+        zeroOriginatingReplacementCharacter();
     }
 
     @Override public boolean cdataSectionAllowed() throws SAXException {
         return false;
     }
+
+    @Override public void ensureBufferSpace(int inputLength)
+            throws SAXException {
+    }
 }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TokenizerTester.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TokenizerTester.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TokenizerTester.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TokenizerTester.java	2025-09-16 08:29:41.000000000 +0000
@@ -22,6 +22,7 @@
 
 package nu.validator.htmlparser.test;
 
+import java.io.ByteArrayInputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -31,6 +32,9 @@ import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 import nu.validator.htmlparser.impl.ErrorReportingTokenizer;
@@ -51,14 +55,20 @@ import com.sdicons.json.parser.JSONParse
 
 public class TokenizerTester {
 
+    static int exitStatus = 0;
+
     private static JSONString PLAINTEXT = new JSONString("PLAINTEXT state");
 
-    private static JSONString PCDATA = new JSONString("DATA state");
+    private static JSONString PCDATA = new JSONString("Data state");
 
     private static JSONString RCDATA = new JSONString("RCDATA state");
 
+    private static JSONString CDATA = new JSONString("CDATA section state");
+
     private static JSONString RAWTEXT = new JSONString("RAWTEXT state");
 
+    private static JSONString SCRIPT_DATA = new JSONString("Script data state");
+
     private static boolean jsonDeepEquals(JSONValue one, JSONValue other) {
         if (one.isSimple()) {
             return one.equals(other);
@@ -91,7 +101,7 @@ public class TokenizerTester {
 
     private final Writer writer;
 
-    private TokenizerTester(InputStream stream) throws TokenStreamException,
+    public TokenizerTester(InputStream stream) throws TokenStreamException,
             RecognitionException, UnsupportedEncodingException {
         tokenHandler = new JSONArrayTokenHandler();
         driver = new Driver(new ErrorReportingTokenizer(tokenHandler));
@@ -101,6 +111,7 @@ public class TokenizerTester {
         driver.setNamePolicy(XmlViolationPolicy.ALLOW);
         driver.setXmlnsPolicy(XmlViolationPolicy.ALLOW);
         driver.setErrorHandler(tokenHandler);
+        driver.dontSwallowBom();
         writer = new OutputStreamWriter(System.out, "UTF-8");
         JSONParser jsonParser = new JSONParser(new InputStreamReader(stream,
                 "UTF-8"));
@@ -115,7 +126,7 @@ public class TokenizerTester {
         }
     }
 
-    private void runTests() throws SAXException, IOException {
+    void runTests() throws SAXException, IOException {
         for (JSONValue val : tests.getValue()) {
             runTest((JSONObject) val);
         }
@@ -136,17 +147,29 @@ public class TokenizerTester {
         } else {
             for (JSONValue value : contentModelFlags.getValue()) {
                 if (PCDATA.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "xmp" : lastStartTag;
                     runTestInner(inputString, expectedTokens, description,
                             Tokenizer.DATA, lastStartTag);
                 } else if (RAWTEXT.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "xmp" : lastStartTag;
                     runTestInner(inputString, expectedTokens, description,
                             Tokenizer.RAWTEXT, lastStartTag);
                 } else if (RCDATA.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "xmp" : lastStartTag;
                     runTestInner(inputString, expectedTokens, description,
                             Tokenizer.RCDATA, lastStartTag);
+                } else if (CDATA.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "xmp" : lastStartTag;
+                    runTestInner(inputString, expectedTokens, description,
+                            Tokenizer.CDATA_SECTION, lastStartTag);
                 } else if (PLAINTEXT.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "plaintext" : lastStartTag;
                     runTestInner(inputString, expectedTokens, description,
                             Tokenizer.PLAINTEXT, lastStartTag);
+                } else if (SCRIPT_DATA.equals(value)) {
+                    lastStartTag = lastStartTag == null ? "script" : lastStartTag;
+                    runTestInner(inputString, expectedTokens, description,
+                            Tokenizer.SCRIPT_DATA, lastStartTag);
                 } else {
                     throw new RuntimeException("Broken test data.");
                 }
@@ -169,9 +192,8 @@ public class TokenizerTester {
         try {
             driver.tokenize(is);
             JSONArray actualTokens = tokenHandler.getArray();
-            if (jsonDeepEquals(actualTokens, expectedTokens)) {
-                writer.write("Success\n");
-            } else {
+            if (!jsonDeepEquals(actualTokens, expectedTokens)) {
+                exitStatus = 1;
                 writer.write("Failure\n");
                 writer.write(description);
                 writer.write("\nInput:\n");
@@ -183,6 +205,7 @@ public class TokenizerTester {
                 writer.write("\n");
             }
         } catch (Throwable t) {
+            exitStatus = 1;
             writer.write("Failure\n");
             writer.write(description);
             writer.write("\nInput:\n");
@@ -202,10 +225,15 @@ public class TokenizerTester {
     public static void main(String[] args) throws TokenStreamException,
             RecognitionException, SAXException, IOException {
         for (int i = 0; i < args.length; i++) {
-            TokenizerTester tester = new TokenizerTester(new FileInputStream(
-                    args[i]));
+            byte[] fileBytes = Files.readAllBytes(Paths.get(args[i]));
+            String fileContent = new String(fileBytes, StandardCharsets.UTF_8);
+            String unescapedContent = fileContent.replace("\\\\u", "\\u");
+            byte[] newBytes = unescapedContent.getBytes(StandardCharsets.UTF_8);
+            ByteArrayInputStream bais = new ByteArrayInputStream(newBytes);
+            TokenizerTester tester = new TokenizerTester(bais);
             tester.runTests();
         }
+        System.exit(exitStatus);
     }
 
 }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreeDumpContentHandler.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreeDumpContentHandler.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreeDumpContentHandler.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreeDumpContentHandler.java	2025-09-16 08:29:41.000000000 +0000
@@ -89,6 +89,11 @@ public class TreeDumpContentHandler impl
                 inCharacters = false;
             }
             level--;
+            if ("http://www.w3.org/1999/xhtml" == uri &&
+                    "template" == localName) {
+                // decrement level for the "content"
+                level--;
+            }
         } catch (IOException e) {
             throw new SAXException(e);
         }
@@ -104,12 +109,11 @@ public class TreeDumpContentHandler impl
             } else if ("http://www.w3.org/2000/svg" == uri) {
                 writer.write("svg ");                                
             } else if ("http://www.w3.org/1999/xhtml" != uri) {
-                writer.write("otherns ");                                
+                writer.write("otherns ");
             }
             writer.write(localName);
             writer.write(">\n");
             level++;
-
             TreeMap<String, String> map = new TreeMap<String, String>();
             for (int i = 0; i < atts.getLength(); i++) {
                 String ns = atts.getURI(i);
@@ -134,6 +138,12 @@ public class TreeDumpContentHandler impl
                 writer.write(entry.getValue());
                 writer.write("\"\n");
             }
+            if ("http://www.w3.org/1999/xhtml" == uri &&
+                    "template" == localName) {
+                printLead();
+                level++;
+                writer.write("content\n");
+            }
         } catch (IOException e) {
             throw new SAXException(e);
         }
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreePrinter.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreePrinter.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreePrinter.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreePrinter.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,22 +1,22 @@
 /*
  * Copyright (c) 2007 Henri Sivonen
  *
- * Permission is hereby granted, free of charge, to any person obtaining a 
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation 
- * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
- * and/or sell copies of the Software, and to permit persons to whom the 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included in 
+ * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
@@ -27,19 +27,21 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 
-import nu.validator.htmlparser.sax.HtmlParser;
-
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
+import nu.validator.htmlparser.common.XmlViolationPolicy;
+import nu.validator.htmlparser.sax.HtmlParser;
+
 public class TreePrinter {
 
     public static void main(String[] args) throws SAXException, IOException {
-        TreeDumpContentHandler treeDumpContentHandler = new TreeDumpContentHandler(new OutputStreamWriter(System.out, "UTF-8")); 
+        TreeDumpContentHandler treeDumpContentHandler = new TreeDumpContentHandler(new OutputStreamWriter(System.out, "UTF-8"));
         HtmlParser htmlParser = new HtmlParser();
         htmlParser.setContentHandler(treeDumpContentHandler);
         htmlParser.setLexicalHandler(treeDumpContentHandler);
         htmlParser.setErrorHandler(new SystemErrErrorHandler());
+        htmlParser.setXmlPolicy(XmlViolationPolicy.ALLOW);
         File file = new File(args[0]);
         InputSource is = new InputSource(new FileInputStream(file));
         is.setSystemId(file.toURI().toASCIIString());
diff -pruN 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreeTester.java 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreeTester.java
--- 1.4+r1.3.1-3/test-src/nu/validator/htmlparser/test/TreeTester.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/test-src/nu/validator/htmlparser/test/TreeTester.java	2025-09-16 08:29:41.000000000 +0000
@@ -43,6 +43,8 @@ public class TreeTester {
 
     private boolean streaming = false;
 
+    static int exitStatus = 0;
+
     /**
      * @param aggregateStream
      */
@@ -50,7 +52,7 @@ public class TreeTester {
         this.aggregateStream = new BufferedInputStream(aggregateStream);
     }
 
-    private void runTests() throws Throwable {
+    void runTests() throws Throwable {
         if (aggregateStream.read() != '#') {
             System.err.println("No hash at start!");
             return;
@@ -60,10 +62,13 @@ public class TreeTester {
         }
     }
 
+    @SuppressWarnings("resource")
     private boolean runTest() throws Throwable {
         UntilHashInputStream stream = null;
         try {
             String context = null;
+            boolean scriptingEnabled = true;
+            boolean hadScriptingDirective = false;
             aggregateStream.mark(12288);
             if (skipLabel()) { // #data
                 return false;
@@ -81,18 +86,43 @@ public class TreeTester {
                 // spin
             }
 
+            boolean newErrors = false;
             StringBuilder sb = new StringBuilder();
             int c;
             while ((c = aggregateStream.read()) != '\n') {
                 sb.append((char) c);
             }
             String label = sb.toString();
+            if ("new-errors".equals(label)) {
+                newErrors = true;
+                stream = new UntilHashInputStream(aggregateStream);
+                while (stream.read() != -1) {
+                    // spin
+                }
+                sb.setLength(0);
+                while ((c = aggregateStream.read()) != '\n') {
+                    sb.append((char) c);
+                }
+                label = sb.toString();
+            }
             if ("document-fragment".equals(label)) {
                 sb.setLength(0);
                 while ((c = aggregateStream.read()) != '\n') {
                     sb.append((char) c);
                 }
                 context = sb.toString();
+                // Now potentially gather #script-on/off
+                sb.setLength(0);
+                while ((c = aggregateStream.read()) != '\n') {
+                    sb.append((char) c);
+                }
+                label = sb.toString();
+            }
+            if ("script-on".equals(label)) {
+                hadScriptingDirective = true;
+            } else if ("script-off".equals(label)) {
+                hadScriptingDirective = true;
+                scriptingEnabled = false;
             }
             aggregateStream.reset();
             if (skipLabel()) { // #data
@@ -113,12 +143,20 @@ public class TreeTester {
             htmlParser.setContentHandler(treeDumpContentHandler);
             htmlParser.setLexicalHandler(treeDumpContentHandler);
             htmlParser.setErrorHandler(leh);
-            htmlParser.setScriptingEnabled(true);
+            htmlParser.setScriptingEnabled(scriptingEnabled);
             try {
                 if (context == null) {
                     htmlParser.parse(is);
                 } else {
-                    htmlParser.parseFragment(is, context);
+                    String ns = "http://www.w3.org/1999/xhtml";
+                    if (context.startsWith("svg ")) {
+                        ns = "http://www.w3.org/2000/svg";
+                        context = context.substring(4);
+                    } else if (context.startsWith("math ")) {
+                        ns = "http://www.w3.org/1998/Math/MathML";
+                        context = context.substring(5);
+                    }
+                    htmlParser.parseFragment(is, context, ns);
                     treeDumpContentHandler.endDocument();
                 }
             } catch (SAXParseException e) {
@@ -138,6 +176,18 @@ public class TreeTester {
                 expectedErrors.add(line);
             }
 
+            if (newErrors) {
+                if (skipLabel()) { // #new-errors
+                    System.err.println("Premature end of test data.");
+                    return false;
+                }
+                br = new BufferedReader(new InputStreamReader(
+                        new UntilHashInputStream(aggregateStream), "UTF-8"));
+                while ((line = br.readLine()) != null) {
+                    expectedErrors.add(line);
+                }
+            }
+
             if (context != null) {
                 if (skipLabel()) { // #document-fragment
                     System.err.println("Premature end of test data.");
@@ -148,7 +198,10 @@ public class TreeTester {
                     // spin
                 }
             }
-
+            if (hadScriptingDirective && skipLabel()) { // #script-on/off
+                System.err.println("Premature end of test data.");
+                return false;                
+            }
 
             if (skipLabel()) { // #document
                 System.err.println("Premature end of test data.");
@@ -163,6 +216,9 @@ public class TreeTester {
                 expectedBuilder.append((char)ch);
             }
             String expected = expectedBuilder.toString();
+            if (expected.contains("<keygen>")) {
+                return true;
+            }
             String actual = sw.toString();
 
             LinkedList<String> actualErrors = leh.getErrors();
@@ -171,9 +227,9 @@ public class TreeTester {
              * && expectedErrors.size() ==
              * actualErrors.size()
              */) {
-                System.err.println("Success.");
                 // System.err.println(stream);
             } else {
+                exitStatus = 1;
                 System.err.print("Failure.\nData:\n" + stream + "\nExpected:\n"
                         + expected + "Got: \n" + actual);
                 System.err.println("Expected errors:");
@@ -186,6 +242,7 @@ public class TreeTester {
                 }
             }
         } catch (Throwable t) {
+            exitStatus = 1;
             System.err.println("Failure.\nData:\n" + stream);
             throw t;
         }
@@ -216,6 +273,7 @@ public class TreeTester {
             TreeTester tester = new TreeTester(new FileInputStream(args[i]));
             tester.runTests();
         }
+        System.exit(exitStatus);
     }
 
 }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/AnnotationHelperVisitor.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/AnnotationHelperVisitor.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/AnnotationHelperVisitor.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/AnnotationHelperVisitor.java	2025-09-16 08:29:41.000000000 +0000
@@ -39,8 +39,11 @@ package nu.validator.htmlparser.cpptrans
 
 import java.util.List;
 
+import japa.parser.ast.expr.Expression;
+import japa.parser.ast.expr.IntegerLiteralExpr;
 import japa.parser.ast.expr.AnnotationExpr;
 import japa.parser.ast.expr.MarkerAnnotationExpr;
+import japa.parser.ast.expr.SingleMemberAnnotationExpr;
 import japa.parser.ast.type.ReferenceType;
 import japa.parser.ast.visitor.VoidVisitorAdapter;
 
@@ -56,6 +59,14 @@ public class AnnotationHelperVisitor<T>
         return hasAnnotation("Prefix");
     }
 
+    protected boolean staticLocal() {
+        return hasAnnotation("StaticLocal");
+    }
+
+    protected boolean weakLocal() {
+        return hasAnnotation("WeakLocal");
+    }
+
     protected boolean local() {
         return hasAnnotation("Local");
     }
@@ -72,6 +83,10 @@ public class AnnotationHelperVisitor<T>
         return hasAnnotation("NoLength");
     }
 
+    protected boolean unsigned() {
+        return hasAnnotation("Unsigned");
+    }
+
     protected boolean auto() {
         return hasAnnotation("Auto");
     }
@@ -80,6 +95,10 @@ public class AnnotationHelperVisitor<T>
         return hasAnnotation("Virtual");
     }
 
+    protected boolean override() {
+        return hasAnnotation("Override");
+    }
+
     protected boolean isConst() {
         return hasAnnotation("Const");
     }
@@ -88,32 +107,71 @@ public class AnnotationHelperVisitor<T>
         return hasAnnotation("CharacterName");
     }
 
+    protected boolean creator() {
+        return hasAnnotation("Creator");
+    }
+
+    protected boolean htmlCreator() {
+        return hasAnnotation("HtmlCreator");
+    }
+
+    protected boolean svgCreator() {
+        return hasAnnotation("SvgCreator");
+    }
+
+    protected int inlineLength() {
+        AnnotationExpr anno = findAnnotation("CppInlineLength");
+        if (anno == null || !(anno instanceof SingleMemberAnnotationExpr)) {
+            return 0;
+        }
+        Expression expr = ((SingleMemberAnnotationExpr)anno).getMemberValue();
+        if (!(expr instanceof IntegerLiteralExpr)) {
+            return 0;
+        }
+        return Integer.parseInt(((IntegerLiteralExpr)expr).getValue());
+    }
+
     private boolean hasAnnotation(String anno) {
+        AnnotationExpr expr = findAnnotation(anno);
+        return expr != null && expr instanceof MarkerAnnotationExpr;
+    }
+
+    private AnnotationExpr findAnnotation(String anno) {
         if (currentAnnotations == null) {
-            return false;
+            return null;
         }
         for (AnnotationExpr ann : currentAnnotations) {
             if (ann instanceof MarkerAnnotationExpr) {
-                MarkerAnnotationExpr marker = (MarkerAnnotationExpr) ann;
-                if (marker.getName().getName().equals(anno)) {
-                    return true;
+                if (((MarkerAnnotationExpr)ann).getName().getName().equals(anno)) {
+                    return ann;
+                }
+            }
+            if (ann instanceof SingleMemberAnnotationExpr) {
+                if (((SingleMemberAnnotationExpr)ann).getName().getName().equals(anno)) {
+                    return ann;
                 }
             }
         }
-        return false;
+        return null;
     }
 
     protected Type convertType(japa.parser.ast.type.Type type, int modifiers) {
         if (type instanceof ReferenceType) {
             ReferenceType referenceType = (ReferenceType) type;
-            return new Type(convertTypeName(referenceType.getType().toString()), referenceType.getArrayCount(), noLength(), modifiers);
+            return new Type(convertTypeName(referenceType.getType().toString()));
         } else {
-            return new Type(convertTypeName(type.toString()), 0, false, modifiers);
+            return new Type(convertTypeName(type.toString()));
         }
     }
 
     private String convertTypeName(String name) {
         if ("String".equals(name)) {
+            if (staticLocal()) {
+                return "@StaticLocal";
+            }
+            if (weakLocal()) {
+                return "@WeakLocal";
+            }
             if (local()) {
                 return "@Local";
             }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java	2025-09-16 08:29:41.000000000 +0000
@@ -37,9 +37,12 @@
 
 package nu.validator.htmlparser.cpptranslate;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.Arrays;
@@ -47,33 +50,15 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class CppTypes {
 
-    /**
-     * The license for the atom list written by this program.
-     */
-    private static final String ATOM_LICENSE = "/*\n"
-            + " * Copyright (c) 2008-2010 Mozilla Foundation\n"
-            + " *\n"
-            + " * Permission is hereby granted, free of charge, to any person obtaining a \n"
-            + " * copy of this software and associated documentation files (the \"Software\"), \n"
-            + " * to deal in the Software without restriction, including without limitation \n"
-            + " * the rights to use, copy, modify, merge, publish, distribute, sublicense, \n"
-            + " * and/or sell copies of the Software, and to permit persons to whom the \n"
-            + " * Software is furnished to do so, subject to the following conditions:\n"
-            + " *\n"
-            + " * The above copyright notice and this permission notice shall be included in \n"
-            + " * all copies or substantial portions of the Software.\n"
-            + " *\n"
-            + " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \n"
-            + " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \n"
-            + " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL \n"
-            + " * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \n"
-            + " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \n"
-            + " * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \n"
-            + " * DEALINGS IN THE SOFTWARE.\n" + " */\n\n";
-    
+    /* Please note we aren't looking for the following Atom definitions:
+       PseudoElementAtom or NonInheritingAnonBoxAtom or InheritingAnonBoxAtom */
+    private static final Pattern ATOM_DEF = Pattern.compile("^\\s*Atom\\(\"([^,]+)\",\\s*\"([^\"]*)\"\\).*$");
+
     private static Set<String> reservedWords = new HashSet<String>();
 
     static {
@@ -96,57 +81,122 @@ public class CppTypes {
         reservedWords.add("unicode");
     }
 
-    private static final String[] TREE_BUILDER_INCLUDES = { "prtypes",
-            "nsIAtom", "nsHtml5AtomTable", "nsITimer", "nsString",
-            "nsINameSpaceManager", "nsIContent", "nsIDocument",
-            "nsTraceRefcnt", "jArray", "nsHtml5DocumentMode",
-            "nsHtml5ArrayCopy", "nsHtml5Parser", "nsHtml5Atoms",
-            "nsHtml5ByteReadable", "nsHtml5TreeOperation",
-            "nsHtml5PendingNotification", "nsHtml5StateSnapshot",
-            "nsHtml5StackNode", "nsHtml5TreeOpExecutor", "nsHtml5StreamParser",
-            "nsAHtml5TreeBuilderState" };
-
-    private static final String[] INCLUDES = { "prtypes", "nsIAtom",
-            "nsHtml5AtomTable", "nsString", "nsINameSpaceManager",
-            "nsIContent", "nsIDocument", "nsTraceRefcnt", "jArray",
-            "nsHtml5DocumentMode", "nsHtml5ArrayCopy",
-            "nsHtml5NamedCharacters", "nsHtml5NamedCharactersAccel",
-            "nsHtml5Atoms", "nsHtml5ByteReadable", "nsIUnicodeDecoder",
-            "nsAHtml5TreeBuilderState", "nsHtml5Macros" };
+    private static final String[] TREE_BUILDER_INCLUDES = { "jArray",
+            "mozilla/ImportScanner", "mozilla/Likely",
+            "nsAHtml5TreeBuilderState", "nsAtom", "nsContentUtils", "nsGkAtoms",
+            "nsHtml5ArrayCopy", "nsHtml5AtomTable", "nsHtml5DocumentMode",
+            "nsHtml5Highlighter", "nsHtml5OplessBuilder", "nsHtml5Parser",
+            "nsHtml5PlainTextUtils", "nsHtml5StackNode", "nsHtml5StateSnapshot",
+            "nsHtml5StreamParser", "nsHtml5String", "nsHtml5TreeOperation",
+            "nsHtml5TreeOpExecutor", "nsHtml5ViewSourceUtils", "nsIContent",
+            "nsIContentHandle", "nsNameSpaceManager", "nsTraceRefcnt", };
+
+    private static final String[] TOKENIZER_INCLUDES = { "jArray",
+            "nsAHtml5TreeBuilderState", "nsAtom", "nsGkAtoms",
+            "nsHtml5ArrayCopy", "nsHtml5AtomTable", "nsHtml5DocumentMode",
+            "nsHtml5Highlighter", "nsHtml5Macros", "nsHtml5NamedCharacters",
+            "nsHtml5NamedCharactersAccel", "nsHtml5String",
+            "nsIContent", "nsTraceRefcnt" };
+
+    private static final String[] STACK_NODE_INCLUDES = { "nsAtom", "nsHtml5AtomTable",
+            "nsHtml5HtmlAttributes", "nsHtml5String", "nsNameSpaceManager", "nsIContent",
+            "nsTraceRefcnt", "jArray", "nsHtml5ArrayCopy",
+            "nsAHtml5TreeBuilderState", "nsGkAtoms", "nsHtml5ByteReadable",
+            "nsHtml5Macros", "nsIContentHandle", "nsHtml5Portability",
+            "nsHtml5ContentCreatorFunction" };
+
+    private static final String[] INCLUDES = { "nsAtom", "nsHtml5AtomTable",
+            "nsHtml5String", "nsNameSpaceManager", "nsIContent",
+            "nsTraceRefcnt", "jArray", "nsHtml5ArrayCopy",
+            "nsAHtml5TreeBuilderState", "nsGkAtoms", "nsHtml5ByteReadable",
+            "nsHtml5Macros", "nsIContentHandle", "nsHtml5Portability",
+            "nsHtml5ContentCreatorFunction" };
 
     private static final String[] OTHER_DECLATIONS = {};
 
     private static final String[] TREE_BUILDER_OTHER_DECLATIONS = {};
 
-    private static final String[] NAMED_CHARACTERS_INCLUDES = { "prtypes",
-            "jArray", "nscore", "nsDebug", "prlog", "nsMemory" };
+    private static final String[] NAMED_CHARACTERS_INCLUDES = { "jArray",
+            "mozilla/Logging", "nscore", "nsDebug", "nsMemory" };
 
-    private static final String[] FORWARD_DECLARATIONS = { "nsHtml5StreamParser", };
+    private static final String[] FORWARD_DECLARATIONS = { "nsHtml5StreamParser" };
 
     private static final String[] CLASSES_THAT_NEED_SUPPLEMENT = {
-            "MetaScanner", "TreeBuilder", "UTF16Buffer", };
+            "Tokenizer", "TreeBuilder", "UTF16Buffer", };
+
+    private static final String[] STATE_LOOP_POLICIES = {
+            "nsHtml5ViewSourcePolicy", "nsHtml5LineColPolicy", "nsHtml5FastestPolicy" };
 
     private final Map<String, String> atomMap = new HashMap<String, String>();
 
     private final Writer atomWriter;
 
-    public CppTypes(File atomList) {
+    public CppTypes(File atomList, File generatedAtomFile) {
         if (atomList == null) {
             atomWriter = null;
         } else {
             try {
+                ingestAtoms(atomList);
                 atomWriter = new OutputStreamWriter(new FileOutputStream(
-                        atomList), "utf-8");
-                atomWriter.write(ATOM_LICENSE);
+                        generatedAtomFile), "utf-8");
+                this.start();
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
         }
     }
 
+    private void ingestAtoms(File atomList) throws IOException {
+        // This doesn't need to be efficient, so let's make it easy to write.
+        BufferedReader atomReader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(atomList), "utf-8"));
+        try {
+            String line;
+            boolean startedParsing = false;
+            while ((line = atomReader.readLine()) != null) {
+                // only start parsing lines after this comment
+                if (line.trim().startsWith("# START ATOMS")) {
+                    startedParsing = true;
+                } else if (!startedParsing) {
+                    continue;
+                }
+                // stop parsing lines after this comment
+                if (line.trim().startsWith("# END ATOMS")) {
+                    return;
+                }
+                if (!line.trim().startsWith("Atom")) {
+                    continue;
+                }
+                Matcher m = ATOM_DEF.matcher(line);
+                if (!m.matches()) {
+                    throw new RuntimeException("Malformed atom definition: " + line);
+                }
+                atomMap.put(m.group(2), m.group(1));
+            }
+            throw new RuntimeException(
+                    "Atom list did not have a marker for generated section.");
+        } finally {
+            atomReader.close();
+        }
+    }
+
+    public void start() {
+        try {
+
+            if (atomWriter != null) {
+                atomWriter.write("# THIS FILE IS GENERATED BY THE HTML PARSER TRANSLATOR AND WILL BE OVERWRITTEN!\n");
+                atomWriter.write("from Atom import Atom\n\n");
+                atomWriter.write("HTML_PARSER_ATOMS = [\n");
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     public void finished() {
         try {
             if (atomWriter != null) {
+                atomWriter.write("]\n");
                 atomWriter.flush();
                 atomWriter.close();
             }
@@ -160,55 +210,68 @@ public class CppTypes {
     }
 
     public String booleanType() {
-        return "PRBool";
+        return "bool";
     }
 
     public String byteType() {
-        return "PRInt8";
+        return "int8_t";
     }
 
     public String charType() {
-        return "PRUnichar";
+        return "char16_t";
     }
 
     /**
      * Only used for named characters.
+     *
      * @return
      */
     public String unsignedShortType() {
-        return "PRUint16";
+        return "uint16_t";
     }
 
     public String intType() {
-        return "PRInt32";
+        return "int32_t";
+    }
+
+    public String unsignedIntType() {
+        return "uint32_t";
     }
 
     public String stringType() {
-        return "nsString*";
+        return "nsHtml5String";
+    }
+
+    public String weakLocalType() {
+        return "nsAtom*";
     }
 
     public String localType() {
-        return "nsIAtom*";
+        return "RefPtr<nsAtom>";
+    }
+
+    public String staticLocalType() {
+        return "nsStaticAtom*";
     }
 
     public String prefixType() {
-        return "nsIAtom*";
+        return "nsStaticAtom*";
     }
 
     public String nsUriType() {
-        return "PRInt32";
+        return "int32_t";
     }
 
     public String falseLiteral() {
-        return "PR_FALSE";
+        return "false";
     }
 
     public String trueLiteral() {
-        return "PR_TRUE";
+        return "true";
     }
 
     public String nullLiteral() {
-        return "nsnull";
+        return "nullptr";
     }
 
     public String encodingDeclarationHandlerType() {
@@ -216,7 +279,19 @@ public class CppTypes {
     }
 
     public String nodeType() {
-        return "nsIContent**";
+        return "nsIContentHandle*";
+    }
+
+    public String htmlCreatorType() {
+        return "mozilla::dom::HTMLContentCreatorFunction";
+    }
+
+    public String svgCreatorType() {
+        return "mozilla::dom::SVGContentCreatorFunction";
+    }
+
+    public String creatorType() {
+        return "nsHtml5ContentCreatorFunction";
     }
 
     public String xhtmlNamespaceLiteral() {
@@ -262,14 +337,14 @@ public class CppTypes {
             atomMap.put(literal, atom);
             if (atomWriter != null) {
                 try {
-                    atomWriter.write("HTML5_ATOM(" + atom + ", \"" + literal
-                            + "\")\n");
+                    atomWriter.write("    # ATOM GENERATED BY HTML PARSER TRANSLATOR (WILL BE AUTOMATICALLY OVERWRITTEN):\n    Atom(\"" + atom + "\", \"" + literal
+                            + "\"),\n");
                 } catch (IOException e) {
                     throw new RuntimeException(e);
                 }
             }
         }
-        return "nsHtml5Atoms::" + atom;
+        return "nsGkAtoms::" + atom;
     }
 
     private String createAtomName(String literal) {
@@ -291,7 +366,7 @@ public class CppTypes {
     public String staticArrayTemplate() {
         return "staticJArray";
     }
-    
+
     public String newArrayCreator() {
         return "newJArray";
     }
@@ -299,6 +374,10 @@ public class CppTypes {
     public String[] boilerplateIncludes(String javaClass) {
         if ("TreeBuilder".equals(javaClass)) {
             return TREE_BUILDER_INCLUDES;
+        } else if ("Tokenizer".equals(javaClass)) {
+            return TOKENIZER_INCLUDES;
+        } else if ("StackNode".equals(javaClass)) {
+            return STACK_NODE_INCLUDES;
         } else {
             return INCLUDES;
         }
@@ -319,6 +398,17 @@ public class CppTypes {
     public String[] boilerplateForwardDeclarations() {
         return FORWARD_DECLARATIONS;
     }
+    
+    public boolean requiresTemplateParameter(String methodName) {
+        return "stateLoop".equals(methodName)
+                || "adjustDoubleHyphenAndAppendToStrBufCarriageReturn".equals(
+                        methodName)
+                || "adjustDoubleHyphenAndAppendToStrBufLineFeed".equals(
+                        methodName)
+                || "appendStrBufLineFeed".equals(methodName)
+                || "appendStrBufCarriageReturn".equals(methodName)
+                || "emitCarriageReturn".equals(methodName);
+    }
 
     public String documentModeHandlerType() {
         return "nsHtml5TreeBuilder*";
@@ -333,14 +423,14 @@ public class CppTypes {
     }
 
     public String maxInteger() {
-        return "PR_INT32_MAX";
+        return "INT32_MAX";
     }
 
     public String constructorBoilerplate(String className) {
         return "MOZ_COUNT_CTOR(" + className + ");";
     }
 
-    public String destructorBoilderplate(String className) {
+    public String destructorBoilerplate(String className) {
         return "MOZ_COUNT_DTOR(" + className + ");";
     }
 
@@ -365,15 +455,11 @@ public class CppTypes {
     }
 
     public String arrayLengthMacro() {
-        return "NS_ARRAY_LENGTH";
+        return "std::size";
     }
 
     public String staticAssert() {
-        return "PR_STATIC_ASSERT";
-    }
-
-    public String abortIfFalse() {
-        return "NS_ABORT_IF_FALSE";
+        return "static_assert";
     }
 
     public String continueMacro() {
@@ -391,4 +477,68 @@ public class CppTypes {
     public String characterNameTypeDeclaration() {
         return "nsHtml5CharacterName";
     }
+
+    public String transition() {
+        return "P::transition";
+    }
+
+    public String checkChar() {
+        return "P::checkChar";
+    }
+
+    public String silentLineFeed() {
+        return "P::silentLineFeed";
+    }
+    
+    public String silentCarriageReturn() {
+        return "P::silentCarriageReturn";
+    }
+    
+    public String tokenizerErrorCondition() {
+        return "P::reportErrors";
+    }
+
+    public String firstTransitionArg() {
+        return "mViewSource.get()";
+    }
+
+    public String errorHandler() {
+        return this.unlikely() + "(mViewSource)";
+    }
+
+    public String unlikely() {
+        return "MOZ_UNLIKELY";
+    }
+
+    public String completedCharacterReference() {
+        return "P::completedNamedCharacterReference(mViewSource.get())";
+    }
+
+    public String[] stateLoopPolicies() {
+        return STATE_LOOP_POLICIES;
+    }
+
+    public String releaseIfNonNull() {
+        return "NS_IF_RELEASE";
+    }
+
+    public String addrefIfNonNull() {
+        return "NS_IF_ADDREF";
+    }
+
+    public String assertionMacro() {
+        return "MOZ_ASSERT";
+    }
+
+    public String releaseAssertionMacro() {
+        return "MOZ_RELEASE_ASSERT";
+    }
+
+    public String crashMacro() {
+        return "MOZ_CRASH";
+    }
+    
+    public String loopPolicyInclude() {
+     return "nsHtml5TokenizerLoopPolicies";
+    }
 }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/CppVisitor.java	2025-09-16 08:29:41.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Júlio Vilmar Gesser.
  * Copyright (C) 2008 Mozilla Foundation
- * 
+ *
  * This file is part of HTML Parser C++ Translator. It was derived from DumpVisitor
  * which was part of Java 1.5 parser and Abstract Syntax Tree and came with the following notice:
  *
@@ -23,6 +23,13 @@
  */
 package nu.validator.htmlparser.cpptranslate;
 
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
 import japa.parser.ast.BlockComment;
 import japa.parser.ast.CompilationUnit;
 import japa.parser.ast.ImportDeclaration;
@@ -110,13 +117,6 @@ import japa.parser.ast.type.Type;
 import japa.parser.ast.type.VoidType;
 import japa.parser.ast.type.WildcardType;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
 /**
  * @author Julio Vilmar Gesser
  * @author Henri Sivonen
@@ -125,10 +125,13 @@ import java.util.Set;
 public class CppVisitor extends AnnotationHelperVisitor<LocalSymbolTable> {
 
     private static final String[] CLASS_NAMES = { "AttributeName",
-            "ElementName", "HtmlAttributes", "LocatorImpl", "MetaScanner",
+            "ElementName", "HtmlAttributes", "LocatorImpl",
             "NamedCharacters", "NamedCharactersAccel", "Portability",
             "StackNode", "Tokenizer", "TreeBuilder", "UTF16Buffer" };
 
+    private static final String[] METHODS_WITH_UNLIKELY_CONDITIONS = {
+            "appendStrBuf" };
+
     public class SourcePrinter {
 
         private int level = 0;
@@ -151,6 +154,11 @@ public class CppVisitor extends Annotati
             }
         }
 
+        public void printWithoutIndent(String arg) {
+            indented = false;
+            buf.append(arg);
+        }
+
         public void print(String arg) {
             if (!indented) {
                 makeIndent();
@@ -178,14 +186,7 @@ public class CppVisitor extends Annotati
         }
     }
 
-    private boolean skipRestOfStatementsInBlock = false;
-    
-    private String currentTokenizerState = null;
-    
-    private boolean inTokenizerLoop() {
-        return "stateLoop".equals(currentMethod)
-                && "Tokenizer".equals(javaClassName);
-    }
+    private boolean supportErrorReporting = true;
 
     protected SourcePrinter printer = new SourcePrinter();
 
@@ -203,6 +204,10 @@ public class CppVisitor extends Annotati
 
     protected boolean inPrimitiveNoLengthFieldDeclarator = false;
 
+    protected boolean inField = false;
+
+    protected boolean inArray = false;
+
     protected final SymbolTable symbolTable;
 
     protected String definePrefix;
@@ -220,9 +225,13 @@ public class CppVisitor extends Annotati
     private Set<String> labels = null;
 
     private boolean destructor;
-    
+
     protected boolean inStatic = false;
 
+    private boolean reportTransitions = false;
+
+    private int stateLoopCallCount = 0;
+
     /**
      * @param cppTypes
      */
@@ -253,7 +262,13 @@ public class CppVisitor extends Annotati
     private void printMembers(List<BodyDeclaration> members,
             LocalSymbolTable arg) {
         for (BodyDeclaration member : members) {
+            if ("Tokenizer".equals(javaClassName)
+                    && member instanceof MethodDeclaration
+                    && "stateLoop".equals(((MethodDeclaration) member).getName())) {
+                reportTransitions = true;
+            }
             member.accept(this, arg);
+            reportTransitions = false;
         }
     }
 
@@ -317,14 +332,12 @@ public class CppVisitor extends Annotati
             printer.print(cppTypes.localForLiteral("html"));
         } else if ("documentModeHandler".equals(n.getName())) {
             printer.print("this");
+        } else if ("errorHandler".equals(n.getName())) {
+            printer.print(cppTypes.errorHandler());
+        } else if ("MOZ_FALLTHROUGH".equals(n.getName())) {
+            printer.print("[[fallthrough]]");
         } else {
-            String prefixedName = javaClassName + "." + n.getName();
-            String constant = symbolTable.cppDefinesByJavaNames.get(prefixedName);
-            if (constant != null) {
-                printer.print(constant);
-            } else {
-                printer.print(n.getName());
-            }
+            printer.print(n.getName());
         }
     }
 
@@ -411,16 +424,6 @@ public class CppVisitor extends Annotati
         printer.printLn("_cpp__");
         printer.printLn();
 
-        String[] incs = cppTypes.boilerplateIncludes(javaClassName);
-        for (int i = 0; i < incs.length; i++) {
-            String inc = incs[i];
-            printer.print("#include \"");
-            printer.print(inc);
-            printer.printLn(".h\"");
-        }
-
-        printer.printLn();
-
         for (int i = 0; i < Main.H_LIST.length; i++) {
             String klazz = Main.H_LIST[i];
             if (!klazz.equals(javaClassName)) {
@@ -435,15 +438,17 @@ public class CppVisitor extends Annotati
         printer.print("#include \"");
         printer.print(className);
         printer.printLn(".h\"");
-        if ("AttributeName".equals(javaClassName)
-                || "ElementName".equals(javaClassName)) {
-            printer.print("#include \"");
-            printer.print(cppTypes.classPrefix());
-            printer.print("Releasable");
-            printer.print(javaClassName);
-            printer.printLn(".h\"");
-        }
         printer.printLn();
+        
+        if ("Tokenizer".equals(javaClassName)) {
+            String loopPolicyInclude = cppTypes.loopPolicyInclude();
+            if (loopPolicyInclude != null) {
+                printer.print("#include \"");
+                printer.print(loopPolicyInclude);
+                printer.printLn(".h\"");
+                printer.printLn();                
+            }
+        }
     }
 
     public void visit(EmptyTypeDeclaration n, LocalSymbolTable arg) {
@@ -467,8 +472,12 @@ public class CppVisitor extends Annotati
         }
         String name = n.getName();
         if ("String".equals(name)) {
-            if (local()) {
-                name = cppTypes.localType();
+            if (weakLocal()) {
+                name = cppTypes.weakLocalType();
+            } else if (staticLocal()) {
+                name = cppTypes.staticLocalType();
+            } else if (local()) {
+                name = inField || inArray ? cppTypes.localType() : cppTypes.weakLocalType();
             } else if (prefix()) {
                 name = cppTypes.prefixType();
             } else if (nsUri()) {
@@ -481,7 +490,15 @@ public class CppVisitor extends Annotati
                 name = cppTypes.stringType();
             }
         } else if ("T".equals(name) || "Object".equals(name)) {
-            name = cppTypes.nodeType();
+            if (htmlCreator()) {
+                name = cppTypes.htmlCreatorType();
+            } else if (svgCreator()) {
+                name = cppTypes.svgCreatorType();
+            } else if (creator()) {
+                name = cppTypes.creatorType();
+            } else {
+                name = cppTypes.nodeType();
+            }
         } else if ("TokenHandler".equals(name)) {
             name = cppTypes.classPrefix() + "TreeBuilder*";
         } else if ("EncodingDeclarationHandler".equals(name)) {
@@ -535,7 +552,11 @@ public class CppVisitor extends Annotati
             case Float:
                 throw new IllegalStateException("Unsupported primitive.");
             case Int:
-                printer.print(cppTypes.intType());
+                if (unsigned()) {
+                    printer.print(cppTypes.unsignedIntType());
+                } else {
+                    printer.print(cppTypes.intType());
+                }
                 break;
             case Long:
                 throw new IllegalStateException("Unsupported primitive.");
@@ -548,17 +569,32 @@ public class CppVisitor extends Annotati
         if (isConst()) {
             printer.print("const ");
         }
+        boolean wasInArray = inArray;
+        if (n.getArrayCount() > 0) {
+            inArray = true;
+        }
         if (noLength()) {
+            final int inlineLength = inlineLength();
+            if (inlineLength > 0) {
+                printer.print("jInlineArray<");
+            }
             n.getType().accept(this, arg);
-            for (int i = 0; i < n.getArrayCount(); i++) {
-                if (!inPrimitiveNoLengthFieldDeclarator) {
+            if (!inPrimitiveNoLengthFieldDeclarator) {
+                int count = n.getArrayCount();
+                if (inlineLength > 0) {
+                    count -= 1;
+                }
+                for (int i = 0; i < count; i++) {
                     printer.print("*");
                 }
             }
+            if (inlineLength > 0) {
+                printer.print(", " + inlineLength + ">");
+            }
         } else {
             for (int i = 0; i < n.getArrayCount(); i++) {
                 if (inStatic) {
-                    printer.print(cppTypes.staticArrayTemplate());                    
+                    printer.print(cppTypes.staticArrayTemplate());
                 } else {
                     if (auto()) {
                         printer.print(cppTypes.autoArrayTemplate());
@@ -570,11 +606,14 @@ public class CppVisitor extends Annotati
             }
             n.getType().accept(this, arg);
             for (int i = 0; i < n.getArrayCount(); i++) {
-                printer.print(",");
+                printer.print(", ");
                 printer.print(cppTypes.intType());
                 printer.print(">");
             }
         }
+        if (n.getArrayCount() > 0) {
+            inArray = wasInArray;
+        }
     }
 
     public void visit(WildcardType n, LocalSymbolTable arg) {
@@ -605,6 +644,7 @@ public class CppVisitor extends Annotati
     }
 
     protected void fieldDeclaration(FieldDeclaration n, LocalSymbolTable arg) {
+        inField = true;
         tempPrinterHolder = printer;
         printer = staticInitializerPrinter;
         int modifiers = n.getModifiers();
@@ -631,10 +671,10 @@ public class CppVisitor extends Annotati
                             printer.print("::");
                             declarator.getId().accept(this, arg);
 
-                            printer.print(" = ");                    
-                            
+                            printer.print(" = ");
+
                             declarator.getInit().accept(this, arg);
-                           
+
                             printer.printLn(";");
                             printer = staticInitializerPrinter;
                         } else {
@@ -647,7 +687,7 @@ public class CppVisitor extends Annotati
 
                             printer.printLn(" = 0;");
                             printer = staticInitializerPrinter;
-                            
+
                             staticReleases.add("delete[] "
                                     + declarator.getId().getName());
 
@@ -673,13 +713,13 @@ public class CppVisitor extends Annotati
                         declarator.getId().accept(this, arg);
                         printer.print("_DATA[] = ");
                         declarator.getInit().accept(this, arg);
-                        printer.printLn(";");                        
+                        printer.printLn(";");
                         printer.print(cppTypes.staticArrayTemplate());
                         printer.print("<");
                         suppressPointer = true;
                         rt.getType().accept(this, arg);
                         suppressPointer = false;
-                        printer.print(",");
+                        printer.print(", ");
                         printer.print(cppTypes.intType());
                         printer.print("> ");
                         printer.print(className);
@@ -706,7 +746,7 @@ public class CppVisitor extends Annotati
                             suppressPointer = true;
                             rt.getType().accept(this, arg);
                             suppressPointer = false;
-                            printer.print(",");
+                            printer.print(", ");
                             printer.print(cppTypes.intType());
                             printer.print(">::");
                             printer.print(cppTypes.newArrayCreator());
@@ -727,10 +767,14 @@ public class CppVisitor extends Annotati
                         printer.print(" ");
                         printer.print(className);
                         printer.print("::");
-                        if ("AttributeName".equals(n.getType().toString())) {
-                            printer.print("ATTR_");
-                        } else if ("ElementName".equals(n.getType().toString())) {
-                            printer.print("ELT_");
+                        String clazzName = n.getType().toString();
+                        String field = declarator.getId().toString();
+                        if (symbolTable.isAttributeOrElementName(clazzName, field)) {
+                            if ("AttributeName".equals(clazzName)) {
+                                printer.print("ATTR_");
+                            } else if ("ElementName".equals(clazzName)) {
+                                printer.print("ELT_");
+                            }
                         }
                         declarator.getId().accept(this, arg);
                         printer.print(" = ");
@@ -738,7 +782,7 @@ public class CppVisitor extends Annotati
                         printer.printLn(";");
                         printer = staticInitializerPrinter;
                     }
-                    
+
                     if ("AttributeName".equals(n.getType().toString())) {
                         printer.print("ATTR_");
                         staticReleases.add("delete ATTR_"
@@ -762,6 +806,7 @@ public class CppVisitor extends Annotati
         currentArrayCount = 0;
         printer = tempPrinterHolder;
         inPrimitiveNoLengthFieldDeclarator = false;
+        inField = false;
     }
 
     private void printArrayInit(VariableDeclaratorId variableDeclaratorId,
@@ -839,6 +884,7 @@ public class CppVisitor extends Annotati
         // n.getType().accept(this, arg);
         // printTypeArgs(n.getTypeArgs(), arg);
 
+        inArray = true;
         if (n.getDimensions() != null) {
             if (noLength()) {
                 for (Expression dim : n.getDimensions()) {
@@ -853,7 +899,7 @@ public class CppVisitor extends Annotati
                     printer.print(cppTypes.arrayTemplate());
                     printer.print("<");
                     n.getType().accept(this, arg);
-                    printer.print(",");
+                    printer.print(", ");
                     printer.print(cppTypes.intType());
                     printer.print(">::");
                     printer.print(cppTypes.newArrayCreator());
@@ -872,6 +918,7 @@ public class CppVisitor extends Annotati
                     "Array initializer as part of array creation not supported. "
                             + n.toString());
         }
+        inArray = false;
     }
 
     public void visit(AssignExpr n, LocalSymbolTable arg) {
@@ -1066,26 +1113,22 @@ public class CppVisitor extends Annotati
                 if ("DocumentMode".equals(scope.toString())) {
                     // printer.print(cppTypes.documentModeType());
                     // printer.print(".");
+                } else if ("creator".equals(scope.toString()) || "this.creator".equals(scope.toString())) {
+                    scope.accept(this, arg);
+                    printer.print(".");
                 } else {
                     scope.accept(this, arg);
                     printer.print("->");
                 }
             } else {
-                String prefixedName = clazzName + "." + field;
-                String constant = symbolTable.cppDefinesByJavaNames.get(prefixedName);
-                if (constant != null) {
-                    printer.print(constant);
-                    return;
-                } else {
-                    printer.print(cppTypes.classPrefix());
-                    printer.print(clazzName);
-                    printer.print("::");
-                    if (symbolTable.isNotAnAttributeOrElementName(field)) {
-                        if ("AttributeName".equals(clazzName)) {
-                            printer.print("ATTR_");
-                        } else if ("ElementName".equals(clazzName)) {
-                            printer.print("ELT_");
-                        }
+                printer.print(cppTypes.classPrefix());
+                printer.print(clazzName);
+                printer.print("::");
+                if (symbolTable.isAttributeOrElementName(clazzName, field)) {
+                    if ("AttributeName".equals(clazzName)) {
+                        printer.print("ATTR_");
+                    } else if ("ElementName".equals(clazzName)) {
+                        printer.print("ELT_");
                     }
                 }
             }
@@ -1244,6 +1287,22 @@ public class CppVisitor extends Annotati
                 && "Portability".equals(n.getScope().toString())) {
             n.getArgs().get(0).accept(this, arg);
             printer.print(".release()");
+        } else if ("releaseString".equals(n.getName())
+                && "Portability".equals(n.getScope().toString())) {
+            n.getArgs().get(0).accept(this, arg);
+            printer.print(".Release()");
+        } else if ("addrefIfNonNull".equals(n.getName())
+                && "Portability".equals(n.getScope().toString())) {
+            printer.print(cppTypes.addrefIfNonNull());
+            printer.print("(");
+            n.getArgs().get(0).accept(this, arg);
+            printer.print(")");
+        } else if ("releaseIfNonNull".equals(n.getName())
+                && "Portability".equals(n.getScope().toString())) {
+            printer.print(cppTypes.releaseIfNonNull());
+            printer.print("(");
+            n.getArgs().get(0).accept(this, arg);
+            printer.print(")");
         } else if ("deleteArray".equals(n.getName())
                 && "Portability".equals(n.getScope().toString())) {
             printer.print("delete[] ");
@@ -1258,6 +1317,15 @@ public class CppVisitor extends Annotati
         } else if ("transition".equals(n.getName())
                 && n.getScope() == null) {
             visitTransition(n, arg);
+        } else if ("checkChar".equals(n.getName())
+                && n.getScope() == null) {
+            visitCheckChar(n, arg);
+        } else if ("silentCarriageReturn".equals(n.getName())
+                && n.getScope() == null) {
+            visitSilentCarriageReturn(n, arg);
+        } else if ("silentLineFeed".equals(n.getName())
+                && n.getScope() == null) {
+            visitSilentLineFeed(n, arg);
         } else if ("arraycopy".equals(n.getName())
                 && "System".equals(n.getScope().toString())) {
             printer.print(cppTypes.arrayCopy());
@@ -1320,7 +1388,8 @@ public class CppVisitor extends Annotati
                     if (clazzName == null) {
                         scope.accept(this, arg);
                         if ("length".equals(n.getName())
-                                || "charAt".equals(n.getName())) {
+                                || "charAt".equals(n.getName())
+                                || "creator".equals(scope.toString())) {
                             printer.print(".");
                         } else {
                             printer.print("->");
@@ -1334,6 +1403,18 @@ public class CppVisitor extends Annotati
             }
             printTypeArgs(n.getTypeArgs(), arg);
             printer.print(n.getName());
+            if ("stateLoop".equals(n.getName())
+                    && "Tokenizer".equals(javaClassName)
+                    && cppTypes.stateLoopPolicies().length > 0) {
+                printer.print("<");
+                printer.print(cppTypes.stateLoopPolicies()[stateLoopCallCount]);
+                printer.print(">");
+                stateLoopCallCount++;
+            } else if (cppTypes.requiresTemplateParameter(n.getName())
+                    && "Tokenizer".equals(javaClassName)
+                    && cppTypes.stateLoopPolicies().length > 0) {
+                printer.print("<P>");                
+            }
             printer.print("(");
             if (n.getArgs() != null) {
                 for (Iterator<Expression> i = n.getArgs().iterator(); i.hasNext();) {
@@ -1358,20 +1439,16 @@ public class CppVisitor extends Annotati
 
         suppressPointer = true;
         printTypeArgs(n.getTypeArgs(), arg);
-        if ("createAttributeName".equals(currentMethod)
-                || "elementNameByBuffer".equals(currentMethod)) {
-            printer.print(cppTypes.classPrefix());
-            printer.print("Releasable");
-            printer.print(n.getType().getName());
-        } else {
-            n.getType().accept(this, arg);
-        }
+        n.getType().accept(this, arg);
         suppressPointer = false;
 
         if ("AttributeName".equals(n.getType().getName())) {
             List<Expression> args = n.getArgs();
-            while (args.size() > 3) {
-                args.remove(3);
+            if (args != null) {
+                assert args.size() == 7;
+                // Remove flags, and htmlLang from AttributeName constructor.
+                args.remove(6);
+                args.remove(4);
             }
         }
 
@@ -1445,6 +1522,7 @@ public class CppVisitor extends Annotati
         printModifiers(n.getModifiers());
 
         printMethodNamespace();
+        printConstructorExplicit(n.getParameters());
         printer.print(className);
         currentAnnotations = null;
 
@@ -1463,6 +1541,21 @@ public class CppVisitor extends Annotati
         printConstructorBody(n.getBlock(), arg);
     }
 
+    protected void printConstructorExplicit(List<Parameter> params) {
+    }
+
+    protected boolean isMemberAssignment(Statement statement) {
+        if (!(statement instanceof ExpressionStmt)) {
+            return false;
+        }
+        Expression expr = ((ExpressionStmt) statement).getExpression();
+        if (!(expr instanceof AssignExpr)) {
+            return false;
+        }
+        Expression target = ((AssignExpr)expr).getTarget();
+        return target instanceof FieldAccessExpr;
+    }
+
     protected void printConstructorBody(BlockStmt block, LocalSymbolTable arg) {
         inConstructorBody = true;
         List<Statement> statements = block.getStmts();
@@ -1470,17 +1563,16 @@ public class CppVisitor extends Annotati
         int i = 0;
         boolean needOutdent = false;
         for (Statement statement : statements) {
-            if (statement instanceof ExpressionStmt
-                    && ((ExpressionStmt) statement).getExpression() instanceof AssignExpr) {
+            if (isMemberAssignment(statement)) {
+                printer.printLn();
                 if (i == 0) {
-                    printer.printLn();
+                    // : firstMember(arg)
                     printer.indent();
                     printer.print(": ");
                     needOutdent = true;
                 } else {
-                    printer.print(",");
-                    printer.printLn();
-                    printer.print("  ");
+                    // , secondMember(arg)
+                    printer.print(", ");
                 }
                 statement.accept(this, arg);
                 i++;
@@ -1529,6 +1621,7 @@ public class CppVisitor extends Annotati
                 || n.getName().startsWith("maybeWarn")
                 || n.getName().startsWith("note")
                 || "releaseArray".equals(n.getName())
+                || "releaseString".equals(n.getName())
                 || "deleteArray".equals(n.getName())
                 || "delete".equals(n.getName())) {
             return;
@@ -1536,7 +1629,7 @@ public class CppVisitor extends Annotati
 
         currentMethod = n.getName();
 
-        destructor = "destructor".equals(n.getName());
+        destructor = "destructor".equals(currentMethod);
 
         // if (n.getJavaDoc() != null) {
         // n.getJavaDoc().accept(this, arg);
@@ -1553,6 +1646,17 @@ public class CppVisitor extends Annotati
             printModifiers(n.getModifiers());
         }
 
+        if (cppTypes.requiresTemplateParameter(currentMethod)
+                && "Tokenizer".equals(javaClassName)
+                && cppTypes.stateLoopPolicies().length > 0) {
+            printer.print("template<class P>");
+            if (inHeader()) {
+                printer.print(" ");
+            } else {
+                printer.printLn();
+            }
+        }
+
         printTypeParameters(n.getTypeParameters(), arg);
         if (n.getTypeParameters() != null) {
             printer.print(" ");
@@ -1569,7 +1673,6 @@ public class CppVisitor extends Annotati
             printer.print(n.getName());
         }
 
-        currentAnnotations = null;
         printer.print("(");
         if (n.getParameters() != null) {
             for (Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext();) {
@@ -1586,6 +1689,12 @@ public class CppVisitor extends Annotati
             printer.print("[]");
         }
 
+        if (override() && inHeader()) {
+            printer.print(" override");
+        }
+
+        currentAnnotations = null;
+
         if (inHeader() == isInline) {
             printMethodBody(n.getBody(), arg);
         } else {
@@ -1601,7 +1710,7 @@ public class CppVisitor extends Annotati
             printer.printLn("{");
             printer.indent();
             if (destructor) {
-                String boilerplate = cppTypes.destructorBoilderplate(className);
+                String boilerplate = cppTypes.destructorBoilerplate(className);
                 if (boilerplate != null) {
                     printer.printLn(boilerplate);
                 }
@@ -1689,6 +1798,55 @@ public class CppVisitor extends Annotati
     }
 
     public void visit(AssertStmt n, LocalSymbolTable arg) {
+        String message = null;
+        Expression msg = n.getMessage();
+        boolean hasCheck = true;
+        if (msg != null) {
+            if (msg instanceof StringLiteralExpr) {
+                StringLiteralExpr sle = (StringLiteralExpr) msg;
+                message = sle.getValue();
+            } else {
+                throw new RuntimeException("Bad assertion message.");
+            }
+        }
+        String macro = cppTypes.assertionMacro();
+        if (message != null && message.startsWith("RELEASE: ")) {
+            message = message.substring("RELEASE: ".length());
+            macro = cppTypes.releaseAssertionMacro();
+            Expression check = n.getCheck();
+            if (check instanceof BooleanLiteralExpr) {
+                BooleanLiteralExpr expr = (BooleanLiteralExpr) check;
+                if (!expr.getValue()) {
+                    hasCheck = false;
+                    macro = cppTypes.crashMacro();
+                }
+            }
+        }
+        if (macro != null) {
+            printer.print(macro);
+            printer.print("(");
+            if (hasCheck) {
+                n.getCheck().accept(this, arg);
+            }
+            if (message != null) {
+                if (hasCheck) {
+                    printer.print(", ");
+                }
+                printer.print("\"");
+                for (int i = 0; i < message.length(); i++) {
+                    char c = message.charAt(i);
+                    if (c == '"') {
+                        printer.print("\"");
+                    } else if (c >= ' ' && c <= '~') {
+                        printer.print("" + c);
+                    } else {
+                        throw new RuntimeException("Bad assertion message string.");
+                    }
+                }
+                printer.print("\"");
+            }
+            printer.print(");");
+        }
     }
 
     public void visit(BlockStmt n, LocalSymbolTable arg) {
@@ -1722,15 +1880,19 @@ public class CppVisitor extends Annotati
         }
         String label = n.getLabel();
         if (labels.contains(label)) {
+            printer.unindent();
             printer.print(label);
-            printer.print(": ");
+            printer.indent();
+            printer.printLn(":");
         }
         stmt.accept(this, arg);
         printer.printLn();
         label += "_end";
         if (labels.contains(label)) {
+            printer.unindent();
             printer.print(label);
-            printer.print(": ;");
+            printer.indent();
+            printer.print(":;");
         }
     }
 
@@ -1740,27 +1902,116 @@ public class CppVisitor extends Annotati
 
     public void visit(ExpressionStmt n, LocalSymbolTable arg) {
         Expression e = n.getExpression();
-        if (isDroppedExpression(e)) {
+        if (isCompletedCharacterReference(e)) {
+            printer.print(cppTypes.completedCharacterReference());
+            printer.print(";");
+            return;
+        }
+        boolean needsCondition = isTokenizerErrorReportingExpression(e);
+        if (!needsCondition && isDroppedExpression(e)) {
             return;
         }
+        if (needsCondition) {
+            printer.print("if (");
+            printer.print(cppTypes.tokenizerErrorCondition());
+            printer.printLn(") {");
+            printer.indent();
+        }
         e.accept(this, arg);
         if (!inConstructorBody) {
             printer.print(";");
         }
+        if (needsCondition) {
+            printer.printLn();
+            printer.unindent();
+            printer.print("}");
+        }
     }
 
     private void visitTransition(MethodCallExpr call, LocalSymbolTable arg) {
         List<Expression> args = call.getArgs();
+        if (reportTransitions) {
+            printer.print(cppTypes.transition());
+            printer.print("(");
+            printer.print(cppTypes.firstTransitionArg());
+            printer.print(", ");
+            args.get(1).accept(this, arg);
+            printer.print(", ");
+            args.get(2).accept(this, arg);
+            printer.print(", ");
+            args.get(3).accept(this, arg);
+            printer.print(")");
+        } else {
+            args.get(1).accept(this, arg);
+        }
+    }
+
+    private void visitCheckChar(MethodCallExpr call, LocalSymbolTable arg) {
+        List<Expression> args = call.getArgs();
+        printer.print(cppTypes.checkChar());
+        printer.print("(this, ");
+        args.get(0).accept(this, arg);
+        printer.print(", ");
         args.get(1).accept(this, arg);
+        printer.print(")");
+    }
+
+    private void visitSilentLineFeed(MethodCallExpr call, LocalSymbolTable arg) {
+        printer.print(cppTypes.silentLineFeed());
+        printer.print("(this)");
+    }
+
+    private void visitSilentCarriageReturn(MethodCallExpr call, LocalSymbolTable arg) {
+        printer.print(cppTypes.silentCarriageReturn());
+        printer.print("(this)");
+    }
+    
+    private boolean isTokenizerErrorReportingExpression(Expression e) {
+        if (!reportTransitions) {
+            return false;
+        }
+        if (e instanceof MethodCallExpr) {
+            MethodCallExpr methodCallExpr = (MethodCallExpr) e;
+            String name = methodCallExpr.getName();
+            if (supportErrorReporting && !name.startsWith("errHtml4")
+                    && ("stateLoop".equals(currentMethod))
+                    && (name.startsWith("err") || name.startsWith("maybeErr"))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isCompletedCharacterReference(Expression e) {
+        if (!reportTransitions) {
+            return false;
+        }
+        if (e instanceof MethodCallExpr) {
+            MethodCallExpr methodCallExpr = (MethodCallExpr) e;
+            String name = methodCallExpr.getName();
+            if (name.equals("completedNamedCharacterReference")) {
+                return true;
+            }
+        }
+        return false;
     }
 
     private boolean isDroppedExpression(Expression e) {
         if (e instanceof MethodCallExpr) {
             MethodCallExpr methodCallExpr = (MethodCallExpr) e;
             String name = methodCallExpr.getName();
-            if (name.startsWith("fatal") || name.startsWith("err")
-                    || name.startsWith("warn") || name.startsWith("maybeErr")
-                    || name.startsWith("maybeWarn") || name.startsWith("note")) {
+            if (name.startsWith("fatal") || name.startsWith("note")
+                    || name.startsWith("errHtml4") || name.startsWith("warn")
+                    || name.startsWith("maybeWarn")) {
+                return true;
+            }
+            if (supportErrorReporting
+                    && ("stateLoop".equals(currentMethod) && !reportTransitions)
+                    && (name.startsWith("err") || name.startsWith("maybeErr"))) {
+                return true;
+            }
+            if (name.equals("completedNamedCharacterReference")
+                    && !reportTransitions) {
                 return true;
             }
         }
@@ -1768,7 +2019,7 @@ public class CppVisitor extends Annotati
     }
 
     public void visit(SwitchStmt n, LocalSymbolTable arg) {
-        printer.print("switch(");
+        printer.print("switch (");
         n.getSelector().accept(this, arg);
         printer.printLn(") {");
         if (n.getEntries() != null) {
@@ -1961,10 +2212,23 @@ public class CppVisitor extends Annotati
     }
 
     public void visit(IfStmt n, LocalSymbolTable arg) {
-        if (!isErrorHandlerIf(n.getCondition())) {
-            if (isErrorOnlyBlock(n.getThenStmt())) {
+        if (TranslatorUtils.isDocumentModeHandlerNullCheck(n.getCondition())) {
+            Statement then = n.getThenStmt();
+            if (then instanceof BlockStmt) {
+                BlockStmt block = (BlockStmt) then;
+                List<Statement> statements = block.getStmts();
+                if (statements != null && statements.size() == 1) {
+                    statements.get(0).accept(this, arg);
+                } else {
+                    then.accept(this, arg);
+                }
+            } else {
+                then.accept(this, arg);
+            }
+        } else if (!TranslatorUtils.isErrorHandlerIf(n.getCondition(), supportErrorReporting)) {
+            if (TranslatorUtils.isErrorOnlyBlock(n.getThenStmt(), supportErrorReporting)) {
                 if (n.getElseStmt() != null
-                        && !isErrorOnlyBlock(n.getElseStmt())) {
+                        && !TranslatorUtils.isErrorOnlyBlock(n.getElseStmt(), supportErrorReporting)) {
                     printer.print("if (");
                     if (n.getCondition() instanceof BinaryExpr) {
                         BinaryExpr binExpr = (BinaryExpr) n.getCondition();
@@ -1994,19 +2258,30 @@ public class CppVisitor extends Annotati
                     n.getElseStmt().accept(this, arg);
                 }
             } else {
+                boolean unlikely = (currentMethod != null)
+                        && (Arrays.binarySearch(
+                                METHODS_WITH_UNLIKELY_CONDITIONS,
+                                currentMethod) >= 0);
                 printer.print("if (");
+                if (unlikely) {
+                    printer.print(cppTypes.unlikely());
+                    printer.print("(");
+                }
                 formatCondition(n.getCondition(), arg);
+                if (unlikely) {
+                    printer.print(")");
+                }
                 printer.print(") ");
                 n.getThenStmt().accept(this, arg);
                 if (n.getElseStmt() != null
-                        && !isErrorOnlyBlock(n.getElseStmt())) {
+                        && !TranslatorUtils.isErrorOnlyBlock(n.getElseStmt(), supportErrorReporting)) {
                     printer.print(" else ");
                     n.getElseStmt().accept(this, arg);
                 }
             }
         }
     }
-    
+
     private void formatCondition(Expression expr, LocalSymbolTable arg) {
         if (expr instanceof BinaryExpr) {
             BinaryExpr binExpr = (BinaryExpr) expr;
@@ -2024,34 +2299,6 @@ public class CppVisitor extends Annotati
         expr.accept(this, arg);
     }
 
-    private boolean isErrorOnlyBlock(Statement elseStmt) {
-        if (elseStmt instanceof BlockStmt) {
-            BlockStmt block = (BlockStmt) elseStmt;
-            List<Statement> statements = block.getStmts();
-            if (statements == null) {
-                return false;
-            }
-            if (statements.size() != 1) {
-                return false;
-            }
-            Statement statement = statements.get(0);
-            if (statement instanceof ExpressionStmt) {
-                ExpressionStmt exprStmt = (ExpressionStmt) statement;
-                Expression expr = exprStmt.getExpression();
-                if (expr instanceof MethodCallExpr) {
-                    MethodCallExpr call = (MethodCallExpr) expr;
-                    if (call.getName().startsWith("err")) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean isErrorHandlerIf(Expression condition) {
-        return condition.toString().indexOf("errorHandler") != -1;
-    }
 
     public void visit(WhileStmt n, LocalSymbolTable arg) {
         printer.print("while (");
@@ -2108,12 +2355,14 @@ public class CppVisitor extends Annotati
                 }
             }
         }
-        printer.print("; ");
+        printer.print(";");
         if (n.getCompare() != null) {
+            printer.print(" ");
             n.getCompare().accept(this, arg);
         }
-        printer.print("; ");
+        printer.print(";");
         if (n.getUpdate() != null) {
+            printer.print(" ");
             for (Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext();) {
                 Expression e = i.next();
                 e.accept(this, arg);
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/GkAtomParser.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/GkAtomParser.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/GkAtomParser.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/GkAtomParser.java	2025-09-16 08:29:41.000000000 +0000
@@ -47,7 +47,9 @@ import java.util.regex.Pattern;
 
 public class GkAtomParser {
 
-    private static final Pattern ATOM = Pattern.compile("^GK_ATOM\\(([^,]+),\\s*\"([^\"]*)\"\\).*$");
+    /* Please note we aren't looking for the following Atom definitions:
+       PseudoElementAtom or NonInheritingAnonBoxAtom or InheritingAnonBoxAtom */
+    private static final Pattern ATOM = Pattern.compile("^Atom\\(\"([^,]+)\",\\s*\"([^\"]*)\"\\).*$");
     
     private final BufferedReader reader;
     
@@ -59,7 +61,7 @@ public class GkAtomParser {
         Map<String, String> map = new HashMap<String, String>();
         String line;
         while((line = reader.readLine()) != null) {
-            Matcher m = ATOM.matcher(line);
+            Matcher m = ATOM.matcher(line.trim());
             if (m.matches()) {
                 map.put(m.group(2), m.group(1));
             }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/HVisitor.java	2025-09-16 08:29:41.000000000 +0000
@@ -37,19 +37,16 @@
 
 package nu.validator.htmlparser.cpptranslate;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import japa.parser.ast.body.FieldDeclaration;
 import japa.parser.ast.body.MethodDeclaration;
 import japa.parser.ast.body.ModifierSet;
+import japa.parser.ast.body.Parameter;
 import japa.parser.ast.body.VariableDeclarator;
-import japa.parser.ast.expr.IntegerLiteralExpr;
-import japa.parser.ast.expr.MethodCallExpr;
 import japa.parser.ast.stmt.BlockStmt;
 import japa.parser.ast.type.PrimitiveType;
 import japa.parser.ast.type.ReferenceType;
-import japa.parser.ast.type.Type;
 
 public class HVisitor extends CppVisitor {
 
@@ -59,8 +56,6 @@ public class HVisitor extends CppVisitor
 
     private Visibility previousVisibility = Visibility.NONE;
 
-    private List<String> defines = new LinkedList<String>();
-
     /**
      * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printMethodNamespace()
      */
@@ -75,15 +70,15 @@ public class HVisitor extends CppVisitor
      * @see nu.validator.htmlparser.cpptranslate.CppVisitor#startClassDeclaration()
      */
     @Override protected void startClassDeclaration() {
-        printer.print("#ifndef ");        
+        printer.print("#ifndef ");
         printer.print(className);
-        printer.printLn("_h__");
-        printer.print("#define ");        
+        printer.printLn("_h");
+        printer.print("#define ");
         printer.print(className);
-        printer.printLn("_h__");
-        
+        printer.printLn("_h");
+
         printer.printLn();
-        
+
         String[] incs = cppTypes.boilerplateIncludes(javaClassName);
         for (int i = 0; i < incs.length; i++) {
             String inc = incs[i];
@@ -102,9 +97,9 @@ public class HVisitor extends CppVisitor
             String decl = forwDecls[i];
             printer.print("class ");
             printer.print(decl);
-            printer.printLn(";");            
+            printer.printLn(";");
         }
-        
+
         printer.printLn();
 
         for (int i = 0; i < Main.H_LIST.length; i++) {
@@ -116,15 +111,15 @@ public class HVisitor extends CppVisitor
                 printer.printLn(";");
             }
         }
-        
+
         printer.printLn();
-        
+
         String[] otherDecls = cppTypes.boilerplateDeclarations(javaClassName);
         for (int i = 0; i < otherDecls.length; i++) {
             String decl = otherDecls[i];
             printer.printLn(decl);
         }
-        
+
         printer.printLn();
 
         printer.print("class ");
@@ -136,7 +131,6 @@ public class HVisitor extends CppVisitor
         printer.printLn();
         printer.printLn("{");
         printer.indent();
-        printer.indent();
     }
 
     /**
@@ -144,30 +138,22 @@ public class HVisitor extends CppVisitor
      */
     @Override protected void endClassDeclaration() {
         printModifiers(ModifierSet.PUBLIC | ModifierSet.STATIC);
-        printer.printLn("void initializeStatics();");        
+        printer.printLn("void initializeStatics();");
         printModifiers(ModifierSet.PUBLIC | ModifierSet.STATIC);
-        printer.printLn("void releaseStatics();");        
-        
-        printer.unindent();
+        printer.printLn("void releaseStatics();");
+
         printer.unindent();
-        
+
         if (cppTypes.hasSupplement(javaClassName)) {
             printer.printLn();
             printer.print("#include \"");
             printer.print(className);
             printer.printLn("HSupplement.h\"");
         }
-        
-        printer.printLn("};");
-        printer.printLn();
 
-        for (String define : defines) {
-            printer.printLn(define);
-        }
-        
-        printer.printLn();
+        printer.printLn("};");
         printer.printLn();
-        printer.printLn("#endif");
+        printer.print("#endif");
     }
 
     /**
@@ -197,10 +183,10 @@ public class HVisitor extends CppVisitor
             }
         }
         if (inline()) {
-            printer.print("inline ");            
+            printer.print("inline ");
         }
         if (virtual()) {
-            printer.print("virtual ");            
+            printer.print("virtual ");
         }
         if (ModifierSet.isStatic(modifiers)) {
             printer.print("static ");
@@ -211,6 +197,7 @@ public class HVisitor extends CppVisitor
      * @see nu.validator.htmlparser.cpptranslate.CppVisitor#fieldDeclaration(japa.parser.ast.body.FieldDeclaration, java.lang.LocalSymbolTable)
      */
     @Override protected void fieldDeclaration(FieldDeclaration n, LocalSymbolTable arg) {
+        inField = true;
         int modifiers = n.getModifiers();
         List<VariableDeclarator> variables = n.getVariables();
         VariableDeclarator declarator = variables.get(0);
@@ -225,18 +212,16 @@ public class HVisitor extends CppVisitor
                 throw new IllegalStateException(
                         "More than one variable declared by one declarator.");
             }
-            String name = javaClassName + "." + declarator.getId().getName();
-            String value = declarator.getInit().toString();
-            if ("Integer.MAX_VALUE".equals(value)) {
-                value = cppTypes.maxInteger();
-            }
-            String longName = definePrefix + declarator.getId().getName();
-            if (symbolTable.cppDefinesByJavaNames.containsKey(name)) {
-                throw new IllegalStateException(
-                        "Duplicate #define constant local name: " + name);
-            }
-            symbolTable.cppDefinesByJavaNames.put(name, longName);
-            defines.add("#define " + longName + " " + value);
+            printModifiers(modifiers);
+            printer.print("const ");
+            n.getType().accept(this, arg);
+            printer.print(" ");
+            declarator.getId().accept(this, arg);
+            printer.print(" = ");
+            declarator.getInit().accept(this, arg);
+            printer.printLn(";");
+            printer.printLn();
+            symbolTable.addPrimitiveConstant(javaClassName, declarator.getId().toString());
         } else {
             if (n.getType() instanceof ReferenceType) {
                 ReferenceType rt = (ReferenceType) n.getType();
@@ -269,6 +254,16 @@ public class HVisitor extends CppVisitor
             inStatic = false;
             inPrimitiveNoLengthFieldDeclarator = false;
         }
+        inField = false;
+    }
+
+    /**
+     * @see nu.validator.htmlparser.cpptranslate.CppVisitor#printConstructorExplicit(java.util.List<japa.parser.ast.body.Parameter>)
+     */
+    @Override protected void printConstructorExplicit(List<Parameter> params) {
+        if (params != null && params.size() == 1) {
+            printer.print("explicit ");
+        }
     }
 
     /**
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/Main.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/Main.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/Main.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/Main.java	2025-09-16 08:29:41.000000000 +0000
@@ -37,60 +37,55 @@
 
 package nu.validator.htmlparser.cpptranslate;
 
-import japa.parser.JavaParser;
-import japa.parser.ParseException;
-import japa.parser.ast.CompilationUnit;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 
+import japa.parser.JavaParser;
+import japa.parser.ParseException;
+import japa.parser.ast.CompilationUnit;
+
 public class Main {
 
     static final String[] H_LIST = {
-        "Tokenizer",
-        "TreeBuilder",
-        "MetaScanner",
         "AttributeName",
         "ElementName",
-        "HtmlAttributes",
+        "Tokenizer",
+        "TreeBuilder",
         "StackNode",
         "UTF16Buffer",
         "StateSnapshot",
         "Portability",
     };
-    
+
     private static final String[] CPP_LIST = {
-        "Tokenizer",
-        "TreeBuilder",
-        "MetaScanner",
         "AttributeName",
         "ElementName",
-        "HtmlAttributes",
+        "Tokenizer",
+        "TreeBuilder",
         "StackNode",
         "UTF16Buffer",
         "StateSnapshot",
     };
-    
+
     /**
      * @param args
-     * @throws ParseException 
-     * @throws IOException 
+     * @throws ParseException
+     * @throws IOException
      */
     public static void main(String[] args) throws ParseException, IOException {
-        CppTypes cppTypes = new CppTypes(new File(args[2]));
+        CppTypes cppTypes = new CppTypes(new File(args[2]), new File(args[3]));
         SymbolTable symbolTable = new SymbolTable();
-        
+
         File javaDirectory = new File(args[0]);
         File targetDirectory = new File(args[1]);
         File cppDirectory = targetDirectory;
         File javaCopyDirectory = new File(targetDirectory, "javasrc");
-        
+
         for (int i = 0; i < H_LIST.length; i++) {
             parseFile(cppTypes, javaDirectory, cppDirectory, H_LIST[i], ".h", new HVisitor(cppTypes, symbolTable));
             copyFile(new File(javaDirectory, H_LIST[i] + ".java"), new File(javaCopyDirectory, H_LIST[i] + ".java"));
@@ -116,7 +111,7 @@ public class Main {
         out.close();
         in.close();
     }
-    
+
     private static void parseFile(CppTypes cppTypes, File javaDirectory,
             File cppDirectory, String className, String fne, CppVisitor visitor)
             throws FileNotFoundException, UnsupportedEncodingException,
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/SymbolTable.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/SymbolTable.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/SymbolTable.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/SymbolTable.java	2025-09-16 08:29:41.000000000 +0000
@@ -38,42 +38,57 @@
 package nu.validator.htmlparser.cpptranslate;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 public class SymbolTable {
-    
-    public final Map<String, String> cppDefinesByJavaNames = new HashMap<String, String>();
+
+    private final Set<StringPair> primitiveConstants = new HashSet<StringPair>();
 
     private final Map<StringPair, Type> fields = new HashMap<StringPair, Type>();
-    
+
     private final Map<StringPair, Type> methodReturns = new HashMap<StringPair, Type>();
-    
+
     /**
      * This is a sad hack to work around the fact the there's no real symbol
      * table yet.
-     * 
-     * @param name
+     *
+     * @param field
      * @return
      */
-    public boolean isNotAnAttributeOrElementName(String name) {
-        return !("ATTRIBUTE_HASHES".equals(name)
-                || "ATTRIBUTE_NAMES".equals(name)
-                || "ELEMENT_HASHES".equals(name)
-                || "ELEMENT_NAMES".equals(name) || "ALL_NO_NS".equals(name));
+    public boolean isAttributeOrElementName(String klazz, String field) {
+        if (isPrimitiveConstant(klazz, field)) {
+            return false;
+        }
+        return !("ATTRIBUTE_HASHES".equals(field)
+                || "ATTRIBUTE_NAMES".equals(field)
+                || "ELEMENT_HASHES".equals(field)
+                || "ELEMENT_NAMES".equals(field)
+                || "ALL_NO_NS".equals(field)
+                || "SAME_LOCAL_NULL".equals(field));
     }
-    
+
+    public void addPrimitiveConstant(String klazz, String field) {
+        primitiveConstants.add(new StringPair(klazz, field));
+    }
+
     public void putFieldType(String klazz, String field, Type type) {
         fields.put(new StringPair(klazz, field), type);
     }
-    
+
     public void putMethodReturnType(String klazz, String method, Type type) {
         methodReturns.put(new StringPair(klazz, method), type);
     }
-    
+
+    public boolean isPrimitiveConstant(String klazz, String field) {
+        return primitiveConstants.contains(new StringPair(klazz, field));
+    }
+
     public Type getFieldType(String klazz, String field) {
         return fields.get(new StringPair(klazz, field));
     }
-    
+
     public Type getMethodReturnType(String klazz, String method) {
         return methodReturns.get(new StringPair(klazz, method));
     }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/TranslatorUtils.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/TranslatorUtils.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/TranslatorUtils.java	1970-01-01 00:00:00.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/TranslatorUtils.java	2025-09-16 08:29:41.000000000 +0000
@@ -0,0 +1,81 @@
+package nu.validator.htmlparser.cpptranslate;
+
+import japa.parser.ast.expr.BinaryExpr;
+import japa.parser.ast.expr.BinaryExpr.Operator;
+import japa.parser.ast.expr.Expression;
+import japa.parser.ast.expr.MethodCallExpr;
+import japa.parser.ast.expr.NameExpr;
+import japa.parser.ast.expr.NullLiteralExpr;
+import japa.parser.ast.stmt.BlockStmt;
+import japa.parser.ast.stmt.ExpressionStmt;
+import japa.parser.ast.stmt.Statement;
+
+import java.util.List;
+
+public class TranslatorUtils {
+    public static boolean isErrorOnlyBlock(Statement elseStmt, boolean supportErrorReporting) {
+        if (supportErrorReporting) {
+            return false;
+        }
+        if (elseStmt instanceof BlockStmt) {
+            BlockStmt block = (BlockStmt) elseStmt;
+            List<Statement> statements = block.getStmts();
+            if (statements == null) {
+                return false;
+            }
+            if (statements.size() != 1) {
+                return false;
+            }
+            Statement statement = statements.get(0);
+            if (statement instanceof ExpressionStmt) {
+                ExpressionStmt exprStmt = (ExpressionStmt) statement;
+                Expression expr = exprStmt.getExpression();
+                if (expr instanceof MethodCallExpr) {
+                    MethodCallExpr call = (MethodCallExpr) expr;
+                    if (call.getName().startsWith("err")) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean isErrorHandlerIf(Expression condition, boolean supportErrorReporting) {
+        if (supportErrorReporting) {
+            return false;
+        }
+        while (condition instanceof BinaryExpr) {
+            BinaryExpr binex = (BinaryExpr) condition;
+            condition = binex.getLeft();
+            if (condition instanceof NameExpr) {
+                NameExpr name = (NameExpr) condition;
+                if ("errorHandler".equals(name.getName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean isDocumentModeHandlerNullCheck(Expression condition) {
+        if (condition instanceof BinaryExpr) {
+            BinaryExpr binex = (BinaryExpr) condition;
+            if (binex.getOperator() != Operator.notEquals) {
+                return false;
+            }
+            if (!(binex.getRight() instanceof NullLiteralExpr)) {
+                return false;
+            }
+            Expression left = binex.getLeft();
+            if (left instanceof NameExpr) {
+                NameExpr name = (NameExpr) left;
+                if ("documentModeHandler".equals(name.getName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+}
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/Type.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/Type.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/cpptranslate/Type.java	2016-01-11 19:41:03.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/cpptranslate/Type.java	2025-09-16 08:29:41.000000000 +0000
@@ -41,24 +41,12 @@ public class Type {
 
     /**
      * @param type
-     * @param arrayCount
-     * @param noLength
-     * @param modifiers
      */
-    public Type(String type, int arrayCount, boolean noLength, int modifiers) {
+    public Type(String type) {
         this.type = type;
-        this.arrayCount = arrayCount;
-        this.noLength = noLength;
-        this.modifiers = modifiers;
     }
 
     private final String type;
-    
-    private final int arrayCount;
-    
-    private final boolean noLength;
-    
-    private final int modifiers;
 
     /**
      * Returns the type.
@@ -68,32 +56,4 @@ public class Type {
     public String getType() {
         return type;
     }
-
-    /**
-     * Returns the arrayCount.
-     * 
-     * @return the arrayCount
-     */
-    public int getArrayCount() {
-        return arrayCount;
-    }
-
-    /**
-     * Returns the noLength.
-     * 
-     * @return the noLength
-     */
-    public boolean isNoLength() {
-        return noLength;
-    }
-
-    /**
-     * Returns the modifiers.
-     * 
-     * @return the modifiers
-     */
-    public int getModifiers() {
-        return modifiers;
-    }
-    
 }
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/ApplyHotSpotWorkaround.java	2025-09-16 08:29:41.000000000 +0000
@@ -32,8 +32,6 @@ import java.io.Writer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import nu.validator.htmlparser.impl.Tokenizer;
-
 /**
  * Applies a workaround that splits the <code>stateLoop</code> method in the
  * tokenizer into two methods. This way, each method stays under 8000 bytes in
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharacters.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharacters.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharacters.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharacters.java	2025-09-16 08:29:41.000000000 +0000
@@ -30,9 +30,6 @@ import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import nu.validator.htmlparser.annotation.CharacterName;
-import nu.validator.htmlparser.annotation.NoLength;
-
 public class GenerateNamedCharacters {
     
     private static final int LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
diff -pruN 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharactersCpp.java 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharactersCpp.java
--- 1.4+r1.3.1-3/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharactersCpp.java	2016-01-11 19:41:19.000000000 +0000
+++ 1.4+r20250916-1/translator-src/nu/validator/htmlparser/generator/GenerateNamedCharactersCpp.java	2025-09-16 08:29:41.000000000 +0000
@@ -141,7 +141,7 @@ public class GenerateNamedCharactersCpp
             }
         }
 
-        CppTypes cppTypes = new CppTypes(null);
+        CppTypes cppTypes = new CppTypes(null, null);
         File targetDirectory = new File(args[1]);
 
         generateH(targetDirectory, cppTypes, entities);
@@ -206,7 +206,7 @@ public class GenerateNamedCharactersCpp
             }
         }
 
-        out.write("const PRInt32* const " + cppTypes.classPrefix()
+        out.write("const int32_t* const " + cppTypes.classPrefix()
                 + "NamedCharactersAccel::HILO_ACCEL[] = {\n");
         for (int i = 0; i < hiLoTable.length; i++) {
             if (i != 0) {
@@ -231,8 +231,8 @@ public class GenerateNamedCharactersCpp
         Writer out = new OutputStreamWriter(new FileOutputStream(hFile),
                 "utf-8");
         out.write(DATA_LICENSE);
-        out.write("#ifndef " + cppTypes.classPrefix() + "NamedCharactersAccel_h_\n");
-        out.write("#define " + cppTypes.classPrefix() + "NamedCharactersAccel_h_\n");
+        out.write("#ifndef " + cppTypes.classPrefix() + "NamedCharactersAccel_h\n");
+        out.write("#define " + cppTypes.classPrefix() + "NamedCharactersAccel_h\n");
         out.write('\n');
 
         String[] includes = cppTypes.namedCharactersIncludes();
@@ -251,7 +251,7 @@ public class GenerateNamedCharactersCpp
         out.write("};\n");
 
         out.write("\n#endif // " + cppTypes.classPrefix()
-                + "NamedCharactersAccel_h_\n");
+                + "NamedCharactersAccel_h\n");
         out.flush();
         out.close();
     }
@@ -263,8 +263,8 @@ public class GenerateNamedCharactersCpp
         Writer out = new OutputStreamWriter(new FileOutputStream(hFile),
                 "utf-8");
         out.write(OUTPUT_LICENSE);
-        out.write("#ifndef " + cppTypes.classPrefix() + "NamedCharacters_h_\n");
-        out.write("#define " + cppTypes.classPrefix() + "NamedCharacters_h_\n");
+        out.write("#ifndef " + cppTypes.classPrefix() + "NamedCharacters_h\n");
+        out.write("#define " + cppTypes.classPrefix() + "NamedCharacters_h\n");
         out.write('\n');
 
         String[] includes = cppTypes.namedCharactersIncludes();
@@ -300,7 +300,7 @@ public class GenerateNamedCharactersCpp
         out.write("};\n");
 
         out.write("\n#endif // " + cppTypes.classPrefix()
-                + "NamedCharacters_h_\n");
+                + "NamedCharacters_h\n");
         out.flush();
         out.close();
     }
@@ -326,7 +326,7 @@ public class GenerateNamedCharactersCpp
         out.write(" *       See Tokenizer.java.\n");
         out.write(" *   3.  the length of this sequence of characters,\n");
         out.write(" *   4.  placeholder flag (0 if argument #is not a placeholder and 1 if it is),\n");
-        out.write(" *   5.  a comma-separated sequence of PRUnichar literals corresponding\n");
+        out.write(" *   5.  a comma-separated sequence of char16_t literals corresponding\n");
         out.write(" *       to the code-point(s) of the named character.\n");
         out.write(" *\n");
         out.write(" * The macro expansion doesn't have to refer to all or any of these parameters,\n");
@@ -533,11 +533,10 @@ public class GenerateNamedCharactersCpp
         String arrayLengthMacro = cppTypes.arrayLengthMacro();
         String staticAssert = cppTypes.staticAssert();
         if (staticAssert != null && arrayLengthMacro != null) {
-            out.write("/* check that the start positions will fit in 16 bits */\n");
             out.write(staticAssert + "(" + arrayLengthMacro
-                    + "(ALL_NAMES) < 0x10000);\n\n");
+                    + "(ALL_NAMES) < 0x10000, \"Start positions should fit in 16 bits\");\n\n");
         }
-        
+
         out.write("const " + cppTypes.characterNameTypeDeclaration() + " " + cppTypes.classPrefix()
                 + "NamedCharacters::NAMES[] = {\n");
         defineMacroAndInclude(out, "{ NAME_##N##_START, LEN, },", "{ NAME_##N##_START, LEN, N },", includeFile);
@@ -551,7 +550,7 @@ public class GenerateNamedCharactersCpp
         out.write("\n");
         out.write(cppTypes.characterNameTypeDeclaration());
         out.write("::charAt(");
-        out.write("PRInt32");
+        out.write("int32_t");
         out.write(" index) const\n{\n  return static_cast<");
         out.write(cppTypes.charType());
         out.write("> (ALL_NAMES[nameStart + index]);\n}\n\n");
