Bug 551344 part 6 - Address more review comments from sicking in the Java parts of the HTML5 parser. r=jonas.
authorHenri Sivonen <hsivonen@iki.fi>
Mon, 19 Apr 2010 16:25:13 +0300
changeset 41449 cdacbfe66545b60672016c549262cb9c27c9b7a9
parent 41448 67c682cd7fa46858f61f5986158f6dcbacd79d53
child 41450 d36b48ffd03d18f195258071c525b844bfbb37e6
push id13020
push userhsivonen@iki.fi
push dateWed, 28 Apr 2010 06:29:22 +0000
treeherdermozilla-central@cdacbfe66545 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonas
bugs551344
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 551344 part 6 - Address more review comments from sicking in the Java parts of the HTML5 parser. r=jonas.
parser/html/javasrc/StateSnapshot.java
parser/html/javasrc/Tokenizer.java
parser/html/javasrc/TreeBuilder.java
parser/html/nsAHtml5TreeBuilderState.h
parser/html/nsHtml5AtomList.h
parser/html/nsHtml5AttributeName.cpp
parser/html/nsHtml5AttributeName.h
parser/html/nsHtml5ElementName.cpp
parser/html/nsHtml5ElementName.h
parser/html/nsHtml5HtmlAttributes.cpp
parser/html/nsHtml5HtmlAttributes.h
parser/html/nsHtml5Macros.h
parser/html/nsHtml5MetaScanner.cpp
parser/html/nsHtml5MetaScanner.h
parser/html/nsHtml5Portability.h
parser/html/nsHtml5StackNode.cpp
parser/html/nsHtml5StackNode.h
parser/html/nsHtml5StateSnapshot.cpp
parser/html/nsHtml5StateSnapshot.h
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/html/nsHtml5Tokenizer.cpp
parser/html/nsHtml5Tokenizer.h
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
parser/html/nsHtml5UTF16Buffer.cpp
parser/html/nsHtml5UTF16Buffer.h
--- a/parser/html/javasrc/StateSnapshot.java
+++ b/parser/html/javasrc/StateSnapshot.java
@@ -34,42 +34,42 @@ public class StateSnapshot<T> implements
     private final T headPointer;
 
     private final int mode;
 
     private final int originalMode;
     
     private final boolean framesetOk;
 
-    private final int foreignFlag;
+    private final boolean inForeign;
 
     private final boolean needToDropLF;
 
     private final boolean quirks;
 
     /**
      * @param stack
      * @param listOfActiveFormattingElements
      * @param formPointer
      * @param quirks 
      * @param needToDropLF 
      * @param foreignFlag 
      * @param originalMode 
      * @param mode 
      */
     StateSnapshot(StackNode<T>[] stack,
-            StackNode<T>[] listOfActiveFormattingElements, T formPointer, T headPointer, int mode, int originalMode, boolean framesetOk, int foreignFlag, boolean needToDropLF, boolean quirks) {
+            StackNode<T>[] listOfActiveFormattingElements, T formPointer, T headPointer, int mode, int originalMode, boolean framesetOk, boolean inForeign, boolean needToDropLF, boolean quirks) {
         this.stack = stack;
         this.listOfActiveFormattingElements = listOfActiveFormattingElements;
         this.formPointer = formPointer;
         this.headPointer = headPointer;
         this.mode = mode;
         this.originalMode = originalMode;
         this.framesetOk = framesetOk;
-        this.foreignFlag = foreignFlag;
+        this.inForeign = inForeign;
         this.needToDropLF = needToDropLF;
         this.quirks = quirks;
     }
     
     /**
      * @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
      */
     public StackNode<T>[] getStack() {
@@ -122,22 +122,22 @@ public class StateSnapshot<T> implements
      * 
      * @return the framesetOk
      */
     public boolean isFramesetOk() {
         return framesetOk;
     }
 
     /**
-     * Returns the foreignFlag.
+     * Returns the inForeign.
      * 
-     * @return the foreignFlag
+     * @return the inForeign
      */
-    public int getForeignFlag() {
-        return foreignFlag;
+    public boolean isInForeign() {
+        return inForeign;
     }
 
     /**
      * Returns the needToDropLF.
      * 
      * @return the needToDropLF
      */
     public boolean isNeedToDropLF() {
--- a/parser/html/javasrc/Tokenizer.java
+++ b/parser/html/javasrc/Tokenizer.java
@@ -63,17 +63,17 @@ import org.xml.sax.SAXParseException;
  * 
  * @version $Id$
  * @author hsivonen
  */
 public class Tokenizer implements Locator {
 
     private static final int DATA_AND_RCDATA_MASK = ~1;
 
-	   public static final int DATA = 0;
+    public static final int DATA = 0;
 
     public static final int RCDATA = 1;
 
     public static final int SCRIPT_DATA = 2;
 
     public static final int PLAINTEXT = 3;
 
     private static final int TAG_OPEN = 4;
@@ -2438,17 +2438,17 @@ public class Tokenizer implements Locato
                             // continue stateloop;
                             case 'd':
                             case 'D':
                                 clearLongStrBufAndAppend(c);
                                 index = 0;
                                 state = Tokenizer.MARKUP_DECLARATION_OCTYPE;
                                 continue stateloop;
                             case '[':
-                                if (tokenHandler.inForeign()) {
+                                if (tokenHandler.isInForeign()) {
                                     clearLongStrBufAndAppend(c);
                                     index = 0;
                                     state = Tokenizer.CDATA_START;
                                     continue stateloop;
                                 } else {
                                     // fall through
                                 }
                             default:
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -330,36 +330,32 @@ public abstract class TreeBuilder<T> imp
             "-//w3c//dtd html 4.0 transitional//",
             "-//w3c//dtd html experimental 19960712//",
             "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//",
             "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//",
             "-//webtechs//dtd mozilla html//" };
 
     private static final int NOT_FOUND_ON_STACK = Integer.MAX_VALUE;
 
-    private static final int IN_FOREIGN = 0;
-
-    private static final int NOT_IN_FOREIGN = 1;
-
     // [NOCPP[
 
     private static final @Local String HTML_LOCAL = "html";
 
     // ]NOCPP]
 
     private int mode = INITIAL;
 
     private int originalMode = INITIAL;
     
     /**
      * Used only when moving back to IN_BODY.
      */
     private boolean framesetOk = true;
 
-    private int foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+    private boolean inForeign = false;
 
     protected Tokenizer tokenizer;
 
     // [NOCPP[
 
     protected ErrorHandler errorHandler;
 
     private DocumentModeHandler documentModeHandler;
@@ -458,16 +454,29 @@ public abstract class TreeBuilder<T> imp
      *            the message
      * @throws SAXException
      */
     final void err(String message) throws SAXException {
         // [NOCPP[
         if (errorHandler == null) {
             return;
         }
+        errNoCheck(message);
+        // ]NOCPP]
+    }
+    
+    /**
+     * Reports a Parse Error without checking if an error handler is present.
+     * 
+     * @param message
+     *            the message
+     * @throws SAXException
+     */
+    final void errNoCheck(String message) throws SAXException {
+        // [NOCPP[
         SAXParseException spe = new SAXParseException(message, tokenizer);
         errorHandler.error(spe);
         // ]NOCPP]
     }
 
     /**
      * Reports a warning
      * 
@@ -536,237 +545,224 @@ public abstract class TreeBuilder<T> imp
             }
             Portability.releaseLocal(contextName);
             contextName = null;
             Portability.releaseElement(contextNode);
             contextNode = null;
             Portability.releaseElement(elt);
         } else {
             mode = INITIAL;
-            foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+            inForeign = false;
         }
     }
 
     public final void doctype(@Local String name, String publicIdentifier,
             String systemIdentifier, boolean forceQuirks) throws SAXException {
         needToDropLF = false;
-        doctypeloop: for (;;) {
-            switch (foreignFlag) {
-                case IN_FOREIGN:
-                    break doctypeloop;
-                default:
-                    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);
+        if (!inForeign) {
+            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[
-                            }
-                            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",
+                                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/REC-html40/strict.dtd",
+                                                "http://www.w3.org/TR/html4/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);
+                                        || (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.");
                                     }
-                                    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();
+                                } 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.");
                                     }
-                                    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);
+                                } 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.");
                                     }
-                                    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);
+                                } else {
+                                    if (!(publicIdentifier == null && systemIdentifier == null)) {
+                                        err("Legacy doctype. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
                                     }
-                                    break;
+                                }
+                                documentModeInternal(
+                                        DocumentMode.STANDARDS_MODE,
+                                        publicIdentifier, systemIdentifier,
+                                        html4);
                             }
-                            // ]NOCPP]
-
-                            /*
-                             * 
-                             * Then, switch to the root element mode of the tree
-                             * construction stage.
-                             */
-                            mode = BEFORE_HTML;
-                            return;
-                        default:
-                            break doctypeloop;
+                            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;
             }
-
         }
         /*
          * A DOCTYPE token Parse error.
          */
         err("Stray doctype.");
         /*
          * Ignore the token.
          */
@@ -789,17 +785,17 @@ public abstract class TreeBuilder<T> imp
     public final void comment(@NoLength char[] buf, int start, int length)
             throws SAXException {
         needToDropLF = false;
         // [NOCPP[
         if (!wantingComments) {
             return;
         }
         // ]NOCPP]
-        if (foreignFlag != IN_FOREIGN) {
+        if (!inForeign) {
             switch (mode) {
                 case INITIAL:
                 case BEFORE_HTML:
                 case AFTER_AFTER_BODY:
                 case AFTER_AFTER_FRAMESET:
                     /*
                      * A comment token Append a Comment node to the Document
                      * object with the data attribute set to the data given in
@@ -1211,22 +1207,22 @@ public abstract class TreeBuilder<T> imp
                 if (start < end) {
                     accumulateCharacters(buf, start, end - start);
                 }
         }
     }
 
     public final void eof() throws SAXException {
         flushCharacters();
-        if (foreignFlag == IN_FOREIGN) {
+        if (inForeign) {
             err("End of file in a foreign namespace context.");
             while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                 popOnEof();
             }
-            foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+            inForeign = false;
         }
         eofloop: for (;;) {
             switch (mode) {
                 case INITIAL:
                     /*
                      * Parse error.
                      */
                     // [NOCPP[
@@ -1274,17 +1270,17 @@ public abstract class TreeBuilder<T> imp
                      * reprocess the current token.
                      */
                     continue;
                 case BEFORE_HEAD:
                     appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
                     mode = IN_HEAD;
                     continue;
                 case IN_HEAD:
-                    if (currentPtr > 1) {
+                    if (errorHandler != null && currentPtr > 1) {
                         err("End of file seen and there were open elements.");
                     }
                     while (currentPtr > 0) {
                         popOnEof();
                     }
                     mode = AFTER_HEAD;
                     continue;
                 case IN_HEAD_NOSCRIPT:
@@ -1340,18 +1336,18 @@ public abstract class TreeBuilder<T> imp
                     mode = originalMode;
                     continue;
                 case IN_TABLE_BODY:
                 case IN_ROW:
                 case IN_TABLE:
                 case IN_SELECT:
                 case IN_SELECT_IN_TABLE:
                 case IN_FRAMESET:
-                    if (currentPtr > 0) {
-                        err("End of file seen and there were open elements.");
+                    if (errorHandler != null && currentPtr > 0) {
+                        errNoCheck("End of file seen and there were open elements.");
                     }
                     break eofloop;
                 case AFTER_BODY:
                 case AFTER_FRAMESET:
                 case AFTER_AFTER_BODY:
                 case AFTER_AFTER_FRAMESET:
                 default:
                     // [NOCPP[
@@ -1416,1498 +1412,1468 @@ public abstract class TreeBuilder<T> imp
             // ID uniqueness
             @IdType String id = attributes.getId();
             if (id != null) {
                 LocatorImpl oldLoc = idLocations.get(id);
                 if (oldLoc != null) {
                     err("Duplicate ID \u201C" + id + "\u201D.");
                     errorHandler.warning(new SAXParseException(
                             "The first occurrence of ID \u201C" + id
-                                    + "\u201D was here.", oldLoc));
+                            + "\u201D was here.", oldLoc));
                 } else {
                     idLocations.put(id, new LocatorImpl(tokenizer));
                 }
             }
         }
         // ]NOCPP]
 
         int eltPos;
         needToDropLF = false;
         boolean needsPostProcessing = false;
         starttagloop: for (;;) {
             int group = elementName.group;
             @Local String name = elementName.name;
-            switch (foreignFlag) {
-                case IN_FOREIGN:
-                    StackNode<T> currentNode = stack[currentPtr];
-                    @NsUri String currNs = currentNode.ns;
-                    int currGroup = currentNode.group;
-                    if (("http://www.w3.org/1999/xhtml" == currNs)
-                            || ("http://www.w3.org/1998/Math/MathML" == currNs && ((MGLYPH_OR_MALIGNMARK != group && MI_MO_MN_MS_MTEXT == currGroup) || (SVG == group && ANNOTATION_XML == currGroup)))
-                            || ("http://www.w3.org/2000/svg" == currNs && (TITLE == currGroup || (FOREIGNOBJECT_OR_DESC == currGroup)))) {
-                        needsPostProcessing = true;
-                        // fall through to non-foreign behavior
-                    } else {
-                        switch (group) {
-                            case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
-                            case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
-                            case BODY:
-                            case BR:
-                            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 H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
-                            case HEAD:
-                            case HR:
-                            case LI:
-                            case META:
-                            case NOBR:
-                            case P:
-                            case PRE_OR_LISTING:
-                            case TABLE:
+            if (inForeign) {
+                StackNode<T> currentNode = stack[currentPtr];
+                @NsUri String currNs = currentNode.ns;
+                int currGroup = currentNode.group;
+                if (("http://www.w3.org/1999/xhtml" == currNs)
+                        || ("http://www.w3.org/1998/Math/MathML" == currNs && ((MGLYPH_OR_MALIGNMARK != group && MI_MO_MN_MS_MTEXT == currGroup) || (SVG == group && ANNOTATION_XML == currGroup)))
+                        || ("http://www.w3.org/2000/svg" == currNs && (TITLE == currGroup || (FOREIGNOBJECT_OR_DESC == currGroup)))) {
+                    needsPostProcessing = true;
+                    // fall through to non-foreign behavior
+                } else {
+                    switch (group) {
+                        case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+                        case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+                        case BODY:
+                        case BR:
+                        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 H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+                        case HEAD:
+                        case HR:
+                        case LI:
+                        case META:
+                        case NOBR:
+                        case P:
+                        case PRE_OR_LISTING:
+                        case TABLE:
+                            err("HTML start tag \u201C"
+                                    + name
+                                    + "\u201D in a foreign namespace context.");
+                            while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+                                pop();
+                            }
+                            inForeign = false;
+                            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 (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                                     pop();
                                 }
-                                foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+                                inForeign = false;
                                 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 (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
-                                        pop();
-                                    }
-                                    foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
-                                    continue starttagloop;
+                            }
+                            // else fall thru
+                        default:
+                            if ("http://www.w3.org/2000/svg" == currNs) {
+                                attributes.adjustForSvg();
+                                if (selfClosing) {
+                                    appendVoidElementToCurrentMayFosterCamelCase(
+                                            currNs, elementName, attributes);
+                                    selfClosing = false;
+                                } else {
+                                    appendToCurrentNodeAndPushElementMayFosterCamelCase(
+                                            currNs, elementName, attributes);
+                                }
+                                attributes = null; // CPP
+                                break starttagloop;
+                            } else {
+                                attributes.adjustForMath();
+                                if (selfClosing) {
+                                    appendVoidElementToCurrentMayFoster(
+                                            currNs, elementName, attributes);
+                                    selfClosing = false;
+                                } else {
+                                    appendToCurrentNodeAndPushElementMayFosterNoScoping(
+                                            currNs, elementName, attributes);
                                 }
-                                // else fall thru
-                            default:
-                                if ("http://www.w3.org/2000/svg" == currNs) {
-                                    attributes.adjustForSvg();
-                                    if (selfClosing) {
-                                        appendVoidElementToCurrentMayFosterCamelCase(
-                                                currNs, elementName, attributes);
-                                        selfClosing = false;
-                                    } else {
-                                        appendToCurrentNodeAndPushElementMayFosterCamelCase(
-                                                currNs, elementName, attributes);
-                                    }
-                                    attributes = null; // CPP
+                                attributes = null; // CPP
+                                break starttagloop;
+                            }
+                    } // switch
+                } // foreignObject / annotation-xml
+            }
+            switch (mode) {
+                case IN_TABLE_BODY:
+                    switch (group) {
+                        case TR:
+                            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            mode = IN_ROW;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TD_OR_TH:
+                            err("\u201C" + name
+                                    + "\u201D start tag in table body.");
+                            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    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) {
+                                err("Stray \u201C" + name + "\u201D start tag.");
+                                break starttagloop;
+                            } else {
+                                clearStackBackTo(eltPos);
+                                pop();
+                                mode = IN_TABLE;
+                                continue;
+                            }
+                        default:
+                            // fall through to IN_TABLE
+                    }
+                case IN_ROW:
+                    switch (group) {
+                        case TD_OR_TH:
+                            clearStackBackTo(findLastOrRoot(TreeBuilder.TR));
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            mode = IN_CELL;
+                            insertMarker();
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                            eltPos = findLastOrRoot(TreeBuilder.TR);
+                            if (eltPos == 0) {
+                                assert fragment;
+                                err("No table row to close.");
+                                break starttagloop;
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE_BODY;
+                            continue;
+                        default:
+                            // fall through to IN_TABLE
+                    }
+                case IN_TABLE:
+                    intableloop: for (;;) {
+                        switch (group) {
+                            case CAPTION:
+                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+                                insertMarker();
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                mode = IN_CAPTION;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case COLGROUP:
+                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                mode = IN_COLUMN_GROUP;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case COL:
+                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        ElementName.COLGROUP,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                mode = IN_COLUMN_GROUP;
+                                continue starttagloop;
+                            case TBODY_OR_THEAD_OR_TFOOT:
+                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                mode = IN_TABLE_BODY;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case TR:
+                            case TD_OR_TH:
+                                clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        ElementName.TBODY,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                mode = IN_TABLE_BODY;
+                                continue starttagloop;
+                            case TABLE:
+                                err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.");
+                                eltPos = findLastInTableScope(name);
+                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                    assert fragment;
+                                    break starttagloop;
+                                }
+                                generateImpliedEndTags();
+                                // XXX is the next if dead code?
+                                if (errorHandler != null && !isCurrent("table")) {
+                                    errNoCheck("Unclosed elements on stack.");
+                                }
+                                while (currentPtr >= eltPos) {
+                                    pop();
+                                }
+                                resetTheInsertionMode();
+                                continue starttagloop;
+                            case SCRIPT:
+                                // XXX need to manage much more stuff
+                                // here if
+                                // supporting
+                                // document.write()
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.SCRIPT_DATA, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case STYLE:
+                                appendToCurrentNodeAndPushElement(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RAWTEXT, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case INPUT:
+                                if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+                                        "hidden",
+                                        attributes.getValue(AttributeName.TYPE))) {
+                                    break intableloop;
+                                }
+                                appendVoidElementToCurrent(
+                                        "http://www.w3.org/1999/xhtml", name,
+                                        attributes, formPointer);
+                                selfClosing = false;
+                                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.");
                                     break starttagloop;
                                 } else {
-                                    attributes.adjustForMath();
-                                    if (selfClosing) {
-                                        appendVoidElementToCurrentMayFoster(
-                                                currNs, elementName, attributes);
-                                        selfClosing = false;
-                                    } else {
-                                        appendToCurrentNodeAndPushElementMayFosterNoScoping(
-                                                currNs, elementName, attributes);
-                                    }
+                                    err("Start tag \u201Cform\u201D seen in \u201Ctable\u201D.");
+                                    appendVoidFormToCurrent(attributes);
                                     attributes = null; // CPP
                                     break starttagloop;
                                 }
+                            default:
+                                err("Start tag \u201C" + name
+                                        + "\u201D seen in \u201Ctable\u201D.");
+                                // fall through to IN_BODY
+                                break intableloop;
                         }
                     }
-                default:
-                    switch (mode) {
-                        case IN_TABLE_BODY:
-                            switch (group) {
-                                case TR:
-                                    clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
+                case IN_CAPTION:
+                    switch (group) {
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                        case TD_OR_TH:
+                            err("Stray \u201C"
+                                    + name
+                                    + "\u201D start tag in \u201Ccaption\u201D.");
+                            eltPos = findLastInTableScope("caption");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                break starttagloop;
+                            }
+                            generateImpliedEndTags();
+                            if (errorHandler != null && currentPtr != eltPos) {
+                                errNoCheck("Unclosed elements on stack.");
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
+                            }
+                            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+                            mode = IN_TABLE;
+                            continue;
+                        default:
+                            // fall through to IN_BODY
+                    }
+                case IN_CELL:
+                    switch (group) {
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                        case TD_OR_TH:
+                            eltPos = findLastInTableScopeTdTh();
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                err("No cell to close.");
+                                break starttagloop;
+                            } else {
+                                closeTheCell(eltPos);
+                                continue;
+                            }
+                        default:
+                            // fall through to IN_BODY
+                    }
+                case FRAMESET_OK:
+                    switch (group) {
+                        case FRAMESET:
+                            if (mode == FRAMESET_OK) {
+                                if (currentPtr == 0 || stack[1].group != BODY) {
+                                    assert fragment;
+                                    err("Stray \u201Cframeset\u201D start tag.");
+                                    break starttagloop;
+                                } else {
+                                    err("\u201Cframeset\u201D start tag seen.");
+                                    detachFromParent(stack[1].node);
+                                    while (currentPtr > 0) {
+                                        pop();
+                                    }
                                     appendToCurrentNodeAndPushElement(
                                             "http://www.w3.org/1999/xhtml",
                                             elementName, attributes);
-                                    mode = IN_ROW;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case TD_OR_TH:
-                                    err("\u201C" + name
-                                            + "\u201D start tag in table body.");
-                                    clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            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) {
-                                        err("Stray \u201C" + name
-                                                + "\u201D start tag.");
-                                        break starttagloop;
-                                    } else {
-                                        clearStackBackTo(eltPos);
-                                        pop();
-                                        mode = IN_TABLE;
-                                        continue;
-                                    }
-                                default:
-                                    // fall through to IN_TABLE
-                            }
-                        case IN_ROW:
-                            switch (group) {
-                                case TD_OR_TH:
-                                    clearStackBackTo(findLastOrRoot(TreeBuilder.TR));
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    mode = IN_CELL;
-                                    insertMarker();
+                                    mode = IN_FRAMESET;
                                     attributes = null; // CPP
                                     break starttagloop;
-                                case CAPTION:
-                                case COL:
-                                case COLGROUP:
-                                case TBODY_OR_THEAD_OR_TFOOT:
-                                case TR:
-                                    eltPos = findLastOrRoot(TreeBuilder.TR);
-                                    if (eltPos == 0) {
-                                        assert fragment;
-                                        err("No table row to close.");
-                                        break starttagloop;
-                                    }
-                                    clearStackBackTo(eltPos);
-                                    pop();
-                                    mode = IN_TABLE_BODY;
-                                    continue;
-                                default:
-                                    // fall through to IN_TABLE
+                                }
+                            } else {
+                                err("Stray \u201Cframeset\u201D start tag.");
+                                break starttagloop;
+                            }
+                            // NOT falling through!
+                        case PRE_OR_LISTING:
+                        case LI:
+                        case DD_OR_DT:
+                        case BUTTON:
+                        case MARQUEE_OR_APPLET:
+                        case OBJECT:
+                        case TABLE:
+                        case AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR:
+                        case BR:
+                        case EMBED_OR_IMG:
+                        case INPUT:
+                        case KEYGEN:
+                        case HR:
+                        case TEXTAREA:
+                        case XMP:
+                        case IFRAME:
+                        case SELECT:
+                            if (mode == FRAMESET_OK) {
+                                framesetOk = false;
+                                mode = IN_BODY;
                             }
-                        case IN_TABLE:
-                            intableloop: for (;;) {
-                                switch (group) {
-                                    case CAPTION:
-                                        clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
-                                        insertMarker();
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        mode = IN_CAPTION;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case COLGROUP:
-                                        clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        mode = IN_COLUMN_GROUP;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case COL:
-                                        clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                ElementName.COLGROUP,
-                                                HtmlAttributes.EMPTY_ATTRIBUTES);
-                                        mode = IN_COLUMN_GROUP;
-                                        continue starttagloop;
-                                    case TBODY_OR_THEAD_OR_TFOOT:
-                                        clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        mode = IN_TABLE_BODY;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case TR:
-                                    case TD_OR_TH:
-                                        clearStackBackTo(findLastOrRoot(TreeBuilder.TABLE));
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                ElementName.TBODY,
-                                                HtmlAttributes.EMPTY_ATTRIBUTES);
-                                        mode = IN_TABLE_BODY;
-                                        continue starttagloop;
-                                    case TABLE:
-                                        err("Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.");
-                                        eltPos = findLastInTableScope(name);
-                                        if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                            assert fragment;
-                                            break starttagloop;
-                                        }
-                                        generateImpliedEndTags();
-                                        // XXX is the next if dead code?
-                                        if (!isCurrent("table")) {
-                                            err("Unclosed elements on stack.");
+                            // fall through to IN_BODY
+                        default:
+                            // fall through to IN_BODY
+                    }
+                case IN_BODY:
+                    inbodyloop: for (;;) {
+                        switch (group) {
+                            case HTML:
+                                err("Stray \u201Chtml\u201D start tag.");
+                                addAttributesToHtml(attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case BASE:
+                            case LINK:
+                            case META:
+                            case STYLE:
+                            case SCRIPT:
+                            case TITLE:
+                            case COMMAND:
+                                // Fall through to IN_HEAD
+                                break inbodyloop;
+                            case BODY:
+                                err("\u201Cbody\u201D start tag found but the \u201Cbody\u201D element is already open.");
+                                addAttributesToBody(attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case P:
+                            case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+                            case UL_OR_OL_OR_DL:
+                            case ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION:
+                                implicitlyCloseP();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+                                implicitlyCloseP();
+                                if (stack[currentPtr].group == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
+                                    err("Heading cannot be a child of another heading.");
+                                    pop();
+                                }
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case FIELDSET:
+                                implicitlyCloseP();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes, formPointer);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case PRE_OR_LISTING:
+                                implicitlyCloseP();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                needToDropLF = true;
+                                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.");
+                                    break starttagloop;
+                                } else {
+                                    implicitlyCloseP();
+                                    appendToCurrentNodeAndPushFormElementMayFoster(attributes);
+                                    attributes = null; // CPP
+                                    break starttagloop;
+                                }
+                            case LI:
+                            case DD_OR_DT:
+                                eltPos = currentPtr;
+                                for (;;) {
+                                    StackNode<T> node = stack[eltPos]; // weak
+                                    // ref
+                                    if (node.group == group) { // LI or
+                                        // DD_OR_DT
+                                        generateImpliedEndTagsExceptFor(node.name);
+                                        if (errorHandler != null
+                                                && eltPos != currentPtr) {
+                                            errNoCheck("Unclosed elements inside a list.");
                                         }
                                         while (currentPtr >= eltPos) {
                                             pop();
                                         }
-                                        resetTheInsertionMode();
-                                        continue starttagloop;
-                                    case SCRIPT:
-                                        // XXX need to manage much more stuff
-                                        // here if
-                                        // supporting
-                                        // document.write()
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.SCRIPT_DATA, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case STYLE:
-                                        appendToCurrentNodeAndPushElement(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RAWTEXT, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case INPUT:
-                                        if (!Portability.lowerCaseLiteralEqualsIgnoreAsciiCaseString(
-                                                "hidden",
-                                                attributes.getValue(AttributeName.TYPE))) {
-                                            break intableloop;
-                                        }
-                                        appendVoidElementToCurrent(
-                                                "http://www.w3.org/1999/xhtml",
-                                                name, attributes, formPointer);
-                                        selfClosing = false;
-                                        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.");
-                                            break starttagloop;
-                                        } else {
-                                            err("Start tag \u201Cform\u201D seen in \u201Ctable\u201D.");
-                                            appendVoidFormToCurrent(attributes);
-                                            attributes = null; // CPP
-                                            break starttagloop;
-                                        }
-                                    default:
-                                        err("Start tag \u201C"
-                                                + name
-                                                + "\u201D seen in \u201Ctable\u201D.");
-                                        // fall through to IN_BODY
-                                        break intableloop;
+                                        break;
+                                    } else if (node.scoping
+                                            || (node.special
+                                                    && node.name != "p"
+                                                    && node.name != "address" && node.name != "div")) {
+                                        break;
+                                    }
+                                    eltPos--;
                                 }
-                            }
-                        case IN_CAPTION:
-                            switch (group) {
-                                case CAPTION:
-                                case COL:
-                                case COLGROUP:
-                                case TBODY_OR_THEAD_OR_TFOOT:
-                                case TR:
-                                case TD_OR_TH:
-                                    err("Stray \u201C"
-                                            + name
-                                            + "\u201D start tag in \u201Ccaption\u201D.");
-                                    eltPos = findLastInTableScope("caption");
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        break starttagloop;
+                                implicitlyCloseP();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case PLAINTEXT:
+                                implicitlyCloseP();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.PLAINTEXT, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case A:
+                                int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a");
+                                if (activeAPos != -1) {
+                                    err("An \u201Ca\u201D start tag seen with already an active \u201Ca\u201D element.");
+                                    StackNode<T> activeA = listOfActiveFormattingElements[activeAPos];
+                                    activeA.retain();
+                                    adoptionAgencyEndTag("a");
+                                    removeFromStack(activeA);
+                                    activeAPos = findInListOfActiveFormattingElements(activeA);
+                                    if (activeAPos != -1) {
+                                        removeFromListOfActiveFormattingElements(activeAPos);
                                     }
+                                    activeA.release();
+                                }
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushFormattingElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            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();
+                                appendToCurrentNodeAndPushFormattingElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            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.");
+                                    adoptionAgencyEndTag("nobr");
+                                }
+                                appendToCurrentNodeAndPushFormattingElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            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.");
+
                                     generateImpliedEndTags();
-                                    if (currentPtr != eltPos) {
-                                        err("Unclosed elements on stack.");
+                                    if (errorHandler != null
+                                            && !isCurrent(name)) {
+                                        errNoCheck("End tag \u201Cbutton\u201D seen but there were unclosed elements.");
                                     }
                                     while (currentPtr >= eltPos) {
                                         pop();
                                     }
-                                    clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-                                    mode = IN_TABLE;
-                                    continue;
-                                default:
-                                    // fall through to IN_BODY
-                            }
-                        case IN_CELL:
-                            switch (group) {
-                                case CAPTION:
-                                case COL:
-                                case COLGROUP:
-                                case TBODY_OR_THEAD_OR_TFOOT:
-                                case TR:
-                                case TD_OR_TH:
-                                    eltPos = findLastInTableScopeTdTh();
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        err("No cell to close.");
-                                        break starttagloop;
-                                    } else {
-                                        closeTheCell(eltPos);
-                                        continue;
-                                    }
-                                default:
-                                    // fall through to IN_BODY
-                            }
-                        case FRAMESET_OK:
-                            switch (group) {
-                                case FRAMESET:
-                                    if (mode == FRAMESET_OK) {
-                                        if (currentPtr == 0
-                                                || stack[1].group != BODY) {
-                                            assert fragment;
-                                            err("Stray \u201Cframeset\u201D start tag.");
-                                            break starttagloop;
-                                        } else {
-                                            err("\u201Cframeset\u201D start tag seen.");
-                                            detachFromParent(stack[1].node);
-                                            while (currentPtr > 0) {
-                                                pop();
-                                            }
-                                            appendToCurrentNodeAndPushElement(
-                                                    "http://www.w3.org/1999/xhtml",
-                                                    elementName, attributes);
-                                            mode = IN_FRAMESET;
-                                            attributes = null; // CPP
-                                            break starttagloop;
-                                        }
-                                    } else {
-                                        err("Stray \u201Cframeset\u201D start tag.");
-                                        break starttagloop;
-                                    }
-                                    // NOT falling through!
-                                case PRE_OR_LISTING:
-                                case LI:
-                                case DD_OR_DT:
-                                case BUTTON:
-                                case MARQUEE_OR_APPLET:
-                                case OBJECT:
-                                case TABLE:
-                                case AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR:
-                                case BR:
-                                case EMBED_OR_IMG:
-                                case INPUT:
-                                case KEYGEN:
-                                case HR:
-                                case TEXTAREA:
-                                case XMP:
-                                case IFRAME:
-                                case SELECT:
-                                    if (mode == FRAMESET_OK) {
-                                        framesetOk = false;
-                                        mode = IN_BODY;
+                                    continue starttagloop;
+                                } else {
+                                    reconstructTheActiveFormattingElements();
+                                    appendToCurrentNodeAndPushElementMayFoster(
+                                            "http://www.w3.org/1999/xhtml",
+                                            elementName, attributes,
+                                            formPointer);
+                                    attributes = null; // CPP
+                                    break starttagloop;
+                                }
+                            case OBJECT:
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes, formPointer);
+                                insertMarker();
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case MARQUEE_OR_APPLET:
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                insertMarker();
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case TABLE:
+                                // The only quirk. Blame Hixie and
+                                // Acid2.
+                                if (!quirks) {
+                                    implicitlyCloseP();
+                                }
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                mode = IN_TABLE;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case BR:
+                            case EMBED_OR_IMG:
+                            case AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR:
+                                reconstructTheActiveFormattingElements();
+                                // FALL THROUGH to PARAM_OR_SOURCE
+                            case PARAM_OR_SOURCE:
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                selfClosing = false;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case HR:
+                                implicitlyCloseP();
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                selfClosing = false;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case IMAGE:
+                                err("Saw a start tag \u201Cimage\u201D.");
+                                elementName = ElementName.IMG;
+                                continue starttagloop;
+                            case KEYGEN:
+                            case INPUT:
+                                reconstructTheActiveFormattingElements();
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml", name,
+                                        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(
+                                        "http://www.w3.org/1999/xhtml",
+                                        ElementName.HR,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        ElementName.LABEL,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                int promptIndex = attributes.getIndex(AttributeName.PROMPT);
+                                if (promptIndex > -1) {
+                                    char[] prompt = Portability.newCharArrayFromString(attributes.getValue(promptIndex));
+                                    appendCharacters(stack[currentPtr].node,
+                                            prompt, 0, prompt.length);
+                                    Portability.releaseArray(prompt);
+                                } else {
+                                    // XXX localization
+                                    appendCharacters(stack[currentPtr].node,
+                                            TreeBuilder.ISINDEX_PROMPT, 0,
+                                            TreeBuilder.ISINDEX_PROMPT.length);
+                                }
+                                HtmlAttributes inputAttributes = new HtmlAttributes(
+                                        0);
+                                inputAttributes.addAttribute(
+                                        AttributeName.NAME,
+                                        Portability.newStringFromLiteral("isindex")
+                                        // [NOCPP[
+                                        , XmlViolationPolicy.ALLOW
+                                // ]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]
+
+                                        );
                                     }
-                                    // fall through to IN_BODY
-                                default:
-                                    // fall through to IN_BODY
-                            }
-                        case IN_BODY:
-                            inbodyloop: for (;;) {
-                                switch (group) {
-                                    case HTML:
-                                        err("Stray \u201Chtml\u201D start tag.");
-                                        addAttributesToHtml(attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case BASE:
-                                    case LINK:
-                                    case META:
-                                    case STYLE:
-                                    case SCRIPT:
-                                    case TITLE:
-                                    case COMMAND:
-                                        // Fall through to IN_HEAD
-                                        break inbodyloop;
-                                    case BODY:
-                                        err("\u201Cbody\u201D start tag found but the \u201Cbody\u201D element is already open.");
-                                        addAttributesToBody(attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case P:
-                                    case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
-                                    case UL_OR_OL_OR_DL:
-                                    case ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION:
-                                        implicitlyCloseP();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
-                                        implicitlyCloseP();
-                                        if (stack[currentPtr].group == H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
-                                            err("Heading cannot be a child of another heading.");
+                                }
+                                attributes.clearWithoutReleasingContents();
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        "input", inputAttributes, formPointer);
+                                // XXX localization
+                                pop(); // label
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        ElementName.HR,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                pop(); // form
+                                selfClosing = false;
+                                // Portability.delete(formAttrs);
+                                // Portability.delete(inputAttributes);
+                                // Don't delete attributes, they are deleted
+                                // later
+                                break starttagloop;
+                            case TEXTAREA:
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes, formPointer);
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RCDATA, elementName);
+                                originalMode = mode;
+                                mode = TEXT;
+                                needToDropLF = true;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case XMP:
+                                implicitlyCloseP();
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RAWTEXT, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case NOSCRIPT:
+                                if (!scriptingEnabled) {
+                                    reconstructTheActiveFormattingElements();
+                                    appendToCurrentNodeAndPushElementMayFoster(
+                                            "http://www.w3.org/1999/xhtml",
+                                            elementName, attributes);
+                                    attributes = null; // CPP
+                                    break starttagloop;
+                                } else {
+                                    // fall through
+                                }
+                            case NOFRAMES:
+                            case IFRAME:
+                            case NOEMBED:
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RAWTEXT, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case SELECT:
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes, formPointer);
+                                switch (mode) {
+                                    case IN_TABLE:
+                                    case IN_CAPTION:
+                                    case IN_COLUMN_GROUP:
+                                    case IN_TABLE_BODY:
+                                    case IN_ROW:
+                                    case IN_CELL:
+                                        mode = IN_SELECT_IN_TABLE;
+                                        break;
+                                    default:
+                                        mode = IN_SELECT;
+                                        break;
+                                }
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case OPTGROUP:
+                            case OPTION:
+                                /*
+                                 * If the stack of open elements has an option
+                                 * element in scope, then act as if an end tag
+                                 * with the tag name "option" had been seen.
+                                 */
+                                if (findLastInScope("option") != TreeBuilder.NOT_FOUND_ON_STACK) {
+                                    optionendtagloop: for (;;) {
+                                        if (isCurrent("option")) {
                                             pop();
+                                            break optionendtagloop;
                                         }
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case FIELDSET:
-                                        implicitlyCloseP();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes,
-                                                formPointer);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case PRE_OR_LISTING:
-                                        implicitlyCloseP();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        needToDropLF = true;
-                                        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.");
-                                            break starttagloop;
-                                        } else {
-                                            implicitlyCloseP();
-                                            appendToCurrentNodeAndPushFormElementMayFoster(attributes);
-                                            attributes = null; // CPP
-                                            break starttagloop;
-                                        }
-                                    case LI:
-                                    case DD_OR_DT:
+
                                         eltPos = currentPtr;
                                         for (;;) {
-                                            StackNode<T> node = stack[eltPos]; // weak
-                                                                               // ref
-                                            if (node.group == group) { // LI or
-                                                // DD_OR_DT
-                                                generateImpliedEndTagsExceptFor(node.name);
-                                                if (eltPos != currentPtr) {
-                                                    err("Unclosed elements inside a list.");
+                                            if (stack[eltPos].name == "option") {
+                                                generateImpliedEndTags();
+                                                if (errorHandler != null
+                                                        && !isCurrent("option")) {
+                                                    errNoCheck("End tag \u201C"
+                                                            + name
+                                                            + "\u201D seen but there were unclosed elements.");
                                                 }
                                                 while (currentPtr >= eltPos) {
                                                     pop();
                                                 }
-                                                break;
-                                            } else if (node.scoping
-                                                    || (node.special
-                                                            && node.name != "p"
-                                                            && node.name != "address" && node.name != "div")) {
-                                                break;
+                                                break optionendtagloop;
                                             }
                                             eltPos--;
                                         }
-                                        implicitlyCloseP();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case PLAINTEXT:
-                                        implicitlyCloseP();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.PLAINTEXT,
-                                                elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case A:
-                                        int activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker("a");
-                                        if (activeAPos != -1) {
-                                            err("An \u201Ca\u201D start tag seen with already an active \u201Ca\u201D element.");
-                                            StackNode<T> activeA = listOfActiveFormattingElements[activeAPos];
-                                            activeA.retain();
-                                            adoptionAgencyEndTag("a");
-                                            removeFromStack(activeA);
-                                            activeAPos = findInListOfActiveFormattingElements(activeA);
-                                            if (activeAPos != -1) {
-                                                removeFromListOfActiveFormattingElements(activeAPos);
-                                            }
-                                            activeA.release();
-                                        }
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushFormattingElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    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();
-                                        appendToCurrentNodeAndPushFormattingElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    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.");
-                                            adoptionAgencyEndTag("nobr");
-                                        }
-                                        appendToCurrentNodeAndPushFormattingElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    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.");
-
-                                            generateImpliedEndTags();
-                                            if (!isCurrent(name)) {
-                                                err("End tag \u201Cbutton\u201D seen but there were unclosed elements.");
-                                            }
-                                            while (currentPtr >= eltPos) {
-                                                pop();
-                                            }
-                                            continue starttagloop;
-                                        } else {
-                                            reconstructTheActiveFormattingElements();
-                                            appendToCurrentNodeAndPushElementMayFoster(
-                                                    "http://www.w3.org/1999/xhtml",
-                                                    elementName, attributes,
-                                                    formPointer);
-                                            attributes = null; // CPP
-                                            break starttagloop;
-                                        }
-                                    case OBJECT:
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes,
-                                                formPointer);
-                                        insertMarker();
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case MARQUEE_OR_APPLET:
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        insertMarker();
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case TABLE:
-                                        // The only quirk. Blame Hixie and
-                                        // Acid2.
-                                        if (!quirks) {
-                                            implicitlyCloseP();
-                                        }
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        mode = IN_TABLE;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case BR:
-                                    case EMBED_OR_IMG:
-                                    case AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR:
-                                        reconstructTheActiveFormattingElements();
-                                        // FALL THROUGH to PARAM_OR_SOURCE
-                                    case PARAM_OR_SOURCE:
-                                        appendVoidElementToCurrentMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        selfClosing = false;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case HR:
-                                        implicitlyCloseP();
-                                        appendVoidElementToCurrentMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        selfClosing = false;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case IMAGE:
-                                        err("Saw a start tag \u201Cimage\u201D.");
-                                        elementName = ElementName.IMG;
-                                        continue starttagloop;
-                                    case KEYGEN:
-                                    case INPUT:
-                                        reconstructTheActiveFormattingElements();
-                                        appendVoidElementToCurrentMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                name, 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(
-                                                "http://www.w3.org/1999/xhtml",
-                                                ElementName.HR,
-                                                HtmlAttributes.EMPTY_ATTRIBUTES);
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                ElementName.LABEL,
-                                                HtmlAttributes.EMPTY_ATTRIBUTES);
-                                        int promptIndex = attributes.getIndex(AttributeName.PROMPT);
-                                        if (promptIndex > -1) {
-                                            char[] prompt = Portability.newCharArrayFromString(attributes.getValue(promptIndex));
-                                            appendCharacters(
-                                                    stack[currentPtr].node,
-                                                    prompt, 0, prompt.length);
-                                            Portability.releaseArray(prompt);
-                                        } else {
-                                            // XXX localization
-                                            appendCharacters(
-                                                    stack[currentPtr].node,
-                                                    TreeBuilder.ISINDEX_PROMPT,
-                                                    0,
-                                                    TreeBuilder.ISINDEX_PROMPT.length);
-                                        }
-                                        HtmlAttributes inputAttributes = new HtmlAttributes(
-                                                0);
-                                        inputAttributes.addAttribute(
-                                                AttributeName.NAME,
-                                                Portability.newStringFromLiteral("isindex")
-                                                // [NOCPP[
-                                                , XmlViolationPolicy.ALLOW
-                                        // ]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(
-                                                "http://www.w3.org/1999/xhtml",
-                                                "input", inputAttributes,
-                                                formPointer);
-                                        // XXX localization
-                                        pop(); // label
-                                        appendVoidElementToCurrentMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                ElementName.HR,
-                                                HtmlAttributes.EMPTY_ATTRIBUTES);
-                                        pop(); // form
-                                        selfClosing = false;
-                                        // Portability.delete(formAttrs);
-                                        // Portability.delete(inputAttributes);
-                                        // Don't delete attributes, they are deleted later
-                                        break starttagloop;
-                                    case TEXTAREA:
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes,
-                                                formPointer);
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RCDATA, elementName);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        needToDropLF = true;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case XMP:
-                                        implicitlyCloseP();
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RAWTEXT, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case NOSCRIPT:
-                                        if (!scriptingEnabled) {
-                                            reconstructTheActiveFormattingElements();
-                                            appendToCurrentNodeAndPushElementMayFoster(
-                                                    "http://www.w3.org/1999/xhtml",
-                                                    elementName, attributes);
-                                            attributes = null; // CPP
-                                            break starttagloop;
-                                        } else {
-                                            // fall through
-                                        }
-                                    case NOFRAMES:
-                                    case IFRAME:
-                                    case NOEMBED:
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RAWTEXT, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case SELECT:
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes,
-                                                formPointer);
-                                        switch (mode) {
-                                            case IN_TABLE:
-                                            case IN_CAPTION:
-                                            case IN_COLUMN_GROUP:
-                                            case IN_TABLE_BODY:
-                                            case IN_ROW:
-                                            case IN_CELL:
-                                                mode = IN_SELECT_IN_TABLE;
-                                                break;
-                                            default:
-                                                mode = IN_SELECT;
-                                                break;
-                                        }
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case OPTGROUP:
-                                    case OPTION:
-                                        /*
-                                         * If the stack of open elements has an
-                                         * option element in scope, then act as
-                                         * if an end tag with the tag name
-                                         * "option" had been seen.
-                                         */
-                                        if (findLastInScope("option") != TreeBuilder.NOT_FOUND_ON_STACK) {
-                                            optionendtagloop: for (;;) {
-                                                if (isCurrent("option")) {
-                                                    pop();
-                                                    break optionendtagloop;
-                                                }
-
-                                                eltPos = currentPtr;
-                                                for (;;) {
-                                                    if (stack[eltPos].name == "option") {
-                                                        generateImpliedEndTags();
-                                                        if (!isCurrent("option")) {
-                                                            err("End tag \u201C"
-                                                                    + name
-                                                                    + "\u201D seen but there were unclosed elements.");
-                                                        }
-                                                        while (currentPtr >= eltPos) {
-                                                            pop();
-                                                        }
-                                                        break optionendtagloop;
-                                                    }
-                                                    eltPos--;
-                                                }
-                                            }
-                                        }
-                                        /*
-                                         * Reconstruct the active formatting
-                                         * elements, if any.
-                                         */
-                                        reconstructTheActiveFormattingElements();
-                                        /*
-                                         * Insert an HTML element for the token.
-                                         */
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, 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.
-                                         */
-                                        eltPos = findLastInScope("ruby");
-                                        if (eltPos != NOT_FOUND_ON_STACK) {
-                                            generateImpliedEndTags();
-                                        }
-                                        if (eltPos != currentPtr) {
-                                            err("Unclosed children in \u201Cruby\u201D.");
-                                            while (currentPtr > eltPos) {
-                                                pop();
-                                            }
-                                        }
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case MATH:
-                                        reconstructTheActiveFormattingElements();
-                                        attributes.adjustForMath();
-                                        if (selfClosing) {
-                                            appendVoidElementToCurrentMayFoster(
-                                                    "http://www.w3.org/1998/Math/MathML",
-                                                    elementName, attributes);
-                                            selfClosing = false;
-                                        } else {
-                                            appendToCurrentNodeAndPushElementMayFoster(
-                                                    "http://www.w3.org/1998/Math/MathML",
-                                                    elementName, attributes);
-                                            foreignFlag = TreeBuilder.IN_FOREIGN;
-                                        }
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case SVG:
-                                        reconstructTheActiveFormattingElements();
-                                        attributes.adjustForSvg();
-                                        if (selfClosing) {
-                                            appendVoidElementToCurrentMayFosterCamelCase(
-                                                    "http://www.w3.org/2000/svg",
-                                                    elementName, attributes);
-                                            selfClosing = false;
-                                        } else {
-                                            appendToCurrentNodeAndPushElementMayFoster(
-                                                    "http://www.w3.org/2000/svg",
-                                                    elementName, attributes);
-                                            foreignFlag = TreeBuilder.IN_FOREIGN;
-                                        }
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case CAPTION:
-                                    case COL:
-                                    case COLGROUP:
-                                    case TBODY_OR_THEAD_OR_TFOOT:
-                                    case TR:
-                                    case TD_OR_TH:
-                                    case FRAME:
-                                    case FRAMESET:
-                                    case HEAD:
-                                        err("Stray start tag \u201C" + name
-                                                + "\u201D.");
-                                        break starttagloop;
-                                    case OUTPUT_OR_LABEL:
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes,
-                                                formPointer);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    default:
-                                        reconstructTheActiveFormattingElements();
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
+                                    }
+                                }
+                                /*
+                                 * Reconstruct the active formatting elements,
+                                 * if any.
+                                 */
+                                reconstructTheActiveFormattingElements();
+                                /*
+                                 * Insert an HTML element for the token.
+                                 */
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, 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.
+                                 */
+                                eltPos = findLastInScope("ruby");
+                                if (eltPos != NOT_FOUND_ON_STACK) {
+                                    generateImpliedEndTags();
                                 }
-                            }
-                        case IN_HEAD:
-                            inheadloop: for (;;) {
-                                switch (group) {
-                                    case HTML:
-                                        err("Stray \u201Chtml\u201D start tag.");
-                                        addAttributesToHtml(attributes);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case BASE:
-                                    case COMMAND:
-                                        appendVoidElementToCurrentMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        selfClosing = false;
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case META:
-                                    case LINK:
-                                        // Fall through to IN_HEAD_NOSCRIPT
-                                        break inheadloop;
-                                    case TITLE:
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RCDATA, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case NOSCRIPT:
-                                        if (scriptingEnabled) {
-                                            appendToCurrentNodeAndPushElement(
-                                                    "http://www.w3.org/1999/xhtml",
-                                                    elementName, attributes);
-                                            originalMode = mode;
-                                            mode = TEXT;
-                                            tokenizer.setStateAndEndTagExpectation(
-                                                    Tokenizer.RAWTEXT,
-                                                    elementName);
-                                        } else {
-                                            appendToCurrentNodeAndPushElementMayFoster(
-                                                    "http://www.w3.org/1999/xhtml",
-                                                    elementName, attributes);
-                                            mode = IN_HEAD_NOSCRIPT;
-                                        }
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case SCRIPT:
-                                        // XXX need to manage much more stuff
-                                        // here if
-                                        // supporting
-                                        // document.write()
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.SCRIPT_DATA, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case STYLE:
-                                    case NOFRAMES:
-                                        appendToCurrentNodeAndPushElementMayFoster(
-                                                "http://www.w3.org/1999/xhtml",
-                                                elementName, attributes);
-                                        originalMode = mode;
-                                        mode = TEXT;
-                                        tokenizer.setStateAndEndTagExpectation(
-                                                Tokenizer.RAWTEXT, elementName);
-                                        attributes = null; // CPP
-                                        break starttagloop;
-                                    case HEAD:
-                                        /* Parse error. */
-                                        err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
-                                        /* Ignore the token. */
-                                        break starttagloop;
-                                    default:
+                                if (eltPos != currentPtr) {
+                                    err("Unclosed children in \u201Cruby\u201D.");
+                                    while (currentPtr > eltPos) {
                                         pop();
-                                        mode = AFTER_HEAD;
-                                        continue starttagloop;
+                                    }
                                 }
-                            }
-                        case IN_HEAD_NOSCRIPT:
-                            switch (group) {
-                                case HTML:
-                                    // XXX did Hixie really mean to omit "base"
-                                    // here?
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case LINK:
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case MATH:
+                                reconstructTheActiveFormattingElements();
+                                attributes.adjustForMath();
+                                if (selfClosing) {
                                     appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
+                                            "http://www.w3.org/1998/Math/MathML",
+                                            elementName, attributes);
+                                    selfClosing = false;
+                                } else {
+                                    appendToCurrentNodeAndPushElementMayFoster(
+                                            "http://www.w3.org/1998/Math/MathML",
+                                            elementName, attributes);
+                                    inForeign = true;
+                                }
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case SVG:
+                                reconstructTheActiveFormattingElements();
+                                attributes.adjustForSvg();
+                                if (selfClosing) {
+                                    appendVoidElementToCurrentMayFosterCamelCase(
+                                            "http://www.w3.org/2000/svg",
                                             elementName, attributes);
                                     selfClosing = false;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case META:
-                                    checkMetaCharset(attributes);
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
+                                } else {
+                                    appendToCurrentNodeAndPushElementMayFoster(
+                                            "http://www.w3.org/2000/svg",
                                             elementName, attributes);
-                                    selfClosing = false;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case STYLE:
-                                case NOFRAMES:
+                                    inForeign = true;
+                                }
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case CAPTION:
+                            case COL:
+                            case COLGROUP:
+                            case TBODY_OR_THEAD_OR_TFOOT:
+                            case TR:
+                            case TD_OR_TH:
+                            case FRAME:
+                            case FRAMESET:
+                            case HEAD:
+                                err("Stray start tag \u201C" + name + "\u201D.");
+                                break starttagloop;
+                            case OUTPUT_OR_LABEL:
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes, formPointer);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            default:
+                                reconstructTheActiveFormattingElements();
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                        }
+                    }
+                case IN_HEAD:
+                    inheadloop: for (;;) {
+                        switch (group) {
+                            case HTML:
+                                err("Stray \u201Chtml\u201D start tag.");
+                                addAttributesToHtml(attributes);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case BASE:
+                            case COMMAND:
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                selfClosing = false;
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case META:
+                            case LINK:
+                                // Fall through to IN_HEAD_NOSCRIPT
+                                break inheadloop;
+                            case TITLE:
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RCDATA, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case NOSCRIPT:
+                                if (scriptingEnabled) {
                                     appendToCurrentNodeAndPushElement(
                                             "http://www.w3.org/1999/xhtml",
                                             elementName, attributes);
                                     originalMode = mode;
                                     mode = TEXT;
                                     tokenizer.setStateAndEndTagExpectation(
                                             Tokenizer.RAWTEXT, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case HEAD:
-                                    err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
-                                    break starttagloop;
-                                case NOSCRIPT:
-                                    err("Start tag for \u201Cnoscript\u201D seen when \u201Cnoscript\u201D was already open.");
-                                    break starttagloop;
-                                default:
-                                    err("Bad start tag in \u201C" + name
-                                            + "\u201D in \u201Chead\u201D.");
-                                    pop();
-                                    mode = IN_HEAD;
-                                    continue;
-                            }
-                        case IN_COLUMN_GROUP:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case COL:
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    selfClosing = false;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    if (currentPtr == 0) {
-                                        assert fragment;
-                                        err("Garbage in \u201Ccolgroup\u201D fragment.");
-                                        break starttagloop;
-                                    }
-                                    pop();
-                                    mode = IN_TABLE;
-                                    continue;
-                            }
-                        case IN_SELECT_IN_TABLE:
-                            switch (group) {
-                                case CAPTION:
-                                case TBODY_OR_THEAD_OR_TFOOT:
-                                case TR:
-                                case TD_OR_TH:
-                                case TABLE:
-                                    err("\u201C"
-                                            + name
-                                            + "\u201D start tag with \u201Cselect\u201D open.");
-                                    eltPos = findLastInTableScope("select");
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        assert fragment;
-                                        break starttagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
-                                    }
-                                    while (currentPtr >= eltPos) {
-                                        pop();
-                                    }
-                                    resetTheInsertionMode();
-                                    continue;
-                                default:
-                                    // fall through to IN_SELECT
-                            }
-                        case IN_SELECT:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case OPTION:
-                                    if (isCurrent("option")) {
-                                        pop();
-                                    }
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case OPTGROUP:
-                                    if (isCurrent("option")) {
-                                        pop();
-                                    }
-                                    if (isCurrent("optgroup")) {
-                                        pop();
-                                    }
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case SELECT:
-                                    err("\u201Cselect\u201D start tag where end tag expected.");
-                                    eltPos = findLastInTableScope(name);
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        assert fragment;
-                                        err("No \u201Cselect\u201D in table scope.");
-                                        break starttagloop;
-                                    } else {
-                                        while (currentPtr >= eltPos) {
-                                            pop();
-                                        }
-                                        resetTheInsertionMode();
-                                        break starttagloop;
-                                    }
-                                case INPUT:
-                                case TEXTAREA:
-                                case KEYGEN:
-                                    err("\u201C"
-                                            + name
-                                            + "\u201D start tag seen in \u201Cselect\2201D.");
-                                    eltPos = findLastInTableScope("select");
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        assert fragment;
-                                        break starttagloop;
-                                    }
-                                    while (currentPtr >= eltPos) {
-                                        pop();
-                                    }
-                                    resetTheInsertionMode();
-                                    continue;
-                                case SCRIPT:
-                                    // XXX need to manage much more stuff
-                                    // here if
-                                    // supporting
-                                    // document.write()
+                                } else {
                                     appendToCurrentNodeAndPushElementMayFoster(
                                             "http://www.w3.org/1999/xhtml",
                                             elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.SCRIPT_DATA, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    err("Stray \u201C" + name
-                                            + "\u201D start tag.");
-                                    break starttagloop;
+                                    mode = IN_HEAD_NOSCRIPT;
+                                }
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case SCRIPT:
+                                // XXX need to manage much more stuff
+                                // here if
+                                // supporting
+                                // document.write()
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.SCRIPT_DATA, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case STYLE:
+                            case NOFRAMES:
+                                appendToCurrentNodeAndPushElementMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName, attributes);
+                                originalMode = mode;
+                                mode = TEXT;
+                                tokenizer.setStateAndEndTagExpectation(
+                                        Tokenizer.RAWTEXT, elementName);
+                                attributes = null; // CPP
+                                break starttagloop;
+                            case HEAD:
+                                /* Parse error. */
+                                err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
+                                /* Ignore the token. */
+                                break starttagloop;
+                            default:
+                                pop();
+                                mode = AFTER_HEAD;
+                                continue starttagloop;
+                        }
+                    }
+                case IN_HEAD_NOSCRIPT:
+                    switch (group) {
+                        case HTML:
+                            // XXX did Hixie really mean to omit "base"
+                            // here?
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case LINK:
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case META:
+                            checkMetaCharset(attributes);
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case STYLE:
+                        case NOFRAMES:
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.RAWTEXT, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case HEAD:
+                            err("Start tag for \u201Chead\u201D seen when \u201Chead\u201D was already open.");
+                            break starttagloop;
+                        case NOSCRIPT:
+                            err("Start tag for \u201Cnoscript\u201D seen when \u201Cnoscript\u201D was already open.");
+                            break starttagloop;
+                        default:
+                            err("Bad start tag in \u201C" + name
+                                    + "\u201D in \u201Chead\u201D.");
+                            pop();
+                            mode = IN_HEAD;
+                            continue;
+                    }
+                case IN_COLUMN_GROUP:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case COL:
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            if (currentPtr == 0) {
+                                assert fragment;
+                                err("Garbage in \u201Ccolgroup\u201D fragment.");
+                                break starttagloop;
                             }
-                        case AFTER_BODY:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    err("Stray \u201C" + name
-                                            + "\u201D start tag.");
-                                    mode = framesetOk ? FRAMESET_OK : IN_BODY;
-                                    continue;
+                            pop();
+                            mode = IN_TABLE;
+                            continue;
+                    }
+                case IN_SELECT_IN_TABLE:
+                    switch (group) {
+                        case CAPTION:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                        case TD_OR_TH:
+                        case TABLE:
+                            err("\u201C"
+                                    + name
+                                    + "\u201D start tag with \u201Cselect\u201D open.");
+                            eltPos = findLastInTableScope("select");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment;
+                                break starttagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
                             }
-                        case IN_FRAMESET:
-                            switch (group) {
-                                case FRAMESET:
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case FRAME:
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    selfClosing = false;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    // fall through to AFTER_FRAMESET
+                            resetTheInsertionMode();
+                            continue;
+                        default:
+                            // fall through to IN_SELECT
+                    }
+                case IN_SELECT:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case OPTION:
+                            if (isCurrent("option")) {
+                                pop();
+                            }
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case OPTGROUP:
+                            if (isCurrent("option")) {
+                                pop();
+                            }
+                            if (isCurrent("optgroup")) {
+                                pop();
                             }
-                        case AFTER_FRAMESET:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case NOFRAMES:
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.RAWTEXT, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    err("Stray \u201C" + name
-                                            + "\u201D start tag.");
-                                    break starttagloop;
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case SELECT:
+                            err("\u201Cselect\u201D start tag where end tag expected.");
+                            eltPos = findLastInTableScope(name);
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment;
+                                err("No \u201Cselect\u201D in table scope.");
+                                break starttagloop;
+                            } else {
+                                while (currentPtr >= eltPos) {
+                                    pop();
+                                }
+                                resetTheInsertionMode();
+                                break starttagloop;
+                            }
+                        case INPUT:
+                        case TEXTAREA:
+                        case KEYGEN:
+                            err("\u201C"
+                                    + name
+                                    + "\u201D start tag seen in \u201Cselect\2201D.");
+                            eltPos = findLastInTableScope("select");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment;
+                                break starttagloop;
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
                             }
-                        case INITIAL:
+                            resetTheInsertionMode();
+                            continue;
+                        case SCRIPT:
+                            // XXX need to manage much more stuff
+                            // here if
+                            // supporting
+                            // document.write()
+                            appendToCurrentNodeAndPushElementMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.SCRIPT_DATA, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            err("Stray \u201C" + name + "\u201D start tag.");
+                            break starttagloop;
+                    }
+                case AFTER_BODY:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            err("Stray \u201C" + name + "\u201D start tag.");
+                            mode = framesetOk ? FRAMESET_OK : IN_BODY;
+                            continue;
+                    }
+                case IN_FRAMESET:
+                    switch (group) {
+                        case FRAMESET:
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case FRAME:
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            // fall through to AFTER_FRAMESET
+                    }
+                case AFTER_FRAMESET:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case NOFRAMES:
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.RAWTEXT, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            err("Stray \u201C" + name + "\u201D start tag.");
+                            break starttagloop;
+                    }
+                case INITIAL:
+                    /*
+                     * 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]
+                    /*
+                     * 
+                     * Set the document to quirks mode.
+                     */
+                    documentModeInternal(DocumentMode.QUIRKS_MODE, null, null,
+                            false);
+                    /*
+                     * Then, switch to the root element mode of the tree
+                     * construction stage
+                     */
+                    mode = BEFORE_HTML;
+                    /*
+                     * and reprocess the current token.
+                     */
+                    continue;
+                case BEFORE_HTML:
+                    switch (group) {
+                        case HTML:
+                            // optimize error check and streaming SAX by
+                            // hoisting
+                            // "html" handling here.
+                            if (attributes == HtmlAttributes.EMPTY_ATTRIBUTES) {
+                                // This has the right magic side effect
+                                // that
+                                // it
+                                // makes attributes in SAX Tree mutable.
+                                appendHtmlElementToDocumentAndPush();
+                            } else {
+                                appendHtmlElementToDocumentAndPush(attributes);
+                            }
+                            // XXX application cache should fire here
+                            mode = BEFORE_HEAD;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
                             /*
-                             * Parse error.
+                             * Create an HTMLElement node with the tag name
+                             * html, in the HTML namespace. Append it to the
+                             * Document object.
                              */
-                            // [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]
+                            appendHtmlElementToDocumentAndPush();
+                            /* Switch to the main mode */
+                            mode = BEFORE_HEAD;
                             /*
-                             * 
-                             * Set the document to quirks mode.
-                             */
-                            documentModeInternal(DocumentMode.QUIRKS_MODE,
-                                    null, null, false);
-                            /*
-                             * Then, switch to the root element mode of the tree
-                             * construction stage
-                             */
-                            mode = BEFORE_HTML;
-                            /*
-                             * and reprocess the current token.
+                             * reprocess the current token.
                              */
                             continue;
-                        case BEFORE_HTML:
-                            switch (group) {
-                                case HTML:
-                                    // optimize error check and streaming SAX by
-                                    // hoisting
-                                    // "html" handling here.
-                                    if (attributes == HtmlAttributes.EMPTY_ATTRIBUTES) {
-                                        // This has the right magic side effect
-                                        // that
-                                        // it
-                                        // makes attributes in SAX Tree mutable.
-                                        appendHtmlElementToDocumentAndPush();
-                                    } else {
-                                        appendHtmlElementToDocumentAndPush(attributes);
-                                    }
-                                    // XXX application cache should fire here
-                                    mode = BEFORE_HEAD;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    /*
-                                     * Create an HTMLElement node with the tag
-                                     * name html, in the HTML namespace. Append
-                                     * it to the Document object.
-                                     */
-                                    appendHtmlElementToDocumentAndPush();
-                                    /* Switch to the main mode */
-                                    mode = BEFORE_HEAD;
-                                    /*
-                                     * reprocess the current token.
-                                     */
-                                    continue;
-                            }
-                        case BEFORE_HEAD:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                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.
-                                     */
-                                    appendToCurrentNodeAndPushHeadElement(attributes);
-                                    /*
-                                     * 
-                                     * Change the insertion mode to "in head".
-                                     */
-                                    mode = IN_HEAD;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-
-                                    /*
-                                     * Any other start tag token
-                                     */
-
-                                    /*
-                                     * Act as if a start tag token with the tag
-                                     * name "head" and no attributes had been
-                                     * seen,
-                                     */
-                                    appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
-                                    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.
-                                     */
-                                    continue;
+                    }
+                case BEFORE_HEAD:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        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.
+                             */
+                            appendToCurrentNodeAndPushHeadElement(attributes);
+                            /*
+                             * Change the insertion mode to "in head".
+                             */
+                            mode = IN_HEAD;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            /*
+                             * Any other start tag token
+                             * 
+                             * Act as if a start tag token with the tag name
+                             * "head" and no attributes had been seen,
+                             */
+                            appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+                            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.
+                             */
+                            continue;
+                    }
+                case AFTER_HEAD:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case BODY:
+                            if (attributes.getLength() == 0) {
+                                // This has the right magic side effect
+                                // that
+                                // it
+                                // makes attributes in SAX Tree mutable.
+                                appendToCurrentNodeAndPushBodyElement();
+                            } else {
+                                appendToCurrentNodeAndPushBodyElement(attributes);
                             }
-                        case AFTER_HEAD:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case BODY:
-                                    if (attributes.getLength() == 0) {
-                                        // This has the right magic side effect
-                                        // that
-                                        // it
-                                        // makes attributes in SAX Tree mutable.
-                                        appendToCurrentNodeAndPushBodyElement();
-                                    } else {
-                                        appendToCurrentNodeAndPushBodyElement(attributes);
-                                    }
-                                    framesetOk = false;
-                                    mode = IN_BODY;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case FRAMESET:
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    mode = IN_FRAMESET;
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case BASE:
-                                    err("\u201Cbase\u201D element outside \u201Chead\u201D.");
-                                    pushHeadPointerOntoStack();
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    selfClosing = false;
-                                    pop(); // head
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case LINK:
-                                    err("\u201Clink\u201D element outside \u201Chead\u201D.");
-                                    pushHeadPointerOntoStack();
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    selfClosing = false;
-                                    pop(); // head
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case META:
-                                    err("\u201Cmeta\u201D element outside \u201Chead\u201D.");
-                                    checkMetaCharset(attributes);
-                                    pushHeadPointerOntoStack();
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    selfClosing = false;
-                                    pop(); // head
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case SCRIPT:
-                                    err("\u201Cscript\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
-                                    pushHeadPointerOntoStack();
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.SCRIPT_DATA, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case STYLE:
-                                case NOFRAMES:
-                                    err("\u201C"
-                                            + name
-                                            + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
-                                    pushHeadPointerOntoStack();
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.RAWTEXT, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case TITLE:
-                                    err("\u201Ctitle\u201D element outside \u201Chead\u201D.");
-                                    pushHeadPointerOntoStack();
-                                    appendToCurrentNodeAndPushElement(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.RCDATA, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                case HEAD:
-                                    err("Stray start tag \u201Chead\u201D.");
-                                    break starttagloop;
-                                default:
-                                    appendToCurrentNodeAndPushBodyElement();
-                                    mode = FRAMESET_OK;
-                                    continue;
-                            }
-                        case AFTER_AFTER_BODY:
-                            switch (group) {
-                                case HTML:
-                                    err("Stray \u201Chtml\u201D start tag.");
-                                    addAttributesToHtml(attributes);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    err("Stray \u201C" + name
-                                            + "\u201D start tag.");
-                                    fatal();
-                                    mode = framesetOk ? FRAMESET_OK : IN_BODY;
-                                    continue;
-                            }
-                        case AFTER_AFTER_FRAMESET:
-                            switch (group) {
-                                case NOFRAMES:
-                                    appendToCurrentNodeAndPushElementMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName, attributes);
-                                    originalMode = mode;
-                                    mode = TEXT;
-                                    tokenizer.setStateAndEndTagExpectation(
-                                            Tokenizer.SCRIPT_DATA, elementName);
-                                    attributes = null; // CPP
-                                    break starttagloop;
-                                default:
-                                    err("Stray \u201C" + name
-                                            + "\u201D start tag.");
-                                    break starttagloop;
-                            }
-                        case TEXT:
-                            assert false;
-                            break starttagloop; // Avoid infinite loop if the assertion fails
+                            framesetOk = false;
+                            mode = IN_BODY;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case FRAMESET:
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            mode = IN_FRAMESET;
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case BASE:
+                            err("\u201Cbase\u201D element outside \u201Chead\u201D.");
+                            pushHeadPointerOntoStack();
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            pop(); // head
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case LINK:
+                            err("\u201Clink\u201D element outside \u201Chead\u201D.");
+                            pushHeadPointerOntoStack();
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            pop(); // head
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case META:
+                            err("\u201Cmeta\u201D element outside \u201Chead\u201D.");
+                            checkMetaCharset(attributes);
+                            pushHeadPointerOntoStack();
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            selfClosing = false;
+                            pop(); // head
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case SCRIPT:
+                            err("\u201Cscript\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+                            pushHeadPointerOntoStack();
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.SCRIPT_DATA, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case STYLE:
+                        case NOFRAMES:
+                            err("\u201C"
+                                    + name
+                                    + "\u201D element between \u201Chead\u201D and \u201Cbody\u201D.");
+                            pushHeadPointerOntoStack();
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.RAWTEXT, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case TITLE:
+                            err("\u201Ctitle\u201D element outside \u201Chead\u201D.");
+                            pushHeadPointerOntoStack();
+                            appendToCurrentNodeAndPushElement(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.RCDATA, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        case HEAD:
+                            err("Stray start tag \u201Chead\u201D.");
+                            break starttagloop;
+                        default:
+                            appendToCurrentNodeAndPushBodyElement();
+                            mode = FRAMESET_OK;
+                            continue;
                     }
+                case AFTER_AFTER_BODY:
+                    switch (group) {
+                        case HTML:
+                            err("Stray \u201Chtml\u201D start tag.");
+                            addAttributesToHtml(attributes);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            err("Stray \u201C" + name + "\u201D start tag.");
+                            fatal();
+                            mode = framesetOk ? FRAMESET_OK : IN_BODY;
+                            continue;
+                    }
+                case AFTER_AFTER_FRAMESET:
+                    switch (group) {
+                        case NOFRAMES:
+                            appendToCurrentNodeAndPushElementMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName, attributes);
+                            originalMode = mode;
+                            mode = TEXT;
+                            tokenizer.setStateAndEndTagExpectation(
+                                    Tokenizer.SCRIPT_DATA, elementName);
+                            attributes = null; // CPP
+                            break starttagloop;
+                        default:
+                            err("Stray \u201C" + name + "\u201D start tag.");
+                            break starttagloop;
+                    }
+                case TEXT:
+                    assert false;
+                    break starttagloop; // Avoid infinite loop if the assertion
+                                        // fails
             }
         }
-        if (needsPostProcessing && foreignFlag == TreeBuilder.IN_FOREIGN
-                && !hasForeignInScope()) {
+        if (needsPostProcessing && inForeign                && !hasForeignInScope()) {
             /*
              * If, after doing so, the insertion mode is still "in foreign
              * content", but there is no element in scope that has a namespace
              * other than the HTML namespace, switch the insertion mode to the
              * secondary insertion mode.
              */
-            foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+            inForeign = false;
         }
-        if (selfClosing) {
-            err("Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.");
+        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);
         }
     }
 
     /**
      * 
@@ -3228,34 +3194,34 @@ public abstract class TreeBuilder<T> imp
                 case IN_CAPTION:
                     switch (group) {
                         case CAPTION:
                             eltPos = findLastInTableScope("caption");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 break endtagloop;
                             }
                             generateImpliedEndTags();
-                            if (currentPtr != eltPos) {
-                                err("Unclosed elements on stack.");
+                            if (errorHandler != null && currentPtr != eltPos) {
+                                errNoCheck("Unclosed elements on stack.");
                             }
                             while (currentPtr >= eltPos) {
                                 pop();
                             }
                             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                             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) {
                                 break endtagloop;
                             }
                             generateImpliedEndTags();
-                            if (currentPtr != eltPos) {
-                                err("Unclosed elements on stack.");
+                            if (errorHandler != null && currentPtr != eltPos) {
+                                errNoCheck("Unclosed elements on stack.");
                             }
                             while (currentPtr >= eltPos) {
                                 pop();
                             }
                             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                             mode = IN_TABLE;
                             continue;
                         case BODY:
@@ -3274,18 +3240,18 @@ public abstract class TreeBuilder<T> imp
                     switch (group) {
                         case TD_OR_TH:
                             eltPos = findLastInTableScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                                 break endtagloop;
                             }
                             generateImpliedEndTags();
-                            if (!isCurrent(name)) {
-                                err("Unclosed elements.");
+                            if (errorHandler != null && !isCurrent(name)) {
+                                errNoCheck("Unclosed elements.");
                             }
                             while (currentPtr >= eltPos) {
                                 pop();
                             }
                             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                             mode = IN_ROW;
                             break endtagloop;
                         case TABLE:
@@ -3368,20 +3334,20 @@ public abstract class TreeBuilder<T> imp
                         case FIELDSET:
                         case BUTTON:
                         case ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION:
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                             } else {
                                 generateImpliedEndTags();
-                                if (!isCurrent(name)) {
-                                    err("End tag \u201C"
-                                            + name
-                                            + "\u201D seen but there were unclosed elements.");
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errNoCheck("End tag \u201C"
+                                               + name
+                                               + "\u201D seen but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                             }
                             break endtagloop;
                         case FORM:
                             if (formPointer == null) {
@@ -3391,95 +3357,95 @@ public abstract class TreeBuilder<T> imp
                             Portability.releaseElement(formPointer);
                             formPointer = null;
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                                 break endtagloop;
                             }
                             generateImpliedEndTags();
-                            if (!isCurrent(name)) {
-                                err("End tag \u201C"
+                            if (errorHandler != null && !isCurrent(name)) {
+                                errNoCheck("End tag \u201C"
                                         + name
                                         + "\u201D seen but there were unclosed elements.");
                             }
                             removeFromStack(eltPos);
                             break endtagloop;
                         case P:
                             eltPos = findLastInScope("p");
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("No \u201Cp\u201D element in scope but a \u201Cp\u201D end tag seen.");
                                 // XXX inline this case
-                                if (foreignFlag == TreeBuilder.IN_FOREIGN) {
+                                if (inForeign) {
                                     err("HTML start tag \u201C"
                                             + name
                                             + "\u201D in a foreign namespace context.");
                                     while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                                         pop();
                                     }
-                                    foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+                                    inForeign = false;
                                 }
                                 appendVoidElementToCurrentMayFoster(
                                         "http://www.w3.org/1999/xhtml",
                                         elementName,
                                         HtmlAttributes.EMPTY_ATTRIBUTES);
                                 break endtagloop;
                             }
                             generateImpliedEndTagsExceptFor("p");
                             assert eltPos != TreeBuilder.NOT_FOUND_ON_STACK;
-                            if (eltPos != currentPtr) {
-                                err("End tag for \u201Cp\u201D seen, but there were unclosed elements.");
+                            if (errorHandler != null && eltPos != currentPtr) {
+                                errNoCheck("End tag for \u201Cp\u201D seen, but there were unclosed elements.");
                             }
                             while (currentPtr >= eltPos) {
                                 pop();
                             }
                             break endtagloop;
                         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.");
                             } else {
                                 generateImpliedEndTagsExceptFor(name);
-                                if (eltPos != currentPtr) {
-                                    err("End tag for \u201Cli\u201D seen, but there were unclosed elements.");
+                                if (errorHandler != null && eltPos != currentPtr) {
+                                    errNoCheck("End tag for \u201Cli\u201D seen, but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                             }
                             break endtagloop;
                         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.");
                             } else {
                                 generateImpliedEndTagsExceptFor(name);
-                                if (eltPos != currentPtr) {
-                                    err("End tag for \u201C"
-                                            + name
-                                            + "\u201D seen, but there were unclosed elements.");
+                                if (errorHandler != null && eltPos != currentPtr) {
+                                    errNoCheck("End tag for \u201C"
+                                               + name
+                                               + "\u201D seen, but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                             }
                             break endtagloop;
                         case H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
                             eltPos = findLastInScopeHn();
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                             } else {
                                 generateImpliedEndTags();
-                                if (!isCurrent(name)) {
-                                    err("End tag \u201C"
-                                            + name
-                                            + "\u201D seen but there were unclosed elements.");
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errNoCheck("End tag \u201C"
+                                               + name
+                                               + "\u201D seen but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                             }
                             break endtagloop;
                         case A:
                         case B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
@@ -3489,37 +3455,37 @@ public abstract class TreeBuilder<T> imp
                             break endtagloop;
                         case OBJECT:
                         case MARQUEE_OR_APPLET:
                             eltPos = findLastInScope(name);
                             if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                             } else {
                                 generateImpliedEndTags();
-                                if (!isCurrent(name)) {
-                                    err("End tag \u201C"
-                                            + name
-                                            + "\u201D seen but there were unclosed elements.");
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errNoCheck("End tag \u201C"
+                                               + name
+                                               + "\u201D seen but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                                 clearTheListOfActiveFormattingElementsUpToTheLastMarker();
                             }
                             break endtagloop;
                         case BR:
                             err("End tag \u201Cbr\u201D.");
-                            if (foreignFlag == TreeBuilder.IN_FOREIGN) {
+                            if (inForeign) {
                                 err("HTML start tag \u201C"
-                                        + name
-                                        + "\u201D in a foreign namespace context.");
+                                    + name
+                                    + "\u201D in a foreign namespace context.");
                                 while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
                                     pop();
                                 }
-                                foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+                                inForeign = false;
                             }
                             reconstructTheActiveFormattingElements();
                             appendVoidElementToCurrentMayFoster(
                                     "http://www.w3.org/1999/xhtml",
                                     elementName,
                                     HtmlAttributes.EMPTY_ATTRIBUTES);
                             break endtagloop;
                         case AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR:
@@ -3551,20 +3517,20 @@ public abstract class TreeBuilder<T> imp
                                 break endtagloop;
                             }
 
                             eltPos = currentPtr;
                             for (;;) {
                                 StackNode<T> node = stack[eltPos];
                                 if (node.name == name) {
                                     generateImpliedEndTags();
-                                    if (!isCurrent(name)) {
-                                        err("End tag \u201C"
-                                                + name
-                                                + "\u201D seen but there were unclosed elements.");
+                                    if (errorHandler != null && !isCurrent(name)) {
+                                        errNoCheck("End tag \u201C"
+                                                   + name
+                                                   + "\u201D seen but there were unclosed elements.");
                                     }
                                     while (currentPtr >= eltPos) {
                                         pop();
                                     }
                                     break endtagloop;
                                 } else if (node.scoping || node.special) {
                                     err("Stray end tag \u201C" + name
                                             + "\u201D.");
@@ -3828,24 +3794,24 @@ public abstract class TreeBuilder<T> imp
                     pop();
                     if (originalMode == AFTER_HEAD) {
                         silentPop();
                     }
                     mode = originalMode;
                     break endtagloop;
             }
         }
-        if (foreignFlag == TreeBuilder.IN_FOREIGN && !hasForeignInScope()) {
+        if (inForeign && !hasForeignInScope()) {
             /*
              * If, after doing so, the insertion mode is still "in foreign
              * content", but there is no element in scope that has a namespace
              * other than the HTML namespace, switch the insertion mode to the
              * secondary insertion mode.
              */
-            foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+            inForeign = false;
         }
     }
 
     private int findLastInTableScopeOrRootTbodyTheadTfoot() {
         for (int i = currentPtr; i > 0; i--) {
             if (stack[i].group == TreeBuilder.TBODY_OR_THEAD_OR_TFOOT) {
                 return i;
             }
@@ -4040,18 +4006,18 @@ public abstract class TreeBuilder<T> imp
                 systemIdentifier)) {
             return true;
         }
         return false;
     }
 
     private void closeTheCell(int eltPos) throws SAXException {
         generateImpliedEndTags();
-        if (eltPos != currentPtr) {
-            err("Unclosed elements.");
+        if (errorHandler != null && eltPos != currentPtr) {
+            errNoCheck("Unclosed elements.");
         }
         while (currentPtr >= eltPos) {
             pop();
         }
         clearTheListOfActiveFormattingElementsUpToTheLastMarker();
         mode = IN_ROW;
         return;
     }
@@ -4070,17 +4036,17 @@ public abstract class TreeBuilder<T> imp
 
     private void clearStackBackTo(int eltPos) throws SAXException {
         while (currentPtr > eltPos) { // > not >= intentional
             pop();
         }
     }
 
     private void resetTheInsertionMode() {
-        foreignFlag = TreeBuilder.NOT_IN_FOREIGN;
+        inForeign = false;
         StackNode<T> node;
         @Local String name;
         @NsUri String ns;
         for (int i = currentPtr; i >= 0; i--) {
             node = stack[i];
             name = node.name;
             ns = node.ns;
             if (i == 0) {
@@ -4109,17 +4075,17 @@ public abstract class TreeBuilder<T> imp
                 return;
             } else if ("colgroup" == name) {
                 mode = IN_COLUMN_GROUP;
                 return;
             } else if ("table" == name) {
                 mode = IN_TABLE;
                 return;
             } else if ("http://www.w3.org/1999/xhtml" != ns) {
-                foreignFlag = TreeBuilder.IN_FOREIGN;
+                inForeign = true;
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
             } else if ("head" == name) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY; // really
                 return;
             } else if ("body" == name) {
                 mode = framesetOk ? FRAMESET_OK : IN_BODY;
                 return;
@@ -4145,17 +4111,17 @@ public abstract class TreeBuilder<T> imp
      * 
      */
     private void implicitlyCloseP() throws SAXException {
         int eltPos = findLastInScope("p");
         if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
             return;
         }
         generateImpliedEndTagsExceptFor("p");
-        if (eltPos != currentPtr) {
+        if (errorHandler != null && eltPos != currentPtr) {
             err("Unclosed elements.");
         }
         while (currentPtr >= eltPos) {
             pop();
         }
     }
 
     private boolean clearLastStackSlot() {
@@ -4325,18 +4291,18 @@ public abstract class TreeBuilder<T> imp
                 removeFromListOfActiveFormattingElements(formattingEltListPos);
                 return;
             }
             if (!inScope) {
                 err("No element \u201C" + name + "\u201D to close.");
                 return;
             }
             // stackPos now points to the formatting element and it is in scope
-            if (formattingEltStackPos != currentPtr) {
-                err("End tag \u201C" + name + "\u201D violates nesting rules.");
+            if (errorHandler != null && formattingEltStackPos != currentPtr) {
+                errNoCheck("End tag \u201C" + name + "\u201D violates nesting rules.");
             }
             int furthestBlockPos = formattingEltStackPos + 1;
             while (furthestBlockPos <= currentPtr) {
                 StackNode<T> node = stack[furthestBlockPos]; // weak ref
                 if (node.scoping || node.special) {
                     break;
                 }
                 furthestBlockPos++;
@@ -5244,23 +5210,16 @@ public abstract class TreeBuilder<T> imp
      */
     public void setReportingDoctype(boolean reportingDoctype) {
         this.reportingDoctype = reportingDoctype;
     }
 
     // ]NOCPP]
 
     /**
-     * @see nu.validator.htmlparser.common.TokenHandler#inForeign()
-     */
-    public boolean inForeign() throws SAXException {
-        return foreignFlag == IN_FOREIGN;
-    }
-
-    /**
      * Flushes the pending characters. Public for document.write use cases only.
      * @throws SAXException
      */
     public final void flushCharacters() throws SAXException {
         if (charBufferLen > 0) {
             StackNode<T> current = stack[currentPtr];
             if (current.fosterParenting && charBufferContainsNonWhitespace()) {
                 err("Misplaced non-space characters insided a table.");
@@ -5333,33 +5292,33 @@ public abstract class TreeBuilder<T> imp
                         null);
                 stackCopy[i] = newNode;
             } else {
                 stackCopy[i] = listCopy[listIndex];
                 stackCopy[i].retain();
             }
         }
         Portability.retainElement(formPointer);
-        return new StateSnapshot<T>(stackCopy, listCopy, formPointer, headPointer, mode, originalMode, framesetOk, foreignFlag, needToDropLF, quirks);
+        return new StateSnapshot<T>(stackCopy, listCopy, formPointer, headPointer, mode, originalMode, framesetOk, inForeign, needToDropLF, quirks);
     }
 
     public boolean snapshotMatches(TreeBuilderState<T> snapshot) {
         StackNode<T>[] stackCopy = snapshot.getStack();
         int stackLen = snapshot.getStackLength();
         StackNode<T>[] listCopy = snapshot.getListOfActiveFormattingElements();
         int listLen = snapshot.getListOfActiveFormattingElementsLength();
 
         if (stackLen != currentPtr + 1
                 || listLen != listPtr + 1
                 || formPointer != snapshot.getFormPointer()
                 || headPointer != snapshot.getHeadPointer()
                 || mode != snapshot.getMode()
                 || originalMode != snapshot.getOriginalMode()
                 || framesetOk != snapshot.isFramesetOk()
-                || foreignFlag != snapshot.getForeignFlag()
+                || inForeign != snapshot.isInForeign()
                 || needToDropLF != snapshot.isNeedToDropLF()
                 || quirks != snapshot.isQuirks()) { // maybe just assert quirks
             return false;
         }
         for (int i = listLen - 1; i >= 0; i--) {
             if (listCopy[i] == null
                     && listOfActiveFormattingElements[i] == null) {
                 continue;
@@ -5440,17 +5399,17 @@ public abstract class TreeBuilder<T> imp
         formPointer = snapshot.getFormPointer();
         Portability.retainElement(formPointer);
         Portability.releaseElement(headPointer);
         headPointer = snapshot.getHeadPointer();
         Portability.retainElement(headPointer);
         mode = snapshot.getMode();
         originalMode = snapshot.getOriginalMode();
         framesetOk = snapshot.isFramesetOk();
-        foreignFlag = snapshot.getForeignFlag();
+        inForeign = snapshot.isInForeign();
         needToDropLF = snapshot.isNeedToDropLF();
         quirks = snapshot.isQuirks();
     }
 
     private int findInArray(StackNode<T> node, StackNode<T>[] arr) {
         for (int i = listPtr; i >= 0; i--) {
             if (node == arr[i]) {
                 return i;
@@ -5513,21 +5472,22 @@ public abstract class TreeBuilder<T> imp
      * @return the framesetOk
      */
     public boolean isFramesetOk() {
         return framesetOk;
     }
     
     /**
      * Returns the foreignFlag.
-     * 
+     *
+     * @see nu.validator.htmlparser.common.TokenHandler#isInForeign()
      * @return the foreignFlag
      */
-    public int getForeignFlag() {
-        return foreignFlag;
+    public boolean isInForeign() {
+        return inForeign;
     }
 
     /**
      * Returns the needToDropLF.
      * 
      * @return the needToDropLF
      */
     public boolean isNeedToDropLF() {
--- a/parser/html/nsAHtml5TreeBuilderState.h
+++ b/parser/html/nsAHtml5TreeBuilderState.h
@@ -33,16 +33,21 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAHtml5TreeBuilderState_h___
 #define nsAHtml5TreeBuilderState_h___
 
+/**
+ * Interface for exposing the internal state of the HTML5 tree builder.
+ * For more documentation, please see
+ * http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/impl/StateSnapshot.java
+ */
 class nsAHtml5TreeBuilderState {
   public:
   
     virtual jArray<nsHtml5StackNode*,PRInt32> getStack() = 0;
     
     virtual jArray<nsHtml5StackNode*,PRInt32> getListOfActiveFormattingElements() = 0;
     
     virtual PRInt32 getStackLength() = 0;
@@ -54,17 +59,17 @@ class nsAHtml5TreeBuilderState {
     virtual nsIContent** getHeadPointer() = 0;
 
     virtual PRInt32 getMode() = 0;
 
     virtual PRInt32 getOriginalMode() = 0;
 
     virtual PRBool isFramesetOk() = 0;
 
-    virtual PRInt32 getForeignFlag() = 0;
+    virtual PRBool isInForeign() = 0;
 
     virtual PRBool isNeedToDropLF() = 0;
 
     virtual PRBool isQuirks() = 0;
     
     virtual ~nsAHtml5TreeBuilderState() {
     }
 };
--- a/parser/html/nsHtml5AtomList.h
+++ b/parser/html/nsHtml5AtomList.h
@@ -4,28 +4,28 @@ HTML5_ATOM(textarea, "textarea")
 HTML5_ATOM(style, "style")
 HTML5_ATOM(xmp, "xmp")
 HTML5_ATOM(iframe, "iframe")
 HTML5_ATOM(noembed, "noembed")
 HTML5_ATOM(noframes, "noframes")
 HTML5_ATOM(noscript, "noscript")
 HTML5_ATOM(plaintext, "plaintext")
 HTML5_ATOM(script, "script")
-HTML5_ATOM(table, "table")
 HTML5_ATOM(caption, "caption")
 HTML5_ATOM(p, "p")
 HTML5_ATOM(address, "address")
 HTML5_ATOM(div, "div")
 HTML5_ATOM(a, "a")
 HTML5_ATOM(nobr, "nobr")
 HTML5_ATOM(input, "input")
 HTML5_ATOM(option, "option")
 HTML5_ATOM(ruby, "ruby")
 HTML5_ATOM(select, "select")
 HTML5_ATOM(optgroup, "optgroup")
+HTML5_ATOM(table, "table")
 HTML5_ATOM(frameset, "frameset")
 HTML5_ATOM(ul, "ul")
 HTML5_ATOM(ol, "ol")
 HTML5_ATOM(html, "html")
 HTML5_ATOM(td, "td")
 HTML5_ATOM(th, "th")
 HTML5_ATOM(tr, "tr")
 HTML5_ATOM(tbody, "tbody")
--- a/parser/html/nsHtml5AttributeName.cpp
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -38,16 +38,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5AttributeName.h
+++ b/parser/html/nsHtml5AttributeName.h
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -38,16 +38,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5HtmlAttributes.cpp
+++ b/parser/html/nsHtml5HtmlAttributes.cpp
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5HtmlAttributes.h
+++ b/parser/html/nsHtml5HtmlAttributes.h
@@ -40,16 +40,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5Macros.h
@@ -0,0 +1,47 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is HTML Parser C++ Translator code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Henri Sivonen <hsivonen@iki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsHtml5Macros_h_
+#define nsHtml5Macros_h_
+
+#define NS_HTML5_CONTINUE(target) \
+  goto target
+
+#define NS_HTML5_BREAK(target) \
+  goto target ## _end
+
+#endif /* nsHtml5Macros_h_ */
--- a/parser/html/nsHtml5MetaScanner.cpp
+++ b/parser/html/nsHtml5MetaScanner.cpp
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
@@ -68,90 +69,90 @@ nsHtml5MetaScanner::stateLoop(PRInt32 st
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '<': {
               state = NS_HTML5META_SCANNER_TAG_OPEN;
-              goto dataloop_end;
+              NS_HTML5_BREAK(dataloop);
             }
             default: {
               continue;
             }
           }
         }
         dataloop_end: ;
       }
       case NS_HTML5META_SCANNER_TAG_OPEN: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case 'm':
             case 'M': {
               metaState = NS_HTML5META_SCANNER_M;
               state = NS_HTML5META_SCANNER_TAG_NAME;
-              goto tagopenloop_end;
+              NS_HTML5_BREAK(tagopenloop);
             }
             case '!': {
               state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\?':
             case '/': {
               state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
                 metaState = NS_HTML5META_SCANNER_NO;
                 state = NS_HTML5META_SCANNER_TAG_NAME;
-                goto tagopenloop_end;
+                NS_HTML5_BREAK(tagopenloop);
               }
               state = NS_HTML5META_SCANNER_DATA;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         tagopenloop_end: ;
       }
       case NS_HTML5META_SCANNER_TAG_NAME: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
-              goto tagnameloop_end;
+              NS_HTML5_BREAK(tagnameloop);
             }
             case '/': {
               state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case 'e':
             case 'E': {
               if (metaState == NS_HTML5META_SCANNER_M) {
                 metaState = NS_HTML5META_SCANNER_E;
               } else {
                 metaState = NS_HTML5META_SCANNER_NO;
               }
@@ -187,75 +188,75 @@ nsHtml5MetaScanner::stateLoop(PRInt32 st
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               continue;
             }
             case '/': {
               state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case 'c':
             case 'C': {
               contentIndex = 0;
               charsetIndex = 0;
               state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
-              goto beforeattributenameloop_end;
+              NS_HTML5_BREAK(beforeattributenameloop);
             }
             default: {
               contentIndex = -1;
               charsetIndex = -1;
               state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
-              goto beforeattributenameloop_end;
+              NS_HTML5_BREAK(beforeattributenameloop);
             }
           }
         }
         beforeattributenameloop_end: ;
       }
       case NS_HTML5META_SCANNER_ATTRIBUTE_NAME: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '/': {
               state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '=': {
               strBufLen = 0;
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
-              goto attributenameloop_end;
+              NS_HTML5_BREAK(attributenameloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               if (metaState == NS_HTML5META_SCANNER_A) {
                 if (c >= 'A' && c <= 'Z') {
                   c += 0x20;
                 }
                 if (contentIndex == 6) {
                   contentIndex = -1;
@@ -274,365 +275,365 @@ nsHtml5MetaScanner::stateLoop(PRInt32 st
         }
         attributenameloop_end: ;
       }
       case NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               continue;
             }
             case '\"': {
               state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
-              goto beforeattributevalueloop_end;
+              NS_HTML5_BREAK(beforeattributevalueloop);
             }
             case '\'': {
               state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               if (charsetIndex == 6 || contentIndex == 6) {
                 addToBuffer(c);
               }
               state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         beforeattributevalueloop_end: ;
       }
       case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\"': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
-              goto attributevaluedoublequotedloop_end;
+              NS_HTML5_BREAK(attributevaluedoublequotedloop);
             }
             default: {
               if (metaState == NS_HTML5META_SCANNER_A && (contentIndex == 6 || charsetIndex == 6)) {
                 addToBuffer(c);
               }
               continue;
             }
           }
         }
         attributevaluedoublequotedloop_end: ;
       }
       case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '/': {
               state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
-              goto afterattributevaluequotedloop_end;
+              NS_HTML5_BREAK(afterattributevaluequotedloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterattributevaluequotedloop_end: ;
       }
       case NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG: {
         c = read();
         switch(c) {
           case -1: {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           case '>': {
             state = NS_HTML5META_SCANNER_DATA;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
             state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
             reconsume = PR_TRUE;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
       case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               if (metaState == NS_HTML5META_SCANNER_A && (contentIndex == 6 || charsetIndex == 6)) {
                 addToBuffer(c);
               }
               continue;
             }
           }
         }
       }
       case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case ' ':
             case '\t':
             case '\n':
             case '\f': {
               continue;
             }
             case '/': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '=': {
               state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case 'c':
             case 'C': {
               contentIndex = 0;
               charsetIndex = 0;
               state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               contentIndex = -1;
               charsetIndex = -1;
               state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN;
-              goto markupdeclarationopenloop_end;
+              NS_HTML5_BREAK(markupdeclarationopenloop);
             }
             default: {
               state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         markupdeclarationopenloop_end: ;
       }
       case NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               state = NS_HTML5META_SCANNER_COMMENT_START;
-              goto markupdeclarationhyphenloop_end;
+              NS_HTML5_BREAK(markupdeclarationhyphenloop);
             }
             default: {
               state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         markupdeclarationhyphenloop_end: ;
       }
       case NS_HTML5META_SCANNER_COMMENT_START: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               state = NS_HTML5META_SCANNER_COMMENT_START_DASH;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               state = NS_HTML5META_SCANNER_COMMENT;
-              goto commentstartloop_end;
+              NS_HTML5_BREAK(commentstartloop);
             }
           }
         }
         commentstartloop_end: ;
       }
       case NS_HTML5META_SCANNER_COMMENT: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               state = NS_HTML5META_SCANNER_COMMENT_END_DASH;
-              goto commentloop_end;
+              NS_HTML5_BREAK(commentloop);
             }
             default: {
               continue;
             }
           }
         }
         commentloop_end: ;
       }
       case NS_HTML5META_SCANNER_COMMENT_END_DASH: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               state = NS_HTML5META_SCANNER_COMMENT_END;
-              goto commentenddashloop_end;
+              NS_HTML5_BREAK(commentenddashloop);
             }
             default: {
               state = NS_HTML5META_SCANNER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         commentenddashloop_end: ;
       }
       case NS_HTML5META_SCANNER_COMMENT_END: {
         for (; ; ) {
           c = read();
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               continue;
             }
             default: {
               state = NS_HTML5META_SCANNER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5META_SCANNER_COMMENT_START_DASH: {
         c = read();
         switch(c) {
           case -1: {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           case '-': {
             state = NS_HTML5META_SCANNER_COMMENT_END;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '>': {
             state = NS_HTML5META_SCANNER_DATA;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
             state = NS_HTML5META_SCANNER_COMMENT;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
       case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\'': {
               if (tryCharset()) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               if (metaState == NS_HTML5META_SCANNER_A && (contentIndex == 6 || charsetIndex == 6)) {
                 addToBuffer(c);
               }
               continue;
             }
           }
@@ -642,21 +643,21 @@ nsHtml5MetaScanner::stateLoop(PRInt32 st
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             c = read();
           }
           switch(c) {
             case -1: {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '>': {
               state = NS_HTML5META_SCANNER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               continue;
             }
           }
         }
       }
     }
--- a/parser/html/nsHtml5MetaScanner.h
+++ b/parser/html/nsHtml5MetaScanner.h
@@ -40,16 +40,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5Portability.h
+++ b/parser/html/nsHtml5Portability.h
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
--- a/parser/html/nsHtml5StackNode.cpp
+++ b/parser/html/nsHtml5StackNode.cpp
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5StackNode.h
+++ b/parser/html/nsHtml5StackNode.h
@@ -40,16 +40,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
--- a/parser/html/nsHtml5StateSnapshot.cpp
+++ b/parser/html/nsHtml5StateSnapshot.cpp
@@ -38,39 +38,40 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
 #include "nsHtml5Portability.h"
 
 #include "nsHtml5StateSnapshot.h"
 
 
-nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer, nsIContent** headPointer, PRInt32 mode, PRInt32 originalMode, PRBool framesetOk, PRInt32 foreignFlag, PRBool needToDropLF, PRBool quirks)
+nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer, nsIContent** headPointer, PRInt32 mode, PRInt32 originalMode, PRBool framesetOk, PRBool inForeign, PRBool needToDropLF, PRBool quirks)
   : stack(stack),
     listOfActiveFormattingElements(listOfActiveFormattingElements),
     formPointer(formPointer),
     headPointer(headPointer),
     mode(mode),
     originalMode(originalMode),
     framesetOk(framesetOk),
-    foreignFlag(foreignFlag),
+    inForeign(inForeign),
     needToDropLF(needToDropLF),
     quirks(quirks)
 {
   MOZ_COUNT_CTOR(nsHtml5StateSnapshot);
 }
 
 jArray<nsHtml5StackNode*,PRInt32> 
 nsHtml5StateSnapshot::getStack()
@@ -109,20 +110,20 @@ nsHtml5StateSnapshot::getOriginalMode()
 }
 
 PRBool 
 nsHtml5StateSnapshot::isFramesetOk()
 {
   return framesetOk;
 }
 
-PRInt32 
-nsHtml5StateSnapshot::getForeignFlag()
+PRBool 
+nsHtml5StateSnapshot::isInForeign()
 {
-  return foreignFlag;
+  return inForeign;
 }
 
 PRBool 
 nsHtml5StateSnapshot::isNeedToDropLF()
 {
   return needToDropLF;
 }
 
@@ -148,17 +149,17 @@ nsHtml5StateSnapshot::getStackLength()
 nsHtml5StateSnapshot::~nsHtml5StateSnapshot()
 {
   MOZ_COUNT_DTOR(nsHtml5StateSnapshot);
   for (PRInt32 i = 0; i < stack.length; i++) {
     stack[i]->release();
   }
   stack.release();
   for (PRInt32 i = 0; i < listOfActiveFormattingElements.length; i++) {
-    if (!!listOfActiveFormattingElements[i]) {
+    if (listOfActiveFormattingElements[i]) {
       listOfActiveFormattingElements[i]->release();
     }
   }
   listOfActiveFormattingElements.release();
   ;
 }
 
 void
--- a/parser/html/nsHtml5StateSnapshot.h
+++ b/parser/html/nsHtml5StateSnapshot.h
@@ -39,16 +39,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
@@ -62,29 +63,29 @@ class nsHtml5StateSnapshot : public nsAH
   private:
     jArray<nsHtml5StackNode*,PRInt32> stack;
     jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements;
     nsIContent** formPointer;
     nsIContent** headPointer;
     PRInt32 mode;
     PRInt32 originalMode;
     PRBool framesetOk;
-    PRInt32 foreignFlag;
+    PRBool inForeign;
     PRBool needToDropLF;
     PRBool quirks;
   public:
-    nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer, nsIContent** headPointer, PRInt32 mode, PRInt32 originalMode, PRBool framesetOk, PRInt32 foreignFlag, PRBool needToDropLF, PRBool quirks);
+    nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer, nsIContent** headPointer, PRInt32 mode, PRInt32 originalMode, PRBool framesetOk, PRBool inForeign, PRBool needToDropLF, PRBool quirks);
     jArray<nsHtml5StackNode*,PRInt32> getStack();
     jArray<nsHtml5StackNode*,PRInt32> getListOfActiveFormattingElements();
     nsIContent** getFormPointer();
     nsIContent** getHeadPointer();
     PRInt32 getMode();
     PRInt32 getOriginalMode();
     PRBool isFramesetOk();
-    PRInt32 getForeignFlag();
+    PRBool isInForeign();
     PRBool isNeedToDropLF();
     PRBool isQuirks();
     PRInt32 getListOfActiveFormattingElementsLength();
     PRInt32 getStackLength();
     ~nsHtml5StateSnapshot();
     static void initializeStatics();
     static void releaseStatics();
 };
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -899,19 +899,17 @@ nsHtml5StreamParser::ContinueAfterScript
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   #ifdef DEBUG
     mExecutor->AssertStageEmpty();
   #endif
   PRBool speculationFailed = PR_FALSE;
   {
     mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
     if (mSpeculations.IsEmpty()) {
-      // Not quite sure how exactly this happens...
-      // Maybe an artifact of defer scripts?
-      NS_WARNING("ContinueAfterScripts called without speculations.");
+      NS_NOTREACHED("ContinueAfterScripts called without speculations.");
       return;
     }
     nsHtml5Speculation* speculation = mSpeculations.ElementAt(0);
     if (aLastWasCR || 
         !aTokenizer->isInDataState() || 
         !aTreeBuilder->snapshotMatches(speculation->GetSnapshot())) {
       speculationFailed = PR_TRUE;
       // We've got a failed speculation :-(
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -129,16 +129,17 @@ class nsHtml5StreamParser : public nsISt
     
     // nsICharsetDetectionObserver
     /**
      * Chardet calls this to report the detection result
      */
     NS_IMETHOD Notify(const char* aCharset, nsDetectionConfident aConf);
 
     // EncodingDeclarationHandler
+    // http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/common/EncodingDeclarationHandler.java
     /**
      * Tree builder uses this to report a late <meta charset>
      */
     void internalEncodingDeclaration(nsString* aEncoding);
 
     // Not from an external interface
 
     /**
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -41,16 +41,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
@@ -315,26 +316,26 @@ nsHtml5Tokenizer::attributeNameComplete(
     attributeName = nsnull;
   }
 }
 
 void 
 nsHtml5Tokenizer::addAttributeWithoutValue()
 {
 
-  if (!!attributeName) {
+  if (attributeName) {
     attributes->addAttribute(attributeName, nsHtml5Portability::newEmptyString());
     attributeName = nsnull;
   }
 }
 
 void 
 nsHtml5Tokenizer::addAttributeWithValue()
 {
-  if (!!attributeName) {
+  if (attributeName) {
     nsString* val = longStrBufToString();
     attributes->addAttribute(attributeName, val);
     attributeName = nsnull;
   }
 }
 
 void 
 nsHtml5Tokenizer::start()
@@ -394,138 +395,138 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
   stateloop: for (; ; ) {
     switch(state) {
       case NS_HTML5TOKENIZER_DATA: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '&': {
               flushChars(buf, pos);
               clearStrBufAndAppend(c);
               setAdditionalAndRememberAmpersandLocation('\0');
               returnState = state;
               state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '<': {
               flushChars(buf, pos);
               state = NS_HTML5TOKENIZER_TAG_OPEN;
-              goto dataloop_end;
+              NS_HTML5_BREAK(dataloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         dataloop_end: ;
       }
       case NS_HTML5TOKENIZER_TAG_OPEN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (c >= 'A' && c <= 'Z') {
             endTag = PR_FALSE;
             clearStrBufAndAppend((PRUnichar) (c + 0x20));
             state = NS_HTML5TOKENIZER_TAG_NAME;
-            goto tagopenloop_end;
+            NS_HTML5_BREAK(tagopenloop);
           } else if (c >= 'a' && c <= 'z') {
             endTag = PR_FALSE;
             clearStrBufAndAppend(c);
             state = NS_HTML5TOKENIZER_TAG_NAME;
-            goto tagopenloop_end;
+            NS_HTML5_BREAK(tagopenloop);
           }
           switch(c) {
             case '!': {
               state = NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '/': {
               state = NS_HTML5TOKENIZER_CLOSE_TAG_OPEN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\?': {
 
               clearLongStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
               cstart = pos + 1;
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
 
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               state = NS_HTML5TOKENIZER_DATA;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         tagopenloop_end: ;
       }
       case NS_HTML5TOKENIZER_TAG_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               strBufToElementNameString();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               strBufToElementNameString();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto tagnameloop_end;
+              NS_HTML5_BREAK(tagnameloop);
             }
             case '/': {
               strBufToElementNameString();
               state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               strBufToElementNameString();
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
@@ -537,105 +538,105 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
         tagnameloop_end: ;
       }
       case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '/': {
               state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<':
             case '=':
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
               clearStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_ATTRIBUTE_NAME;
-              goto beforeattributenameloop_end;
+              NS_HTML5_BREAK(beforeattributenameloop);
             }
           }
         }
         beforeattributenameloop_end: ;
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               attributeNameComplete();
               state = NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               attributeNameComplete();
               state = NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '/': {
               attributeNameComplete();
               addAttributeWithoutValue();
               state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '=': {
               attributeNameComplete();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE;
-              goto attributenameloop_end;
+              NS_HTML5_BREAK(attributenameloop);
             }
             case '>': {
               attributeNameComplete();
               addAttributeWithoutValue();
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<':
             default: {
@@ -647,100 +648,100 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         attributenameloop_end: ;
       }
       case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '\"': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
-              goto beforeattributevalueloop_end;
+              NS_HTML5_BREAK(beforeattributevalueloop);
             }
             case '&': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED;
 
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               addAttributeWithoutValue();
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '<':
             case '=':
             case '`':
             default: {
               clearLongStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED;
 
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         beforeattributevalueloop_end: ;
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\"': {
               addAttributeWithValue();
               state = NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED;
-              goto attributevaluedoublequotedloop_end;
+              NS_HTML5_BREAK(attributevaluedoublequotedloop);
             }
             case '&': {
               clearStrBufAndAppend(c);
               setAdditionalAndRememberAmpersandLocation('\"');
               returnState = state;
               state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -750,117 +751,117 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         attributevaluedoublequotedloop_end: ;
       }
       case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '/': {
               state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-              goto afterattributevaluequotedloop_end;
+              NS_HTML5_BREAK(afterattributevaluequotedloop);
             }
             case '>': {
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
 
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterattributevaluequotedloop_end: ;
       }
       case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         switch(c) {
           case '>': {
             state = emitCurrentTagToken(PR_TRUE, pos);
             if (shouldSuspend) {
-              goto stateloop_end;
-            }
-            goto stateloop;
+              NS_HTML5_BREAK(stateloop);
+            }
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
 
             state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
             reconsume = PR_TRUE;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               addAttributeWithValue();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               addAttributeWithValue();
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '&': {
               clearStrBufAndAppend(c);
               setAdditionalAndRememberAmpersandLocation('>');
               returnState = state;
               state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               addAttributeWithValue();
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '<':
             case '\"':
             case '\'':
             case '=':
@@ -871,91 +872,91 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               continue;
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '/': {
               addAttributeWithoutValue();
               state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '=': {
               state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               addAttributeWithoutValue();
               state = emitCurrentTagToken(PR_FALSE, pos);
               if (shouldSuspend) {
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<':
             default: {
               addAttributeWithoutValue();
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
               clearStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_ATTRIBUTE_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_BOGUS_COMMENT: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '>': {
               emitComment(0, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN;
-              goto boguscommentloop_end;
+              NS_HTML5_BREAK(boguscommentloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -965,170 +966,170 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         boguscommentloop_end: ;
       }
       case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN: {
         boguscommenthyphenloop: for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '>': {
               emitComment(0, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               appendSecondHyphenToBogusComment();
-              goto boguscommenthyphenloop;
+              NS_HTML5_CONTINUE(boguscommenthyphenloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
 
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               clearLongStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN;
-              goto markupdeclarationopenloop_end;
+              NS_HTML5_BREAK(markupdeclarationopenloop);
             }
             case 'd':
             case 'D': {
               clearLongStrBufAndAppend(c);
               index = 0;
               state = NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '[': {
-              if (tokenHandler->inForeign()) {
+              if (tokenHandler->isInForeign()) {
                 clearLongStrBufAndAppend(c);
                 index = 0;
                 state = NS_HTML5TOKENIZER_CDATA_START;
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               } else {
               }
             }
             default: {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         markupdeclarationopenloop_end: ;
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\0': {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_COMMENT_START;
-              goto markupdeclarationhyphenloop_end;
+              NS_HTML5_BREAK(markupdeclarationhyphenloop);
             }
             default: {
 
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         markupdeclarationhyphenloop_end: ;
       }
       case NS_HTML5TOKENIZER_COMMENT_START: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_START_DASH;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               emitComment(0, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto commentstartloop_end;
+              NS_HTML5_BREAK(commentstartloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto commentstartloop_end;
+              NS_HTML5_BREAK(commentstartloop);
             }
           }
         }
         commentstartloop_end: ;
       }
       case NS_HTML5TOKENIZER_COMMENT: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_END_DASH;
-              goto commentloop_end;
+              NS_HTML5_BREAK(commentloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -1138,351 +1139,351 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         commentloop_end: ;
       }
       case NS_HTML5TOKENIZER_COMMENT_END_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_END;
-              goto commentenddashloop_end;
+              NS_HTML5_BREAK(commentenddashloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         commentenddashloop_end: ;
       }
       case NS_HTML5TOKENIZER_COMMENT_END: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '>': {
               emitComment(2, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               adjustDoubleHyphenAndAppendToLongStrBufAndErr(c);
               continue;
             }
             case ' ':
             case '\t':
             case '\f': {
               adjustDoubleHyphenAndAppendToLongStrBufAndErr(c);
               state = NS_HTML5TOKENIZER_COMMENT_END_SPACE;
-              goto commentendloop_end;
+              NS_HTML5_BREAK(commentendloop);
             }
             case '\r': {
               adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn();
               state = NS_HTML5TOKENIZER_COMMENT_END_SPACE;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               adjustDoubleHyphenAndAppendToLongStrBufLineFeed();
               state = NS_HTML5TOKENIZER_COMMENT_END_SPACE;
-              goto commentendloop_end;
+              NS_HTML5_BREAK(commentendloop);
             }
             case '!': {
 
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_END_BANG;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               adjustDoubleHyphenAndAppendToLongStrBufAndErr(c);
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         commentendloop_end: ;
       }
       case NS_HTML5TOKENIZER_COMMENT_END_SPACE: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '>': {
               emitComment(0, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_END_DASH;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case ' ':
             case '\t':
             case '\f': {
               appendLongStrBuf(c);
               continue;
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_COMMENT_END_BANG: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '>': {
               emitComment(3, pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '-': {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT_END_DASH;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               appendLongStrBuf(c);
               state = NS_HTML5TOKENIZER_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_COMMENT_START_DASH: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         switch(c) {
           case '-': {
             appendLongStrBuf(c);
             state = NS_HTML5TOKENIZER_COMMENT_END;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '>': {
 
             emitComment(1, pos);
             state = NS_HTML5TOKENIZER_DATA;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '\r': {
             appendLongStrBufCarriageReturn();
             state = NS_HTML5TOKENIZER_COMMENT;
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           case '\n': {
             appendLongStrBufLineFeed();
             state = NS_HTML5TOKENIZER_COMMENT;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '\0': {
             c = 0xfffd;
           }
           default: {
             appendLongStrBuf(c);
             state = NS_HTML5TOKENIZER_COMMENT;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 6) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
               appendLongStrBuf(c);
             } else {
 
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
           } else {
             state = NS_HTML5TOKENIZER_DOCTYPE;
             reconsume = PR_TRUE;
-            goto markupdeclarationdoctypeloop_end;
+            NS_HTML5_BREAK(markupdeclarationdoctypeloop);
           }
         }
         markupdeclarationdoctypeloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           initDoctypeFields();
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME;
-              goto doctypeloop_end;
+              NS_HTML5_BREAK(doctypeloop);
             }
             default: {
 
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME;
               reconsume = PR_TRUE;
-              goto doctypeloop_end;
+              NS_HTML5_BREAK(doctypeloop);
             }
           }
         }
         doctypeloop_end: ;
       }
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
               clearStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_DOCTYPE_NAME;
-              goto beforedoctypenameloop_end;
+              NS_HTML5_BREAK(beforedoctypenameloop);
             }
           }
         }
         beforedoctypenameloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               strBufToDoctypeName();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               strBufToDoctypeName();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME;
-              goto doctypenameloop_end;
+              NS_HTML5_BREAK(doctypenameloop);
             }
             case '>': {
               strBufToDoctypeName();
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x0020;
               }
@@ -1491,206 +1492,206 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         doctypenameloop_end: ;
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '>': {
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case 'p':
             case 'P': {
               index = 0;
               state = NS_HTML5TOKENIZER_DOCTYPE_UBLIC;
-              goto afterdoctypenameloop_end;
+              NS_HTML5_BREAK(afterdoctypenameloop);
             }
             case 's':
             case 'S': {
               index = 0;
               state = NS_HTML5TOKENIZER_DOCTYPE_YSTEM;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterdoctypenameloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE_UBLIC: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 5) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != nsHtml5Tokenizer::UBLIC[index]) {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
           } else {
             state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD;
             reconsume = PR_TRUE;
-            goto doctypeublicloop_end;
+            NS_HTML5_BREAK(doctypeublicloop);
           }
         }
         doctypeublicloop_end: ;
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
-              goto afterdoctypepublickeywordloop_end;
+              NS_HTML5_BREAK(afterdoctypepublickeywordloop);
             }
             case '\"': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterdoctypepublickeywordloop_end: ;
       }
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '\"': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
-              goto beforedoctypepublicidentifierloop_end;
+              NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         beforedoctypepublicidentifierloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\"': {
               publicIdentifier = longStrBufToString();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
-              goto doctypepublicidentifierdoublequotedloop_end;
+              NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               publicIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -1700,126 +1701,126 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
         doctypepublicidentifierdoublequotedloop_end: ;
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               state = NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               state = NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
-              goto afterdoctypepublicidentifierloop_end;
+              NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
             }
             case '>': {
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\"': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterdoctypepublicidentifierloop_end: ;
       }
       case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '>': {
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\"': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
-              goto betweendoctypepublicandsystemidentifiersloop_end;
+              NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         betweendoctypepublicandsystemidentifiersloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\"': {
               systemIdentifier = longStrBufToString();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               systemIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -1829,223 +1830,223 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
           }
         }
 
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '>': {
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctypeWithoutQuirks();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto afterdoctypesystemidentifierloop_end;
+              NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
             }
           }
         }
         afterdoctypesystemidentifierloop_end: ;
       }
       case NS_HTML5TOKENIZER_BOGUS_DOCTYPE: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '>': {
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_DOCTYPE_YSTEM: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 5) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != nsHtml5Tokenizer::YSTEM[index]) {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           } else {
             state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD;
             reconsume = PR_TRUE;
-            goto doctypeystemloop_end;
+            NS_HTML5_BREAK(doctypeystemloop);
           }
         }
         doctypeystemloop_end: ;
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\r': {
               silentCarriageReturn();
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
-              goto afterdoctypesystemkeywordloop_end;
+              NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
             }
             case '\"': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
 
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         afterdoctypesystemkeywordloop_end: ;
       }
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\r': {
               silentCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '\"': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
-              goto beforedoctypesystemidentifierloop_end;
+              NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
               state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         beforedoctypesystemidentifierloop_end: ;
       }
       case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\'': {
               systemIdentifier = longStrBufToString();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               systemIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -2054,36 +2055,36 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               continue;
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '\'': {
               publicIdentifier = longStrBufToString();
               state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
 
               forceQuirks = PR_TRUE;
               publicIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = NS_HTML5TOKENIZER_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -2092,27 +2093,27 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               continue;
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_CDATA_START: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 6) {
             if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
               appendLongStrBuf(c);
             } else {
 
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
           } else {
             cstart = pos;
             state = NS_HTML5TOKENIZER_CDATA_SECTION;
             reconsume = PR_TRUE;
             break;
@@ -2120,112 +2121,112 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
         }
       }
       case NS_HTML5TOKENIZER_CDATA_SECTION: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case ']': {
               flushChars(buf, pos);
               state = NS_HTML5TOKENIZER_CDATA_RSQB;
-              goto cdatasectionloop_end;
+              NS_HTML5_BREAK(cdatasectionloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         cdatasectionloop_end: ;
       }
       case NS_HTML5TOKENIZER_CDATA_RSQB: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case ']': {
               state = NS_HTML5TOKENIZER_CDATA_RSQB_RSQB;
-              goto cdatarsqb_end;
+              NS_HTML5_BREAK(cdatarsqb);
             }
             default: {
               tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
               cstart = pos;
               state = NS_HTML5TOKENIZER_CDATA_SECTION;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         cdatarsqb_end: ;
       }
       case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         switch(c) {
           case '>': {
             cstart = pos + 1;
             state = NS_HTML5TOKENIZER_DATA;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
             tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
             cstart = pos;
             state = NS_HTML5TOKENIZER_CDATA_SECTION;
             reconsume = PR_TRUE;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\'': {
               addAttributeWithValue();
               state = NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '&': {
               clearStrBufAndAppend(c);
               setAdditionalAndRememberAmpersandLocation('\'');
               returnState = state;
               state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
-              goto attributevaluesinglequotedloop_end;
+              NS_HTML5_BREAK(attributevaluesinglequotedloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               appendLongStrBufLineFeed();
               continue;
             }
             case '\0': {
               c = 0xfffd;
             }
@@ -2234,186 +2235,182 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               continue;
             }
           }
         }
         attributevaluesinglequotedloop_end: ;
       }
       case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         if (c == '\0') {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         switch(c) {
           case ' ':
           case '\t':
           case '\n':
           case '\r':
           case '\f':
           case '<':
           case '&': {
             emitOrAppendStrBuf(returnState);
             if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               cstart = pos;
             }
             state = returnState;
             reconsume = PR_TRUE;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '#': {
             appendStrBuf('#');
             state = NS_HTML5TOKENIZER_CONSUME_NCR;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
             if (c == additional) {
               emitOrAppendStrBuf(returnState);
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             if (c >= 'a' && c <= 'z') {
               firstCharKey = c - 'a' + 26;
             } else if (c >= 'A' && c <= 'Z') {
               firstCharKey = c - 'A';
             } else {
 
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             appendStrBuf(c);
             state = NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP;
           }
         }
       }
       case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP: {
         {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (c == '\0') {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           PRInt32 hilo = 0;
           if (c <= 'z') {
             const PRInt32* row = nsHtml5NamedCharacters::HILO_ACCEL[c];
-            if (!!row) {
+            if (row) {
               hilo = row[firstCharKey];
             }
           }
           if (!hilo) {
 
             emitOrAppendStrBuf(returnState);
             if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               cstart = pos;
             }
             state = returnState;
             reconsume = PR_TRUE;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           appendStrBuf(c);
           lo = hilo & 0xFFFF;
           hi = hilo >> 16;
           entCol = -1;
           candidate = -1;
           strBufMark = 0;
           state = NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL;
         }
       }
       case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (c == '\0') {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           entCol++;
           for (; ; ) {
             if (hi < lo) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             }
             if (entCol == nsHtml5NamedCharacters::NAMES[lo].length) {
               candidate = lo;
               strBufMark = strBufLen;
               lo++;
             } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             } else if (c > nsHtml5NamedCharacters::NAMES[lo][entCol]) {
               lo++;
             } else {
-              goto loloop_end;
+              NS_HTML5_BREAK(loloop);
             }
           }
           loloop_end: ;
           for (; ; ) {
             if (hi < lo) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             }
             if (entCol == nsHtml5NamedCharacters::NAMES[hi].length) {
-              goto hiloop_end;
+              NS_HTML5_BREAK(hiloop);
             }
             if (entCol > nsHtml5NamedCharacters::NAMES[hi].length) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             } else if (c < nsHtml5NamedCharacters::NAMES[hi][entCol]) {
               hi--;
             } else {
-              goto hiloop_end;
+              NS_HTML5_BREAK(hiloop);
             }
           }
           hiloop_end: ;
           if (hi < lo) {
-            goto outer_end;
+            NS_HTML5_BREAK(outer);
           }
           appendStrBuf(c);
           continue;
         }
         outer_end: ;
         if (candidate == -1) {
 
           emitOrAppendStrBuf(returnState);
           if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
             cstart = pos;
           }
           state = returnState;
           reconsume = PR_TRUE;
-          goto stateloop;
+          NS_HTML5_CONTINUE(stateloop);
         } else {
           jArray<PRInt8,PRInt32> candidateArr = nsHtml5NamedCharacters::NAMES[candidate];
           if (!candidateArr.length || candidateArr[candidateArr.length - 1] != ';') {
             if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               PRUnichar ch;
               if (strBufMark == strBufLen) {
                 ch = c;
               } else {
                 ch = strBuf[strBufMark];
               }
               if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
 
                 appendStrBufToLongStrBuf();
                 state = returnState;
                 reconsume = PR_TRUE;
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               }
             }
-            if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
 
-            } else {
-
-            }
           }
           const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
           if ((val[0] & 0xFC00) == 0xD800) {
             emitOrAppendTwo(val, returnState);
           } else {
             emitOrAppendOne(val, returnState);
           }
           if (strBufMark < strBufLen) {
@@ -2425,47 +2422,47 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               tokenHandler->characters(strBuf, strBufMark, strBufLen - strBufMark);
             }
           }
           if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
             cstart = pos;
           }
           state = returnState;
           reconsume = PR_TRUE;
-          goto stateloop;
+          NS_HTML5_CONTINUE(stateloop);
         }
       }
       case NS_HTML5TOKENIZER_CONSUME_NCR: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         prevValue = -1;
         value = 0;
         seenDigits = PR_FALSE;
         switch(c) {
           case 'x':
           case 'X': {
             appendStrBuf(c);
             state = NS_HTML5TOKENIZER_HEX_NCR_LOOP;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           default: {
             state = NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP;
             reconsume = PR_TRUE;
           }
         }
       }
       case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           if (value < prevValue) {
             value = 0x110000;
           }
           prevValue = value;
           if (c >= '0' && c <= '9') {
@@ -2474,59 +2471,59 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             value += c - '0';
             continue;
           } else if (c == ';') {
             if (seenDigits) {
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = NS_HTML5TOKENIZER_HANDLE_NCR_VALUE;
-              goto decimalloop_end;
+              NS_HTML5_BREAK(decimalloop);
             } else {
 
               appendStrBuf(';');
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = returnState;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           } else {
             if (!seenDigits) {
 
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             } else {
 
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = NS_HTML5TOKENIZER_HANDLE_NCR_VALUE;
               reconsume = PR_TRUE;
-              goto decimalloop_end;
+              NS_HTML5_BREAK(decimalloop);
             }
           }
         }
         decimalloop_end: ;
       }
       case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE: {
         handleNcrValue(returnState);
         state = returnState;
-        goto stateloop;
+        NS_HTML5_CONTINUE(stateloop);
       }
       case NS_HTML5TOKENIZER_HEX_NCR_LOOP: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (value < prevValue) {
             value = 0x110000;
           }
           prevValue = value;
           if (c >= '0' && c <= '9') {
             seenDigits = PR_TRUE;
@@ -2544,67 +2541,67 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             value += c - 'a' + 10;
             continue;
           } else if (c == ';') {
             if (seenDigits) {
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = NS_HTML5TOKENIZER_HANDLE_NCR_VALUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             } else {
 
               appendStrBuf(';');
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = returnState;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           } else {
             if (!seenDigits) {
 
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             } else {
 
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = NS_HTML5TOKENIZER_HANDLE_NCR_VALUE;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_PLAINTEXT: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
@@ -2612,566 +2609,566 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
 
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '<': {
               flushChars(buf, pos);
               returnState = state;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN;
-              goto scriptdataloop_end;
+              NS_HTML5_BREAK(scriptdataloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         scriptdataloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '/': {
               index = 0;
               clearStrBuf();
               state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '!': {
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START;
-              goto scriptdatalessthansignloop_end;
+              NS_HTML5_BREAK(scriptdatalessthansignloop);
             }
             default: {
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdatalessthansignloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH;
-              goto scriptdataescapestartloop_end;
+              NS_HTML5_BREAK(scriptdataescapestartloop);
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdataescapestartloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH;
-              goto scriptdataescapestartdashloop_end;
+              NS_HTML5_BREAK(scriptdataescapestartdashloop);
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdataescapestartdashloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               continue;
             }
             case '<': {
               flushChars(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto scriptdataescapeddashdashloop_end;
+              NS_HTML5_BREAK(scriptdataescapeddashdashloop);
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto scriptdataescapeddashdashloop_end;
+              NS_HTML5_BREAK(scriptdataescapeddashdashloop);
             }
           }
         }
         scriptdataescapeddashdashloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH;
-              goto scriptdataescapedloop_end;
+              NS_HTML5_BREAK(scriptdataescapedloop);
             }
             case '<': {
               flushChars(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         scriptdataescapedloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '<': {
               flushChars(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
-              goto scriptdataescapeddashloop_end;
+              NS_HTML5_BREAK(scriptdataescapeddashloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdataescapeddashloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '/': {
               index = 0;
               clearStrBuf();
               returnState = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
               state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case 'S':
             case 's': {
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               index = 1;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START;
-              goto scriptdataescapedlessthanloop_end;
+              NS_HTML5_BREAK(scriptdataescapedlessthanloop);
             }
             default: {
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdataescapedlessthanloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
 
           if (index < 6) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
           }
           switch(c) {
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f':
             case '/':
             case '>': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto scriptdatadoubleescapestartloop_end;
+              NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
             }
             default: {
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdatadoubleescapestartloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH;
-              goto scriptdatadoubleescapedloop_end;
+              NS_HTML5_BREAK(scriptdatadoubleescapedloop);
             }
             case '<': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         scriptdatadoubleescapedloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH;
-              goto scriptdatadoubleescapeddashloop_end;
+              NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
             }
             case '<': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdatadoubleescapeddashloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               continue;
             }
             case '<': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
-              goto scriptdatadoubleescapeddashdashloop_end;
+              NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
             }
             case '>': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdatadoubleescapeddashdashloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '/': {
               index = 0;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END;
-              goto scriptdatadoubleescapedlessthanloop_end;
+              NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
             }
             default: {
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         scriptdatadoubleescapedlessthanloop_end: ;
       }
       case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 6) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
           }
           switch(c) {
             case '\r': {
               emitCarriageReturn(buf, pos);
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f':
             case '/':
             case '>': {
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               reconsume = PR_TRUE;
               state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
 
       }
       case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: {
         if (++pos == endPos) {
-          goto stateloop_end;
+          NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         switch(c) {
           case '>': {
 
             cstart = pos + 1;
             state = NS_HTML5TOKENIZER_DATA;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '\r': {
             silentCarriageReturn();
 
             clearLongStrBufAndAppend('\n');
             state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           case '\n': {
             silentLineFeed();
 
             clearLongStrBufAndAppend('\n');
             state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-            goto stateloop;
+            NS_HTML5_CONTINUE(stateloop);
           }
           case '\0': {
             c = 0xfffd;
           }
           default: {
             if (c >= 'A' && c <= 'Z') {
               c += 0x20;
             }
             if (c >= 'a' && c <= 'z') {
               endTag = PR_TRUE;
               clearStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_TAG_NAME;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             } else {
 
               clearLongStrBufAndAppend(c);
               state = NS_HTML5TOKENIZER_BOGUS_COMMENT;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
       }
       case NS_HTML5TOKENIZER_RCDATA: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '&': {
               flushChars(buf, pos);
               clearStrBufAndAppend(c);
               additional = '\0';
               returnState = state;
               state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '<': {
               flushChars(buf, pos);
               returnState = state;
               state = NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
@@ -3179,131 +3176,131 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
 
       }
       case NS_HTML5TOKENIZER_RAWTEXT: {
         for (; ; ) {
           if (reconsume) {
             reconsume = PR_FALSE;
           } else {
             if (++pos == endPos) {
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             c = checkChar(buf, pos);
           }
           switch(c) {
             case '<': {
               flushChars(buf, pos);
               returnState = state;
               state = NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN;
-              goto rawtextloop_end;
+              NS_HTML5_BREAK(rawtextloop);
             }
             case '\0': {
               emitReplacementCharacter(buf, pos);
               continue;
             }
             case '\r': {
               emitCarriageReturn(buf, pos);
-              goto stateloop_end;
+              NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               silentLineFeed();
             }
             default: {
               continue;
             }
           }
         }
         rawtextloop_end: ;
       }
       case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           switch(c) {
             case '/': {
               index = 0;
               clearStrBuf();
               state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME;
-              goto rawtextrcdatalessthansignloop_end;
+              NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
             }
             default: {
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
         rawtextrcdatalessthansignloop_end: ;
       }
       case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: {
         for (; ; ) {
           if (++pos == endPos) {
-            goto stateloop_end;
+            NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < endTagExpectationAsArray.length) {
             PRUnichar e = endTagExpectationAsArray[index];
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded != e) {
               tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
               emitStrBuf();
               cstart = pos;
               state = returnState;
               reconsume = PR_TRUE;
-              goto stateloop;
+              NS_HTML5_CONTINUE(stateloop);
             }
             appendStrBuf(c);
             index++;
             continue;
           } else {
             endTag = PR_TRUE;
             tagName = endTagExpectation;
             switch(c) {
               case '\r': {
                 silentCarriageReturn();
                 state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-                goto stateloop_end;
+                NS_HTML5_BREAK(stateloop);
               }
               case '\n': {
                 silentLineFeed();
               }
               case ' ':
               case '\t':
               case '\f': {
                 state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME;
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               }
               case '/': {
                 state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG;
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               }
               case '>': {
                 state = emitCurrentTagToken(PR_FALSE, pos);
                 if (shouldSuspend) {
-                  goto stateloop_end;
+                  NS_HTML5_BREAK(stateloop);
                 }
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               }
               default: {
                 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
                 emitStrBuf();
                 if (c == '\0') {
                   emitReplacementCharacter(buf, pos);
                 } else {
                   cstart = pos;
                 }
                 state = returnState;
-                goto stateloop;
+                NS_HTML5_CONTINUE(stateloop);
               }
             }
           }
         }
       }
     }
   }
   stateloop_end: ;
@@ -3313,21 +3310,21 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
   return pos;
 }
 
 void 
 nsHtml5Tokenizer::initDoctypeFields()
 {
   nsHtml5Portability::releaseLocal(doctypeName);
   doctypeName = nsHtml5Atoms::emptystring;
-  if (!!systemIdentifier) {
+  if (systemIdentifier) {
     nsHtml5Portability::releaseString(systemIdentifier);
     systemIdentifier = nsnull;
   }
-  if (!!publicIdentifier) {
+  if (publicIdentifier) {
     nsHtml5Portability::releaseString(publicIdentifier);
     publicIdentifier = nsnull;
   }
   forceQuirks = PR_FALSE;
 }
 
 void 
 nsHtml5Tokenizer::emitCarriageReturn(PRUnichar* buf, PRInt32 pos)
@@ -3411,184 +3408,184 @@ nsHtml5Tokenizer::eof()
 {
   PRInt32 state = stateSave;
   PRInt32 returnState = returnStateSave;
   eofloop: for (; ; ) {
     switch(state) {
       case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
       case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
         tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_TAG_OPEN: {
 
         tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN: {
         tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: {
         tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
         emitStrBuf();
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: {
 
         tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_TAG_NAME: {
 
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
       case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
       case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG: {
 
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_NAME: {
 
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
       case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE: {
 
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
       case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED: {
 
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_BOGUS_COMMENT: {
         emitComment(0, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN: {
         emitComment(0, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN: {
 
         clearLongStrBuf();
         emitComment(0, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN: {
 
         emitComment(0, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE: {
         if (index < 6) {
 
           emitComment(0, 0);
         } else {
 
           nsHtml5Portability::releaseLocal(doctypeName);
           doctypeName = nsHtml5Atoms::emptystring;
-          if (!!systemIdentifier) {
+          if (systemIdentifier) {
             nsHtml5Portability::releaseString(systemIdentifier);
             systemIdentifier = nsnull;
           }
-          if (!!publicIdentifier) {
+          if (publicIdentifier) {
             nsHtml5Portability::releaseString(publicIdentifier);
             publicIdentifier = nsnull;
           }
           forceQuirks = PR_TRUE;
           emitDoctypeToken(0);
-          goto eofloop_end;
+          NS_HTML5_BREAK(eofloop);
         }
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_COMMENT_START:
       case NS_HTML5TOKENIZER_COMMENT:
       case NS_HTML5TOKENIZER_COMMENT_END_SPACE: {
 
         emitComment(0, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_COMMENT_END: {
 
         emitComment(2, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_COMMENT_END_DASH:
       case NS_HTML5TOKENIZER_COMMENT_START_DASH: {
 
         emitComment(1, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_COMMENT_END_BANG: {
 
         emitComment(3, 0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_DOCTYPE:
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME: {
 
         forceQuirks = PR_TRUE;
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_DOCTYPE_NAME: {
 
         strBufToDoctypeName();
         forceQuirks = PR_TRUE;
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_DOCTYPE_UBLIC:
       case NS_HTML5TOKENIZER_DOCTYPE_YSTEM:
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
 
         forceQuirks = PR_TRUE;
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
       case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
 
         forceQuirks = PR_TRUE;
         publicIdentifier = longStrBufToString();
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
       case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
       case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
 
         forceQuirks = PR_TRUE;
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
       case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
 
         forceQuirks = PR_TRUE;
         systemIdentifier = longStrBufToString();
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
 
         forceQuirks = PR_TRUE;
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_BOGUS_DOCTYPE: {
         emitDoctypeToken(0);
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE: {
         emitOrAppendStrBuf(returnState);
         state = returnState;
         continue;
       }
       case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP: {
 
@@ -3597,80 +3594,76 @@ nsHtml5Tokenizer::eof()
         continue;
       }
       case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL: {
         for (; ; ) {
           PRUnichar c = '\0';
           entCol++;
           for (; ; ) {
             if (hi == -1) {
-              goto hiloop_end;
+              NS_HTML5_BREAK(hiloop);
             }
             if (entCol == nsHtml5NamedCharacters::NAMES[hi].length) {
-              goto hiloop_end;
+              NS_HTML5_BREAK(hiloop);
             }
             if (entCol > nsHtml5NamedCharacters::NAMES[hi].length) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             } else if (c < nsHtml5NamedCharacters::NAMES[hi][entCol]) {
               hi--;
             } else {
-              goto hiloop_end;
+              NS_HTML5_BREAK(hiloop);
             }
           }
           hiloop_end: ;
           for (; ; ) {
             if (hi < lo) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             }
             if (entCol == nsHtml5NamedCharacters::NAMES[lo].length) {
               candidate = lo;
               strBufMark = strBufLen;
               lo++;
             } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length) {
-              goto outer_end;
+              NS_HTML5_BREAK(outer);
             } else if (c > nsHtml5NamedCharacters::NAMES[lo][entCol]) {
               lo++;
             } else {
-              goto loloop_end;
+              NS_HTML5_BREAK(loloop);
             }
           }
           loloop_end: ;
           if (hi < lo) {
-            goto outer_end;
+            NS_HTML5_BREAK(outer);
           }
           continue;
         }
         outer_end: ;
         if (candidate == -1) {
 
           emitOrAppendStrBuf(returnState);
           state = returnState;
-          goto eofloop;
+          NS_HTML5_CONTINUE(eofloop);
         } else {
           jArray<PRInt8,PRInt32> candidateArr = nsHtml5NamedCharacters::NAMES[candidate];
           if (!candidateArr.length || candidateArr[candidateArr.length - 1] != ';') {
             if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               PRUnichar ch;
               if (strBufMark == strBufLen) {
                 ch = '\0';
               } else {
                 ch = strBuf[strBufMark];
               }
               if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
 
                 appendStrBufToLongStrBuf();
                 state = returnState;
-                goto eofloop;
+                NS_HTML5_CONTINUE(eofloop);
               }
             }
-            if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
 
-            } else {
-
-            }
           }
           const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
           if ((val[0] & 0xFC00) == 0xD800) {
             emitOrAppendTwo(val, returnState);
           } else {
             emitOrAppendOne(val, returnState);
           }
           if (strBufMark < strBufLen) {
@@ -3678,37 +3671,35 @@ nsHtml5Tokenizer::eof()
               for (PRInt32 i = strBufMark; i < strBufLen; i++) {
                 appendLongStrBuf(strBuf[i]);
               }
             } else {
               tokenHandler->characters(strBuf, strBufMark, strBufLen - strBufMark);
             }
           }
           state = returnState;
-          goto eofloop;
+          NS_HTML5_CONTINUE(eofloop);
         }
       }
       case NS_HTML5TOKENIZER_CONSUME_NCR:
       case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
       case NS_HTML5TOKENIZER_HEX_NCR_LOOP: {
         if (!seenDigits) {
 
           emitOrAppendStrBuf(returnState);
           state = returnState;
           continue;
-        } else {
-
         }
         handleNcrValue(returnState);
         state = returnState;
         continue;
       }
       case NS_HTML5TOKENIZER_DATA:
       default: {
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
     }
   }
   eofloop_end: ;
   tokenHandler->eof();
   return;
 }
 
@@ -3723,17 +3714,17 @@ nsHtml5Tokenizer::emitDoctypeToken(PRInt
   publicIdentifier = nsnull;
   nsHtml5Portability::releaseString(systemIdentifier);
   systemIdentifier = nsnull;
 }
 
 void 
 nsHtml5Tokenizer::internalEncodingDeclaration(nsString* internalCharset)
 {
-  if (!!encodingDeclarationHandler) {
+  if (encodingDeclarationHandler) {
     encodingDeclarationHandler->internalEncodingDeclaration(internalCharset);
   }
 }
 
 void 
 nsHtml5Tokenizer::emitOrAppendTwo(const PRUnichar* val, PRInt32 returnState)
 {
   if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
@@ -3758,34 +3749,34 @@ void
 nsHtml5Tokenizer::end()
 {
   strBuf.release();
   strBuf = nsnull;
   longStrBuf.release();
   longStrBuf = nsnull;
   nsHtml5Portability::releaseLocal(doctypeName);
   doctypeName = nsnull;
-  if (!!systemIdentifier) {
+  if (systemIdentifier) {
     nsHtml5Portability::releaseString(systemIdentifier);
     systemIdentifier = nsnull;
   }
-  if (!!publicIdentifier) {
+  if (publicIdentifier) {
     nsHtml5Portability::releaseString(publicIdentifier);
     publicIdentifier = nsnull;
   }
-  if (!!tagName) {
+  if (tagName) {
     tagName->release();
     tagName = nsnull;
   }
-  if (!!attributeName) {
+  if (attributeName) {
     attributeName->release();
     attributeName = nsnull;
   }
   tokenHandler->endTokenization();
-  if (!!attributes) {
+  if (attributes) {
     attributes->clear(0);
     delete attributes;
     attributes = nsnull;
   }
 }
 
 void 
 nsHtml5Tokenizer::requestSuspension()
@@ -3816,25 +3807,25 @@ nsHtml5Tokenizer::resetToDataState()
   candidate = -1;
   strBufMark = 0;
   prevValue = -1;
   value = 0;
   seenDigits = PR_FALSE;
   endTag = PR_FALSE;
   shouldSuspend = PR_FALSE;
   initDoctypeFields();
-  if (!!tagName) {
+  if (tagName) {
     tagName->release();
     tagName = nsnull;
   }
-  if (!!attributeName) {
+  if (attributeName) {
     attributeName->release();
     attributeName = nsnull;
   }
-  if (!!attributes) {
+  if (attributes) {
     delete attributes;
     attributes = nsnull;
   }
 }
 
 void 
 nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
 {
@@ -3882,33 +3873,33 @@ nsHtml5Tokenizer::loadState(nsHtml5Token
     systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
   }
   nsHtml5Portability::releaseString(publicIdentifier);
   if (!other->publicIdentifier) {
     publicIdentifier = nsnull;
   } else {
     publicIdentifier = nsHtml5Portability::newStringFromString(other->publicIdentifier);
   }
-  if (!!tagName) {
+  if (tagName) {
     tagName->release();
   }
   if (!other->tagName) {
     tagName = nsnull;
   } else {
     tagName = other->tagName->cloneElementName(interner);
   }
-  if (!!attributeName) {
+  if (attributeName) {
     attributeName->release();
   }
   if (!other->attributeName) {
     attributeName = nsnull;
   } else {
     attributeName = other->attributeName->cloneAttributeName(interner);
   }
-  if (!!attributes) {
+  if (attributes) {
     delete attributes;
   }
   if (!other->attributes) {
     attributes = nsnull;
   } else {
     attributes = other->attributes->cloneAttributes(interner);
   }
 }
--- a/parser/html/nsHtml5Tokenizer.h
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -42,16 +42,17 @@
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsAHtml5TreeBuilderState.h"
+#include "nsHtml5Macros.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -81,17 +81,17 @@ nsHtml5TreeBuilder::startTokenization(ns
   ;
   headPointer = nsnull;
   start(fragment);
   charBufferLen = 0;
   charBuffer = jArray<PRUnichar,PRInt32>(1024);
   framesetOk = PR_TRUE;
   if (fragment) {
     nsIContent** elt;
-    if (!!contextNode) {
+    if (contextNode) {
       elt = contextNode;
       ;
     } else {
       elt = createHtmlElementSetAsRoot(tokenizer->emptyAttributes());
     }
     nsHtml5StackNode* node = new nsHtml5StackNode(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HTML, elt);
     currentPtr++;
     stack[currentPtr] = node;
@@ -109,64 +109,56 @@ nsHtml5TreeBuilder::startTokenization(ns
     }
     nsHtml5Portability::releaseLocal(contextName);
     contextName = nsnull;
     ;
     contextNode = nsnull;
     ;
   } else {
     mode = NS_HTML5TREE_BUILDER_INITIAL;
-    foreignFlag = NS_HTML5TREE_BUILDER_NOT_IN_FOREIGN;
+    inForeign = PR_FALSE;
   }
 }
 
 void 
 nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, PRBool forceQuirks)
 {
   needToDropLF = PR_FALSE;
-  for (; ; ) {
-    switch(foreignFlag) {
-      case NS_HTML5TREE_BUILDER_IN_FOREIGN: {
-        goto doctypeloop_end;
+  if (!inForeign) {
+    switch(mode) {
+      case NS_HTML5TREE_BUILDER_INITIAL: {
+        nsString* emptyString = nsHtml5Portability::newEmptyString();
+        appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier);
+        nsHtml5Portability::releaseString(emptyString);
+        if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
+
+          documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
+        } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) {
+
+          documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
+        } else {
+          documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
+        }
+        mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+        return;
       }
       default: {
-        switch(mode) {
-          case NS_HTML5TREE_BUILDER_INITIAL: {
-            nsString* emptyString = nsHtml5Portability::newEmptyString();
-            appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier);
-            nsHtml5Portability::releaseString(emptyString);
-            if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
-
-              documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
-            } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) {
-
-              documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
-            } else {
-              documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, PR_FALSE);
-            }
-            mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
-            return;
-          }
-          default: {
-            goto doctypeloop_end;
-          }
-        }
+        break;
       }
     }
   }
-  doctypeloop_end: ;
 
   return;
 }
 
 void 
 nsHtml5TreeBuilder::comment(PRUnichar* buf, PRInt32 start, PRInt32 length)
 {
   needToDropLF = PR_FALSE;
-  if (foreignFlag != NS_HTML5TREE_BUILDER_IN_FOREIGN) {
+  if (!inForeign) {
     switch(mode) {
       case NS_HTML5TREE_BUILDER_INITIAL:
       case NS_HTML5TREE_BUILDER_BEFORE_HTML:
       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
         appendCommentToDocument(buf, start, length);
         return;
       }
@@ -236,21 +228,21 @@ nsHtml5TreeBuilder::characters(const PRU
               case NS_HTML5TREE_BUILDER_IN_BODY:
               case NS_HTML5TREE_BUILDER_IN_CELL:
               case NS_HTML5TREE_BUILDER_IN_CAPTION: {
                 if (start < i) {
                   accumulateCharacters(buf, start, i - start);
                   start = i;
                 }
                 reconstructTheActiveFormattingElements();
-                goto charactersloop_end;
+                NS_HTML5_BREAK(charactersloop);
               }
               case NS_HTML5TREE_BUILDER_IN_SELECT:
               case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
-                goto charactersloop_end;
+                NS_HTML5_BREAK(charactersloop);
               }
               case NS_HTML5TREE_BUILDER_IN_TABLE:
               case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
               case NS_HTML5TREE_BUILDER_IN_ROW: {
                 reconstructTheActiveFormattingElements();
                 accumulateCharacter(buf[i]);
                 start = i + 1;
                 continue;
@@ -338,17 +330,17 @@ nsHtml5TreeBuilder::characters(const PRU
               case NS_HTML5TREE_BUILDER_IN_BODY:
               case NS_HTML5TREE_BUILDER_IN_CELL:
               case NS_HTML5TREE_BUILDER_IN_CAPTION: {
                 if (start < i) {
                   accumulateCharacters(buf, start, i - start);
                   start = i;
                 }
                 reconstructTheActiveFormattingElements();
-                goto charactersloop_end;
+                NS_HTML5_BREAK(charactersloop);
               }
               case NS_HTML5TREE_BUILDER_IN_TABLE:
               case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
               case NS_HTML5TREE_BUILDER_IN_ROW: {
                 reconstructTheActiveFormattingElements();
                 accumulateCharacter(buf[i]);
                 start = i + 1;
                 continue;
@@ -365,17 +357,17 @@ nsHtml5TreeBuilder::characters(const PRU
                 }
                 pop();
                 mode = NS_HTML5TREE_BUILDER_IN_TABLE;
                 i--;
                 continue;
               }
               case NS_HTML5TREE_BUILDER_IN_SELECT:
               case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
-                goto charactersloop_end;
+                NS_HTML5_BREAK(charactersloop);
               }
               case NS_HTML5TREE_BUILDER_AFTER_BODY: {
 
 
                 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
                 i--;
                 continue;
               }
@@ -420,22 +412,22 @@ nsHtml5TreeBuilder::characters(const PRU
     }
   }
 }
 
 void 
 nsHtml5TreeBuilder::eof()
 {
   flushCharacters();
-  if (foreignFlag == NS_HTML5TREE_BUILDER_IN_FOREIGN) {
+  if (inForeign) {
 
     while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
       popOnEof();
     }
-    foreignFlag = NS_HTML5TREE_BUILDER_NOT_IN_FOREIGN;
+    inForeign = PR_FALSE;
   }
   for (; ; ) {
     switch(mode) {
       case NS_HTML5TREE_BUILDER_INITIAL: {
         documentModeInternal(QUIRKS_MODE, nsnull, nsnull, PR_FALSE);
         mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
         continue;
       }
@@ -445,19 +437,17 @@ nsHtml5TreeBuilder::eof()
         continue;
       }
       case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
         appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
         mode = NS_HTML5TREE_BUILDER_IN_HEAD;
         continue;
       }
       case NS_HTML5TREE_BUILDER_IN_HEAD: {
-        if (currentPtr > 1) {
-
-        }
+
         while (currentPtr > 0) {
           popOnEof();
         }
         mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
         continue;
       }
       case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
 
@@ -470,55 +460,53 @@ nsHtml5TreeBuilder::eof()
       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
         appendToCurrentNodeAndPushBodyElement();
         mode = NS_HTML5TREE_BUILDER_IN_BODY;
         continue;
       }
       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
         if (!currentPtr) {
 
-          goto eofloop_end;
+          NS_HTML5_BREAK(eofloop);
         } else {
           popOnEof();
           mode = NS_HTML5TREE_BUILDER_IN_TABLE;
           continue;
         }
       }
       case NS_HTML5TREE_BUILDER_FRAMESET_OK:
       case NS_HTML5TREE_BUILDER_IN_CAPTION:
       case NS_HTML5TREE_BUILDER_IN_CELL:
       case NS_HTML5TREE_BUILDER_IN_BODY: {
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TREE_BUILDER_TEXT: {
 
         if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
           popOnEof();
         }
         popOnEof();
         mode = originalMode;
         continue;
       }
       case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
       case NS_HTML5TREE_BUILDER_IN_ROW:
       case NS_HTML5TREE_BUILDER_IN_TABLE:
       case NS_HTML5TREE_BUILDER_IN_SELECT:
       case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE:
       case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
-        if (currentPtr > 0) {
-
-        }
-        goto eofloop_end;
+
+        NS_HTML5_BREAK(eofloop);
       }
       case NS_HTML5TREE_BUILDER_AFTER_BODY:
       case NS_HTML5TREE_BUILDER_AFTER_FRAMESET:
       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET:
       default: {
-        goto eofloop_end;
+        NS_HTML5_BREAK(eofloop);
       }
     }
   }
   eofloop_end: ;
   while (currentPtr > 0) {
     popOnEof();
   }
   if (!fragment) {
@@ -528,1267 +516,1251 @@ nsHtml5TreeBuilder::eof()
 
 void 
 nsHtml5TreeBuilder::endTokenization()
 {
   ;
   formPointer = nsnull;
   ;
   headPointer = nsnull;
-  if (!!stack) {
+  if (stack) {
     while (currentPtr > -1) {
       stack[currentPtr]->release();
       currentPtr--;
     }
     stack.release();
     stack = nsnull;
   }
-  if (!!listOfActiveFormattingElements) {
+  if (listOfActiveFormattingElements) {
     while (listPtr > -1) {
-      if (!!listOfActiveFormattingElements[listPtr]) {
+      if (listOfActiveFormattingElements[listPtr]) {
         listOfActiveFormattingElements[listPtr]->release();
       }
       listPtr--;
     }
     listOfActiveFormattingElements.release();
     listOfActiveFormattingElements = nsnull;
   }
-  if (!!charBuffer) {
+  if (charBuffer) {
     charBuffer.release();
     charBuffer = nsnull;
   }
   end();
 }
 
 void 
 nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, PRBool selfClosing)
 {
   PRInt32 eltPos;
   needToDropLF = PR_FALSE;
   PRBool needsPostProcessing = PR_FALSE;
   starttagloop: for (; ; ) {
     PRInt32 group = elementName->group;
     nsIAtom* name = elementName->name;
-    switch(foreignFlag) {
-      case NS_HTML5TREE_BUILDER_IN_FOREIGN: {
-        nsHtml5StackNode* currentNode = stack[currentPtr];
-        PRInt32 currNs = currentNode->ns;
-        PRInt32 currGroup = currentNode->group;
-        if ((kNameSpaceID_XHTML == currNs) || (kNameSpaceID_MathML == currNs && ((NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK != group && NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT == currGroup) || (NS_HTML5TREE_BUILDER_SVG == group && NS_HTML5TREE_BUILDER_ANNOTATION_XML == currGroup))) || (kNameSpaceID_SVG == currNs && (NS_HTML5TREE_BUILDER_TITLE == currGroup || (NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC == currGroup)))) {
-          needsPostProcessing = PR_TRUE;
-        } else {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
-            case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_BR:
-            case NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
-            case NS_HTML5TREE_BUILDER_DD_OR_DT:
-            case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
-            case NS_HTML5TREE_BUILDER_EMBED_OR_IMG:
-            case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
-            case NS_HTML5TREE_BUILDER_HEAD:
-            case NS_HTML5TREE_BUILDER_HR:
-            case NS_HTML5TREE_BUILDER_LI:
-            case NS_HTML5TREE_BUILDER_META:
-            case NS_HTML5TREE_BUILDER_NOBR:
-            case NS_HTML5TREE_BUILDER_P:
-            case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
-            case NS_HTML5TREE_BUILDER_TABLE: {
+    if (inForeign) {
+      nsHtml5StackNode* currentNode = stack[currentPtr];
+      PRInt32 currNs = currentNode->ns;
+      PRInt32 currGroup = currentNode->group;
+      if ((kNameSpaceID_XHTML == currNs) || (kNameSpaceID_MathML == currNs && ((NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK != group && NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT == currGroup) || (NS_HTML5TREE_BUILDER_SVG == group && NS_HTML5TREE_BUILDER_ANNOTATION_XML == currGroup))) || (kNameSpaceID_SVG == currNs && (NS_HTML5TREE_BUILDER_TITLE == currGroup || (NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC == currGroup)))) {
+        needsPostProcessing = PR_TRUE;
+      } else {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
+          case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_BR:
+          case NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
+          case NS_HTML5TREE_BUILDER_DD_OR_DT:
+          case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
+          case NS_HTML5TREE_BUILDER_EMBED_OR_IMG:
+          case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
+          case NS_HTML5TREE_BUILDER_HEAD:
+          case NS_HTML5TREE_BUILDER_HR:
+          case NS_HTML5TREE_BUILDER_LI:
+          case NS_HTML5TREE_BUILDER_META:
+          case NS_HTML5TREE_BUILDER_NOBR:
+          case NS_HTML5TREE_BUILDER_P:
+          case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
+          case NS_HTML5TREE_BUILDER_TABLE: {
+
+            while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
+              pop();
+            }
+            inForeign = PR_FALSE;
+            NS_HTML5_CONTINUE(starttagloop);
+          }
+          case NS_HTML5TREE_BUILDER_FONT: {
+            if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) {
 
               while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
                 pop();
               }
-              foreignFlag = NS_HTML5TREE_BUILDER_NOT_IN_FOREIGN;
-              goto starttagloop;
-            }
-            case NS_HTML5TREE_BUILDER_FONT: {
-              if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) {
-
-                while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
-                  pop();
-                }
-                foreignFlag = NS_HTML5TREE_BUILDER_NOT_IN_FOREIGN;
-                goto starttagloop;
-              }
+              inForeign = PR_FALSE;
+              NS_HTML5_CONTINUE(starttagloop);
             }
-            default: {
-              if (kNameSpaceID_SVG == currNs) {
-                attributes->adjustForSvg();
-                if (selfClosing) {
-                  appendVoidElementToCurrentMayFosterCamelCase(currNs, elementName, attributes);
-                  selfClosing = PR_FALSE;
-                } else {
-                  appendToCurrentNodeAndPushElementMayFosterCamelCase(currNs, elementName, attributes);
-                }
-                attributes = nsnull;
-                goto starttagloop_end;
+          }
+          default: {
+            if (kNameSpaceID_SVG == currNs) {
+              attributes->adjustForSvg();
+              if (selfClosing) {
+                appendVoidElementToCurrentMayFosterCamelCase(currNs, elementName, attributes);
+                selfClosing = PR_FALSE;
               } else {
-                attributes->adjustForMath();
-                if (selfClosing) {
-                  appendVoidElementToCurrentMayFoster(currNs, elementName, attributes);
-                  selfClosing = PR_FALSE;
-                } else {
-                  appendToCurrentNodeAndPushElementMayFosterNoScoping(currNs, elementName, attributes);
-                }
-                attributes = nsnull;
-                goto starttagloop_end;
+                appendToCurrentNodeAndPushElementMayFosterCamelCase(currNs, elementName, attributes);
               }
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            } else {
+              attributes->adjustForMath();
+              if (selfClosing) {
+                appendVoidElementToCurrentMayFoster(currNs, elementName, attributes);
+                selfClosing = PR_FALSE;
+              } else {
+                appendToCurrentNodeAndPushElementMayFosterNoScoping(currNs, elementName, attributes);
+              }
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
             }
           }
         }
       }
-      default: {
-        switch(mode) {
-          case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
-            switch(group) {
-              case NS_HTML5TREE_BUILDER_TR: {
-                clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
-                appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
-                mode = NS_HTML5TREE_BUILDER_IN_ROW;
-                attributes = nsnull;
-                goto starttagloop_end;
-              }
-              case NS_HTML5TREE_BUILDER_TD_OR_TH: {
-
-                clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
-                appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_TR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
-                mode = NS_HTML5TREE_BUILDER_IN_ROW;
-                continue;
+    }
+    switch(mode) {
+      case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TR: {
+            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
+            appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+            mode = NS_HTML5TREE_BUILDER_IN_ROW;
+            attributes = nsnull;
+            NS_HTML5_BREAK(starttagloop);
+          }
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+
+            clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
+            appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_TR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+            mode = NS_HTML5TREE_BUILDER_IN_ROW;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+            eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
+            if (!eltPos) {
+
+              NS_HTML5_BREAK(starttagloop);
+            } else {
+              clearStackBackTo(eltPos);
+              pop();
+              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+              continue;
+            }
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_ROW: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+            clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR));
+            appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+            mode = NS_HTML5TREE_BUILDER_IN_CELL;
+            insertMarker();
+            attributes = nsnull;
+            NS_HTML5_BREAK(starttagloop);
+          }
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TR: {
+            eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+            if (!eltPos) {
+
+
+              NS_HTML5_BREAK(starttagloop);
+            }
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+            continue;
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_TABLE: {
+        for (; ; ) {
+          switch(group) {
+            case NS_HTML5TREE_BUILDER_CAPTION: {
+              clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+              insertMarker();
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+              mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_COLGROUP: {
+              clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+              mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_COL: {
+              clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_COLGROUP, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+              mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
+              NS_HTML5_CONTINUE(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+              clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+              mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_TR:
+            case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+              clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_TBODY, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+              mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+              NS_HTML5_CONTINUE(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_TABLE: {
+
+              eltPos = findLastInTableScope(name);
+              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
+                NS_HTML5_BREAK(starttagloop);
               }
-              case NS_HTML5TREE_BUILDER_CAPTION:
-              case NS_HTML5TREE_BUILDER_COL:
-              case NS_HTML5TREE_BUILDER_COLGROUP:
-              case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
-                eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
-                if (!eltPos) {
-
-                  goto starttagloop_end;
-                } else {
-                  clearStackBackTo(eltPos);
-                  pop();
-                  mode = NS_HTML5TREE_BUILDER_IN_TABLE;
-                  continue;
-                }
+              generateImpliedEndTags();
+
+              while (currentPtr >= eltPos) {
+                pop();
               }
-              default:
-                ; // fall through
+              resetTheInsertionMode();
+              NS_HTML5_CONTINUE(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_SCRIPT: {
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+              originalMode = mode;
+              mode = NS_HTML5TREE_BUILDER_TEXT;
+              tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_STYLE: {
+              appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
+              originalMode = mode;
+              mode = NS_HTML5TREE_BUILDER_TEXT;
+              tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_INPUT: {
+              if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE))) {
+                NS_HTML5_BREAK(intableloop);
+              }
+              appendVoidElementToCurrent(kNameSpaceID_XHTML, name, attributes, formPointer);
+              selfClosing = PR_FALSE;
+              attributes = nsnull;
+              NS_HTML5_BREAK(starttagloop);
+            }
+            case NS_HTML5TREE_BUILDER_FORM: {
+              if (formPointer) {
+
+                NS_HTML5_BREAK(starttagloop);
+              } else {
+
+                appendVoidFormToCurrent(attributes);
+                attributes = nsnull;
+                NS_HTML5_BREAK(starttagloop);
+              }
+            }
+            default: {
+
+              NS_HTML5_BREAK(intableloop);
             }
           }
-          case NS_HTML5TREE_BUILDER_IN_ROW: {
-            switch(group) {
-              case NS_HTML5TREE_BUILDER_TD_OR_TH: {
-                clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR));
+        }
+        intableloop_end: ;
+      }
+      case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TR:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+
+            eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              NS_HTML5_BREAK(starttagloop);
+            }
+            generateImpliedEndTags();
+
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            continue;
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_CELL: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TR:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+            eltPos = findLastInTableScopeTdTh();
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
+              NS_HTML5_BREAK(starttagloop);
+            } else {
+              closeTheCell(eltPos);
+              continue;
+            }
+          }