Bug 579867 - Make foreign content end tag handling not loop back after processing the token in the secondary insertion mode. SVG part of reftest by longsonr. rs=sicking, a=blocking2.0-betaN.
authorHenri Sivonen <hsivonen@iki.fi>
Wed, 21 Jul 2010 16:10:58 +0300
changeset 49146 16bc32053260f9038989f56c394f0347631e35c8
parent 49145 dfe93184c6fa5eedc1ee5ecd3be1c8e46842e3eb
child 49147 96f758f85b42dca038a4a1d42c03d019133ab7fe
push id14922
push userphilringnalda@gmail.com
push dateSun, 08 Aug 2010 01:05:21 +0000
treeherdermozilla-central@16bc32053260 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, blocking2
bugs579867
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 579867 - Make foreign content end tag handling not loop back after processing the token in the secondary insertion mode. SVG part of reftest by longsonr. rs=sicking, a=blocking2.0-betaN. Bug 579867 - Make foreign content end tag handling not loop back after processing the token in the secondary insertion mode. SVG part of reftest by longsonr. rs=sicking, a=blocking2.0-betaN.
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5TreeBuilder.cpp
parser/htmlparser/tests/crashtests/574884-1.html
parser/htmlparser/tests/crashtests/574884-2.html
parser/htmlparser/tests/crashtests/crashtests.list
parser/htmlparser/tests/reftest/bug566280-1-ref.html~
parser/htmlparser/tests/reftest/bug577418-1-ref.html
parser/htmlparser/tests/reftest/bug577418-1.html
parser/htmlparser/tests/reftest/reftest.list
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -3100,832 +3100,776 @@ public abstract class TreeBuilder<T> imp
             Portability.releaseString(internalCharsetLegacy);
             requestSuspension();
         }
     }
 
     public final void endTag(ElementName elementName) throws SAXException {
         needToDropLF = false;
         int eltPos;
-        int eltPosForeign;
         int group = elementName.group;
         @Local String name = elementName.name;
-        assert !inForeign || currentPtr >= 0: "In foreign without a root element?";
-        if (inForeign && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
-            /*
-             * This is the initialization step of handling end tags while in
-             * foreign content and the current node is not an HTML node.
-             * 
-             * inforeignloop is used as the loop in order to be able to use the
-             * big switch below as part of the loop.
-             * 
-             * All other cases just return at the end of inforeignloop.
-             * 
-             * This initialization step can itself be outside endtagloop,
-             * because an end tag token never gets reprocessed in the
-             * "in foreign" mode if the mode wasn't "in foreign" to begin with.
-             */
-            eltPosForeign = currentPtr;
-            // [NOCPP[
-            StackNode<T> node = stack[currentPtr];
-            if (errorHandler != null && node.name != name) {
-                errNoCheck("End tag \u201C"
-                        + name
-                        + "\u201D did not match the name of the current open element (\u201C"
-                        + node.popName + "\u201D).");
-            }
-            // ]NOCPP]
-        } else {
-            /*
-             * Marker for not wanting to continue inforeignloop.
-             */
-            eltPosForeign = -1;
-        }
-        inforeignloop: for (;;) {
-            if (eltPosForeign != -1) {
-                /*
-                 * Handling an end tag where initially the tree builder was in
-                 * the "in foreign" mode and the current node was not an HTML
-                 * node.
-                 */
-                if (currentPtr >= eltPosForeign && stack[eltPosForeign].name == name) {
-                    while (currentPtr >= eltPosForeign) {
-                        pop();
+        endtagloop: for (;;) {
+            assert !inForeign || currentPtr >= 0 : "In foreign without a root element?";
+            if (inForeign
+                    && stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
+                if (errorHandler != null && stack[currentPtr].name != name) {
+                    errNoCheck("End tag \u201C"
+                            + name
+                            + "\u201D did not match the name of the current open element (\u201C"
+                            + stack[currentPtr].popName + "\u201D).");
+                }
+                eltPos = currentPtr;
+                for (;;) {
+                    if (stack[eltPos].name == name) {
+                        while (currentPtr >= eltPos) {
+                            pop();
+                        }
+                        return;
                     }
-                    return;
-                }
-                if (--eltPosForeign > currentPtr) {
-                    continue inforeignloop;
-                }
-                if (eltPosForeign == -1) {
-                    return;
-                }
-                if (stack[eltPosForeign].ns != "http://www.w3.org/1999/xhtml") {
-                    continue inforeignloop;
+                    if (stack[--eltPos].ns == "http://www.w3.org/1999/xhtml") {
+                        break;
+                    }
                 }
-                /*
-                 * Else go through the big switch and re-check after it.
-                 */
             }
-            endtagloop: for (;;) {
-                switch (mode) {
-                    case IN_ROW:
-                        switch (group) {
-                            case TR:
-                                eltPos = findLastOrRoot(TreeBuilder.TR);
-                                if (eltPos == 0) {
-                                    assert fragment;
-                                    err("No table row to close.");
-                                    break endtagloop;
-                                }
-                                clearStackBackTo(eltPos);
-                                pop();
-                                mode = IN_TABLE_BODY;
+            switch (mode) {
+                case IN_ROW:
+                    switch (group) {
+                        case TR:
+                            eltPos = findLastOrRoot(TreeBuilder.TR);
+                            if (eltPos == 0) {
+                                assert fragment;
+                                err("No table row to close.");
+                                break endtagloop;
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE_BODY;
+                            break endtagloop;
+                        case TABLE:
+                            eltPos = findLastOrRoot(TreeBuilder.TR);
+                            if (eltPos == 0) {
+                                assert fragment;
+                                err("No table row to close.");
                                 break endtagloop;
-                            case TABLE:
-                                eltPos = findLastOrRoot(TreeBuilder.TR);
-                                if (eltPos == 0) {
-                                    assert fragment;
-                                    err("No table row to close.");
-                                    break endtagloop;
-                                }
-                                clearStackBackTo(eltPos);
-                                pop();
-                                mode = IN_TABLE_BODY;
-                                continue;
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                                if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    err("Stray end tag \u201C" + name
-                                            + "\u201D.");
-                                    break endtagloop;
-                                }
-                                eltPos = findLastOrRoot(TreeBuilder.TR);
-                                if (eltPos == 0) {
-                                    assert fragment;
-                                    err("No table row to close.");
-                                    break endtagloop;
-                                }
-                                clearStackBackTo(eltPos);
-                                pop();
-                                mode = IN_TABLE_BODY;
-                                continue;
-                            case BODY:
-                            case CAPTION:
-                            case COL:
-                            case COLGROUP:
-                            case HTML:
-                            case TD_OR_TH:
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE_BODY;
+                            continue;
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                            if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                err("Stray end tag \u201C" + name + "\u201D.");
+                                break endtagloop;
+                            }
+                            eltPos = findLastOrRoot(TreeBuilder.TR);
+                            if (eltPos == 0) {
+                                assert fragment;
+                                err("No table row to close.");
+                                break endtagloop;
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE_BODY;
+                            continue;
+                        case BODY:
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case HTML:
+                        case TD_OR_TH:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        default:
+                            // fall through to IN_TABLE
+                    }
+                case IN_TABLE_BODY:
+                    switch (group) {
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                            eltPos = findLastOrRoot(name);
+                            if (eltPos == 0) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                                 break endtagloop;
-                            default:
-                                // fall through to IN_TABLE
-                        }
-                    case IN_TABLE_BODY:
-                        switch (group) {
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                                eltPos = findLastOrRoot(name);
-                                if (eltPos == 0) {
-                                    err("Stray end tag \u201C" + name
-                                            + "\u201D.");
-                                    break endtagloop;
-                                }
-                                clearStackBackTo(eltPos);
-                                pop();
-                                mode = IN_TABLE;
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE;
+                            break endtagloop;
+                        case TABLE:
+                            eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
+                            if (eltPos == 0) {
+                                assert fragment;
+                                err("Stray end tag \u201Ctable\u201D.");
+                                break endtagloop;
+                            }
+                            clearStackBackTo(eltPos);
+                            pop();
+                            mode = IN_TABLE;
+                            continue;
+                        case BODY:
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case HTML:
+                        case TD_OR_TH:
+                        case TR:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        default:
+                            // fall through to IN_TABLE
+                    }
+                case IN_TABLE:
+                    switch (group) {
+                        case TABLE:
+                            eltPos = findLast("table");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment;
+                                err("Stray end tag \u201Ctable\u201D.");
                                 break endtagloop;
-                            case TABLE:
-                                eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
-                                if (eltPos == 0) {
-                                    assert fragment;
-                                    err("Stray end tag \u201Ctable\u201D.");
-                                    break endtagloop;
-                                }
-                                clearStackBackTo(eltPos);
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
+                            }
+                            resetTheInsertionMode();
+                            break endtagloop;
+                        case BODY:
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case HTML:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TD_OR_TH:
+                        case TR:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            // fall through to IN_BODY
+                    }
+                case IN_CAPTION:
+                    switch (group) {
+                        case CAPTION:
+                            eltPos = findLastInTableScope("caption");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                break endtagloop;
+                            }
+                            generateImpliedEndTags();
+                            if (errorHandler != null && currentPtr != eltPos) {
+                                errNoCheck("Unclosed elements on stack.");
+                            }
+                            while (currentPtr >= eltPos) {
                                 pop();
-                                mode = IN_TABLE;
-                                continue;
-                            case BODY:
-                            case CAPTION:
-                            case COL:
-                            case COLGROUP:
-                            case HTML:
-                            case TD_OR_TH:
-                            case TR:
+                            }
+                            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 (errorHandler != null && currentPtr != eltPos) {
+                                errNoCheck("Unclosed elements on stack.");
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
+                            }
+                            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+                            mode = IN_TABLE;
+                            continue;
+                        case BODY:
+                        case COL:
+                        case COLGROUP:
+                        case HTML:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TD_OR_TH:
+                        case TR:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        default:
+                            // fall through to IN_BODY
+                    }
+                case IN_CELL:
+                    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;
-                            default:
-                                // fall through to IN_TABLE
-                        }
-                    case IN_TABLE:
-                        switch (group) {
-                            case TABLE:
-                                eltPos = findLast("table");
-                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    assert fragment;
-                                    err("Stray end tag \u201Ctable\u201D.");
-                                    break endtagloop;
+                            }
+                            generateImpliedEndTags();
+                            if (errorHandler != null && !isCurrent(name)) {
+                                errNoCheck("Unclosed elements.");
+                            }
+                            while (currentPtr >= eltPos) {
+                                pop();
+                            }
+                            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+                            mode = IN_ROW;
+                            break endtagloop;
+                        case TABLE:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                            if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                err("Stray end tag \u201C" + name + "\u201D.");
+                                break endtagloop;
+                            }
+                            closeTheCell(findLastInTableScopeTdTh());
+                            continue;
+                        case BODY:
+                        case CAPTION:
+                        case COL:
+                        case COLGROUP:
+                        case HTML:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        default:
+                            // fall through to IN_BODY
+                    }
+                case FRAMESET_OK:
+                case IN_BODY:
+                    switch (group) {
+                        case BODY:
+                            if (!isSecondOnStackBody()) {
+                                assert fragment;
+                                err("Stray end tag \u201Cbody\u201D.");
+                                break endtagloop;
+                            }
+                            assert currentPtr >= 1;
+                            if (errorHandler != null) {
+                                uncloseloop1: for (int i = 2; i <= currentPtr; i++) {
+                                    switch (stack[i].group) {
+                                        case DD_OR_DT:
+                                        case LI:
+                                        case OPTGROUP:
+                                        case OPTION: // is this possible?
+                                        case P:
+                                        case RT_OR_RP:
+                                        case TD_OR_TH:
+                                        case TBODY_OR_THEAD_OR_TFOOT:
+                                            break;
+                                        default:
+                                            err("End tag for \u201Cbody\u201D seen but there were unclosed elements.");
+                                            break uncloseloop1;
+                                    }
+                                }
+                            }
+                            mode = AFTER_BODY;
+                            break endtagloop;
+                        case HTML:
+                            if (!isSecondOnStackBody()) {
+                                assert fragment;
+                                err("Stray end tag \u201Chtml\u201D.");
+                                break endtagloop;
+                            }
+                            if (errorHandler != null) {
+                                uncloseloop2: for (int i = 0; i <= currentPtr; i++) {
+                                    switch (stack[i].group) {
+                                        case DD_OR_DT:
+                                        case LI:
+                                        case P:
+                                        case TBODY_OR_THEAD_OR_TFOOT:
+                                        case TD_OR_TH:
+                                        case BODY:
+                                        case HTML:
+                                            break;
+                                        default:
+                                            err("End tag for \u201Chtml\u201D seen but there were unclosed elements.");
+                                            break uncloseloop2;
+                                    }
+                                }
+                            }
+                            mode = AFTER_BODY;
+                            continue;
+                        case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+                        case UL_OR_OL_OR_DL:
+                        case PRE_OR_LISTING:
+                        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 (errorHandler != null && !isCurrent(name)) {
+                                    errNoCheck("End tag \u201C"
+                                            + name
+                                            + "\u201D seen but there were unclosed elements.");
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
-                                resetTheInsertionMode();
+                            }
+                            break endtagloop;
+                        case FORM:
+                            if (formPointer == null) {
+                                err("Stray end tag \u201C" + name + "\u201D.");
                                 break endtagloop;
-                            case BODY:
-                            case CAPTION:
-                            case COL:
-                            case COLGROUP:
-                            case HTML:
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                            case TD_OR_TH:
-                            case TR:
+                            }
+                            Portability.releaseElement(formPointer);
+                            formPointer = null;
+                            eltPos = findLastInScope(name);
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                 err("Stray end tag \u201C" + name + "\u201D.");
                                 break endtagloop;
-                            default:
+                            }
+                            generateImpliedEndTags();
+                            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 (inForeign) {
+                                    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;
+                                }
+                                appendVoidElementToCurrentMayFoster(
+                                        "http://www.w3.org/1999/xhtml",
+                                        elementName,
+                                        HtmlAttributes.EMPTY_ATTRIBUTES);
+                                break endtagloop;
+                            }
+                            generateImpliedEndTagsExceptFor("p");
+                            assert eltPos != TreeBuilder.NOT_FOUND_ON_STACK;
+                            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 (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 (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.");
-                                // fall through to IN_BODY
-                        }
-                    case IN_CAPTION:
-                        switch (group) {
-                            case CAPTION:
-                                eltPos = findLastInTableScope("caption");
-                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    break endtagloop;
+                            } else {
+                                generateImpliedEndTags();
+                                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:
+                        case FONT:
+                        case NOBR:
+                            adoptionAgencyEndTag(name);
+                            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 (errorHandler != null
-                                        && currentPtr != eltPos) {
-                                    errNoCheck("Unclosed elements on stack.");
+                                if (errorHandler != null && !isCurrent(name)) {
+                                    errNoCheck("End tag \u201C"
+                                            + name
+                                            + "\u201D seen but there were unclosed elements.");
                                 }
                                 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 (errorHandler != null
-                                        && currentPtr != eltPos) {
-                                    errNoCheck("Unclosed elements on stack.");
-                                }
-                                while (currentPtr >= eltPos) {
-                                    pop();
-                                }
-                                clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-                                mode = IN_TABLE;
-                                continue;
-                            case BODY:
-                            case COL:
-                            case COLGROUP:
-                            case HTML:
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                            case TD_OR_TH:
-                            case TR:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                            default:
-                                // fall through to IN_BODY
-                        }
-                    case IN_CELL:
-                        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 (errorHandler != null && !isCurrent(name)) {
-                                    errNoCheck("Unclosed elements.");
-                                }
-                                while (currentPtr >= eltPos) {
+                            }
+                            break endtagloop;
+                        case BR:
+                            err("End tag \u201Cbr\u201D.");
+                            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();
                                 }
-                                clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-                                mode = IN_ROW;
-                                break endtagloop;
-                            case TABLE:
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                            case TR:
-                                if (findLastInTableScope(name) == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    err("Stray end tag \u201C" + name
-                                            + "\u201D.");
-                                    break endtagloop;
-                                }
-                                closeTheCell(findLastInTableScopeTdTh());
-                                continue;
-                            case BODY:
-                            case CAPTION:
-                            case COL:
-                            case COLGROUP:
-                            case HTML:
-                                err("Stray end tag \u201C" + name + "\u201D.");
+                                inForeign = false;
+                            }
+                            reconstructTheActiveFormattingElements();
+                            appendVoidElementToCurrentMayFoster(
+                                    "http://www.w3.org/1999/xhtml",
+                                    elementName,
+                                    HtmlAttributes.EMPTY_ATTRIBUTES);
+                            break endtagloop;
+                        case AREA_OR_SPACER_OR_WBR:
+                        case PARAM_OR_SOURCE:
+                        case EMBED_OR_IMG:
+                        case IMAGE:
+                        case INPUT:
+                        case KEYGEN: // XXX??
+                        case HR:
+                        case ISINDEX:
+                        case IFRAME:
+                        case NOEMBED: // XXX???
+                        case NOFRAMES: // XXX??
+                        case SELECT:
+                        case TABLE:
+                        case TEXTAREA: // XXX??
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                        case NOSCRIPT:
+                            if (scriptingEnabled) {
+                                err("Stray end tag \u201Cnoscript\u201D.");
                                 break endtagloop;
-                            default:
-                                // fall through to IN_BODY
-                        }
-                    case FRAMESET_OK:
-                    case IN_BODY:
-                        switch (group) {
-                            case BODY:
-                                if (!isSecondOnStackBody()) {
-                                    assert fragment;
-                                    err("Stray end tag \u201Cbody\u201D.");
-                                    break endtagloop;
-                                }
-                                assert currentPtr >= 1;
-                                if (errorHandler != null) {
-                                    uncloseloop1: for (int i = 2; i <= currentPtr; i++) {
-                                        switch (stack[i].group) {
-                                            case DD_OR_DT:
-                                            case LI:
-                                            case OPTGROUP:
-                                            case OPTION: // is this possible?
-                                            case P:
-                                            case RT_OR_RP:
-                                            case TD_OR_TH:
-                                            case TBODY_OR_THEAD_OR_TFOOT:
-                                                break;
-                                            default:
-                                                err("End tag for \u201Cbody\u201D seen but there were unclosed elements.");
-                                                break uncloseloop1;
-                                        }
-                                    }
-                                }
-                                mode = AFTER_BODY;
+                            } else {
+                                // fall through
+                            }
+                        default:
+                            if (isCurrent(name)) {
+                                pop();
                                 break endtagloop;
-                            case HTML:
-                                if (!isSecondOnStackBody()) {
-                                    assert fragment;
-                                    err("Stray end tag \u201Chtml\u201D.");
-                                    break endtagloop;
-                                }
-                                if (errorHandler != null) {
-                                    uncloseloop2: for (int i = 0; i <= currentPtr; i++) {
-                                        switch (stack[i].group) {
-                                            case DD_OR_DT:
-                                            case LI:
-                                            case P:
-                                            case TBODY_OR_THEAD_OR_TFOOT:
-                                            case TD_OR_TH:
-                                            case BODY:
-                                            case HTML:
-                                                break;
-                                            default:
-                                                err("End tag for \u201Chtml\u201D seen but there were unclosed elements.");
-                                                break uncloseloop2;
-                                        }
-                                    }
-                                }
-                                mode = AFTER_BODY;
-                                continue;
-                            case DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
-                            case UL_OR_OL_OR_DL:
-                            case PRE_OR_LISTING:
-                            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 {
+                            }
+
+                            eltPos = currentPtr;
+                            for (;;) {
+                                StackNode<T> node = stack[eltPos];
+                                if (node.name == name) {
                                     generateImpliedEndTags();
                                     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) {
-                                    err("Stray end tag \u201C" + name
-                                            + "\u201D.");
                                     break endtagloop;
-                                }
-                                Portability.releaseElement(formPointer);
-                                formPointer = null;
-                                eltPos = findLastInScope(name);
-                                if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                } else if (node.scoping || node.special) {
                                     err("Stray end tag \u201C" + name
                                             + "\u201D.");
                                     break endtagloop;
                                 }
-                                generateImpliedEndTags();
-                                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 (inForeign) {
-                                        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;
-                                    }
-                                    appendVoidElementToCurrentMayFoster(
-                                            "http://www.w3.org/1999/xhtml",
-                                            elementName,
-                                            HtmlAttributes.EMPTY_ATTRIBUTES);
-                                    break endtagloop;
-                                }
-                                generateImpliedEndTagsExceptFor("p");
-                                assert eltPos != TreeBuilder.NOT_FOUND_ON_STACK;
-                                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 (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 (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 (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:
-                            case FONT:
-                            case NOBR:
-                                adoptionAgencyEndTag(name);
-                                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 (errorHandler != null
-                                            && !isCurrent(name)) {
-                                        errNoCheck("End tag \u201C"
-                                                + name
-                                                + "\u201D seen but there were unclosed elements.");
-                                    }
-                                    while (currentPtr >= eltPos) {
-                                        pop();
-                                    }
-                                    clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-                                }
+                                eltPos--;
+                            }
+                    }
+                case IN_COLUMN_GROUP:
+                    switch (group) {
+                        case COLGROUP:
+                            if (currentPtr == 0) {
+                                assert fragment;
+                                err("Garbage in \u201Ccolgroup\u201D fragment.");
                                 break endtagloop;
-                            case BR:
-                                err("End tag \u201Cbr\u201D.");
-                                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();
-                                    }
-                                    inForeign = false;
-                                }
-                                reconstructTheActiveFormattingElements();
-                                appendVoidElementToCurrentMayFoster(
-                                        "http://www.w3.org/1999/xhtml",
-                                        elementName,
-                                        HtmlAttributes.EMPTY_ATTRIBUTES);
-                                break endtagloop;
-                            case AREA_OR_SPACER_OR_WBR:
-                            case PARAM_OR_SOURCE:
-                            case EMBED_OR_IMG:
-                            case IMAGE:
-                            case INPUT:
-                            case KEYGEN: // XXX??
-                            case HR:
-                            case ISINDEX:
-                            case IFRAME:
-                            case NOEMBED: // XXX???
-                            case NOFRAMES: // XXX??
-                            case SELECT:
-                            case TABLE:
-                            case TEXTAREA: // XXX??
-                                err("Stray end tag \u201C" + name + "\u201D.");
+                            }
+                            pop();
+                            mode = IN_TABLE;
+                            break endtagloop;
+                        case COL:
+                            err("Stray end tag \u201Ccol\u201D.");
+                            break endtagloop;
+                        default:
+                            if (currentPtr == 0) {
+                                assert fragment;
+                                err("Garbage in \u201Ccolgroup\u201D fragment.");
                                 break endtagloop;
-                            case NOSCRIPT:
-                                if (scriptingEnabled) {
-                                    err("Stray end tag \u201Cnoscript\u201D.");
-                                    break endtagloop;
-                                } else {
-                                    // fall through
-                                }
-                            default:
-                                if (isCurrent(name)) {
-                                    pop();
-                                    break endtagloop;
-                                }
-
-                                eltPos = currentPtr;
-                                for (;;) {
-                                    StackNode<T> node = stack[eltPos];
-                                    if (node.name == name) {
-                                        generateImpliedEndTags();
-                                        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.");
-                                        break endtagloop;
-                                    }
-                                    eltPos--;
-                                }
-                        }
-                    case IN_COLUMN_GROUP:
-                        switch (group) {
-                            case COLGROUP:
-                                if (currentPtr == 0) {
-                                    assert fragment;
-                                    err("Garbage in \u201Ccolgroup\u201D fragment.");
-                                    break endtagloop;
-                                }
-                                pop();
-                                mode = IN_TABLE;
-                                break endtagloop;
-                            case COL:
-                                err("Stray end tag \u201Ccol\u201D.");
-                                break endtagloop;
-                            default:
-                                if (currentPtr == 0) {
-                                    assert fragment;
-                                    err("Garbage in \u201Ccolgroup\u201D fragment.");
-                                    break endtagloop;
-                                }
-                                pop();
-                                mode = IN_TABLE;
-                                continue;
-                        }
-                    case IN_SELECT_IN_TABLE:
-                        switch (group) {
-                            case CAPTION:
-                            case TABLE:
-                            case TBODY_OR_THEAD_OR_TFOOT:
-                            case TR:
-                            case TD_OR_TH:
-                                err("\u201C"
-                                        + name
-                                        + "\u201D end tag with \u201Cselect\u201D open.");
-                                if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) {
-                                    eltPos = findLastInTableScope("select");
-                                    if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
-                                        assert fragment;
-                                        break endtagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
-                                    }
-                                    while (currentPtr >= eltPos) {
-                                        pop();
-                                    }
-                                    resetTheInsertionMode();
-                                    continue;
-                                } else {
-                                    break endtagloop;
-                                }
-                            default:
-                                // fall through to IN_SELECT
-                        }
-                    case IN_SELECT:
-                        switch (group) {
-                            case OPTION:
-                                if (isCurrent("option")) {
-                                    pop();
-                                    break endtagloop;
-                                } else {
-                                    err("Stray end tag \u201Coption\u201D");
-                                    break endtagloop;
-                                }
-                            case OPTGROUP:
-                                if (isCurrent("option")
-                                        && "optgroup" == stack[currentPtr - 1].name) {
-                                    pop();
-                                }
-                                if (isCurrent("optgroup")) {
-                                    pop();
-                                } else {
-                                    err("Stray end tag \u201Coptgroup\u201D");
-                                }
-                                break endtagloop;
-                            case SELECT:
+                            }
+                            pop();
+                            mode = IN_TABLE;
+                            continue;
+                    }
+                case IN_SELECT_IN_TABLE:
+                    switch (group) {
+                        case CAPTION:
+                        case TABLE:
+                        case TBODY_OR_THEAD_OR_TFOOT:
+                        case TR:
+                        case TD_OR_TH:
+                            err("\u201C"
+                                    + name
+                                    + "\u201D end tag with \u201Cselect\u201D open.");
+                            if (findLastInTableScope(name) != TreeBuilder.NOT_FOUND_ON_STACK) {
                                 eltPos = findLastInTableScope("select");
                                 if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                     assert fragment;
-                                    err("Stray end tag \u201Cselect\u201D");
-                                    break endtagloop;
+                                    break endtagloop; // http://www.w3.org/Bugs/Public/show_bug.cgi?id=8375
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                                 resetTheInsertionMode();
+                                continue;
+                            } else {
                                 break endtagloop;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D");
+                            }
+                        default:
+                            // fall through to IN_SELECT
+                    }
+                case IN_SELECT:
+                    switch (group) {
+                        case OPTION:
+                            if (isCurrent("option")) {
+                                pop();
+                                break endtagloop;
+                            } else {
+                                err("Stray end tag \u201Coption\u201D");
                                 break endtagloop;
-                        }
-                    case AFTER_BODY:
-                        switch (group) {
-                            case HTML:
-                                if (fragment) {
-                                    err("Stray end tag \u201Chtml\u201D");
-                                    break endtagloop;
-                                } else {
-                                    mode = AFTER_AFTER_BODY;
-                                    break endtagloop;
-                                }
-                            default:
-                                err("Saw an end tag after \u201Cbody\u201D had been closed.");
-                                mode = framesetOk ? FRAMESET_OK : IN_BODY;
-                                continue;
-                        }
-                    case IN_FRAMESET:
-                        switch (group) {
-                            case FRAMESET:
-                                if (currentPtr == 0) {
-                                    assert fragment;
-                                    err("Stray end tag \u201Cframeset\u201D");
-                                    break endtagloop;
-                                }
+                            }
+                        case OPTGROUP:
+                            if (isCurrent("option")
+                                    && "optgroup" == stack[currentPtr - 1].name) {
+                                pop();
+                            }
+                            if (isCurrent("optgroup")) {
+                                pop();
+                            } else {
+                                err("Stray end tag \u201Coptgroup\u201D");
+                            }
+                            break endtagloop;
+                        case SELECT:
+                            eltPos = findLastInTableScope("select");
+                            if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
+                                assert fragment;
+                                err("Stray end tag \u201Cselect\u201D");
+                                break endtagloop;
+                            }
+                            while (currentPtr >= eltPos) {
                                 pop();
-                                if ((!fragment) && !isCurrent("frameset")) {
-                                    mode = AFTER_FRAMESET;
-                                }
-                                break endtagloop;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D");
+                            }
+                            resetTheInsertionMode();
+                            break endtagloop;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D");
+                            break endtagloop;
+                    }
+                case AFTER_BODY:
+                    switch (group) {
+                        case HTML:
+                            if (fragment) {
+                                err("Stray end tag \u201Chtml\u201D");
                                 break endtagloop;
-                        }
-                    case AFTER_FRAMESET:
-                        switch (group) {
-                            case HTML:
-                                mode = AFTER_AFTER_FRAMESET;
+                            } else {
+                                mode = AFTER_AFTER_BODY;
                                 break endtagloop;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D");
+                            }
+                        default:
+                            err("Saw an end tag after \u201Cbody\u201D had been closed.");
+                            mode = framesetOk ? FRAMESET_OK : IN_BODY;
+                            continue;
+                    }
+                case IN_FRAMESET:
+                    switch (group) {
+                        case FRAMESET:
+                            if (currentPtr == 0) {
+                                assert fragment;
+                                err("Stray end tag \u201Cframeset\u201D");
                                 break endtagloop;
-                        }
-                    case INITIAL:
-                        /*
-                         * Parse error.
-                         */
-                        // [NOCPP[
-                        switch (doctypeExpectation) {
-                            case AUTO:
-                                err("End tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
-                                break;
-                            case HTML:
-                                err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
-                                break;
-                            case HTML401_STRICT:
-                                err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
-                                break;
-                            case HTML401_TRANSITIONAL:
-                                err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
-                                break;
-                            case NO_DOCTYPE_ERRORS:
-                        }
-                        // ]NOCPP]
-                        /*
-                         * 
-                         * 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 HEAD:
-                            case BR:
-                            case HTML:
-                            case BODY:
-                                /*
-                                 * 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;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                        }
-                    case BEFORE_HEAD:
-                        switch (group) {
-                            case HEAD:
-                            case BR:
-                            case HTML:
-                            case BODY:
-                                appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
-                                mode = IN_HEAD;
-                                continue;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                        }
-                    case IN_HEAD:
-                        switch (group) {
-                            case HEAD:
-                                pop();
-                                mode = AFTER_HEAD;
-                                break endtagloop;
-                            case BR:
-                            case HTML:
-                            case BODY:
-                                pop();
-                                mode = AFTER_HEAD;
-                                continue;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                        }
-                    case IN_HEAD_NOSCRIPT:
-                        switch (group) {
-                            case NOSCRIPT:
-                                pop();
-                                mode = IN_HEAD;
-                                break endtagloop;
-                            case BR:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                pop();
-                                mode = IN_HEAD;
-                                continue;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                        }
-                    case AFTER_HEAD:
-                        switch (group) {
-                            case HTML:
-                            case BODY:
-                            case BR:
-                                appendToCurrentNodeAndPushBodyElement();
-                                mode = FRAMESET_OK;
-                                continue;
-                            default:
-                                err("Stray end tag \u201C" + name + "\u201D.");
-                                break endtagloop;
-                        }
-                    case AFTER_AFTER_BODY:
-                        err("Stray \u201C" + name + "\u201D end tag.");
-                        mode = framesetOk ? FRAMESET_OK : IN_BODY;
-                        continue;
-                    case AFTER_AFTER_FRAMESET:
-                        err("Stray \u201C" + name + "\u201D end tag.");
-                        mode = IN_FRAMESET;
-                        continue;
-                    case TEXT:
-                        // XXX need to manage insertion point here
-                        pop();
-                        if (originalMode == AFTER_HEAD) {
-                            silentPop();
-                        }
-                        mode = originalMode;
-                        break endtagloop;
-                }
-            } // endtagloop
-            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.
-                 */
-                inForeign = false;
+                            }
+                            pop();
+                            if ((!fragment) && !isCurrent("frameset")) {
+                                mode = AFTER_FRAMESET;
+                            }
+                            break endtagloop;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D");
+                            break endtagloop;
+                    }
+                case AFTER_FRAMESET:
+                    switch (group) {
+                        case HTML:
+                            mode = AFTER_AFTER_FRAMESET;
+                            break endtagloop;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D");
+                            break endtagloop;
+                    }
+                case INITIAL:
+                    /*
+                     * Parse error.
+                     */
+                    // [NOCPP[
+                    switch (doctypeExpectation) {
+                        case AUTO:
+                            err("End tag seen without seeing a doctype first. Expected e.g. \u201C<!DOCTYPE html>\u201D.");
+                            break;
+                        case HTML:
+                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
+                            break;
+                        case HTML401_STRICT:
+                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\u201D.");
+                            break;
+                        case HTML401_TRANSITIONAL:
+                            err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\u201D.");
+                            break;
+                        case NO_DOCTYPE_ERRORS:
+                    }
+                    // ]NOCPP]
+                    /*
+                     * 
+                     * 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 HEAD:
+                        case BR:
+                        case HTML:
+                        case BODY:
+                            /*
+                             * 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;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                    }
+                case BEFORE_HEAD:
+                    switch (group) {
+                        case HEAD:
+                        case BR:
+                        case HTML:
+                        case BODY:
+                            appendToCurrentNodeAndPushHeadElement(HtmlAttributes.EMPTY_ATTRIBUTES);
+                            mode = IN_HEAD;
+                            continue;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                    }
+                case IN_HEAD:
+                    switch (group) {
+                        case HEAD:
+                            pop();
+                            mode = AFTER_HEAD;
+                            break endtagloop;
+                        case BR:
+                        case HTML:
+                        case BODY:
+                            pop();
+                            mode = AFTER_HEAD;
+                            continue;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                    }
+                case IN_HEAD_NOSCRIPT:
+                    switch (group) {
+                        case NOSCRIPT:
+                            pop();
+                            mode = IN_HEAD;
+                            break endtagloop;
+                        case BR:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            pop();
+                            mode = IN_HEAD;
+                            continue;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                    }
+                case AFTER_HEAD:
+                    switch (group) {
+                        case HTML:
+                        case BODY:
+                        case BR:
+                            appendToCurrentNodeAndPushBodyElement();
+                            mode = FRAMESET_OK;
+                            continue;
+                        default:
+                            err("Stray end tag \u201C" + name + "\u201D.");
+                            break endtagloop;
+                    }
+                case AFTER_AFTER_BODY:
+                    err("Stray \u201C" + name + "\u201D end tag.");
+                    mode = framesetOk ? FRAMESET_OK : IN_BODY;
+                    continue;
+                case AFTER_AFTER_FRAMESET:
+                    err("Stray \u201C" + name + "\u201D end tag.");
+                    mode = IN_FRAMESET;
+                    continue;
+                case TEXT:
+                    // XXX need to manage insertion point here
+                    pop();
+                    if (originalMode == AFTER_HEAD) {
+                        silentPop();
+                    }
+                    mode = originalMode;
+                    break endtagloop;
             }
-            if (eltPosForeign != -1) {
-                continue inforeignloop;
-            }
-            return;
-        } // inforeignloop
+        } // endtagloop
+        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.
+             */
+            inForeign = false;
+        }
     }
 
     private int findLastInTableScopeOrRootTbodyTheadTfoot() {
         for (int i = currentPtr; i > 0; i--) {
             if (stack[i].group == TreeBuilder.TBODY_OR_THEAD_OR_TFOOT) {
                 return i;
             }
         }
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -2010,711 +2010,696 @@ nsHtml5TreeBuilder::checkMetaCharset(nsH
   }
 }
 
 void 
 nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
 {
   needToDropLF = PR_FALSE;
   PRInt32 eltPos;
-  PRInt32 eltPosForeign;
   PRInt32 group = elementName->group;
   nsIAtom* name = elementName->name;
-
-  if (inForeign && stack[currentPtr]->ns != kNameSpaceID_XHTML) {
-    eltPosForeign = currentPtr;
-  } else {
-    eltPosForeign = -1;
-  }
-  inforeignloop: for (; ; ) {
-    if (eltPosForeign != -1) {
-      if (currentPtr >= eltPosForeign && stack[eltPosForeign]->name == name) {
-        while (currentPtr >= eltPosForeign) {
-          pop();
+  for (; ; ) {
+
+    if (inForeign && stack[currentPtr]->ns != kNameSpaceID_XHTML) {
+
+      eltPos = currentPtr;
+      for (; ; ) {
+        if (stack[eltPos]->name == name) {
+          while (currentPtr >= eltPos) {
+            pop();
+          }
+          return;
         }
-        return;
-      }
-      if (--eltPosForeign > currentPtr) {
-        NS_HTML5_CONTINUE(inforeignloop);
-      }
-      if (eltPosForeign == -1) {
-        return;
-      }
-      if (stack[eltPosForeign]->ns != kNameSpaceID_XHTML) {
-        NS_HTML5_CONTINUE(inforeignloop);
+        if (stack[--eltPos]->ns == kNameSpaceID_XHTML) {
+          break;
+        }
       }
     }
-    for (; ; ) {
-      switch(mode) {
-        case NS_HTML5TREE_BUILDER_IN_ROW: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_TR: {
-              eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
-              if (!eltPos) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              clearStackBackTo(eltPos);
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+    switch(mode) {
+      case NS_HTML5TREE_BUILDER_IN_ROW: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TR: {
+            eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+            if (!eltPos) {
+
+
+              NS_HTML5_BREAK(endtagloop);
+            }
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_TABLE: {
+            eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+            if (!eltPos) {
+
+
+              NS_HTML5_BREAK(endtagloop);
+            }
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+            if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
+              NS_HTML5_BREAK(endtagloop);
+            }
+            eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
+            if (!eltPos) {
+
+
               NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_TABLE: {
-              eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
-              if (!eltPos) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              clearStackBackTo(eltPos);
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
-              continue;
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
+            eltPos = findLastOrRoot(name);
+            if (!eltPos) {
+
+              NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
-              if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
-              if (!eltPos) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              clearStackBackTo(eltPos);
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
-              continue;
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_TABLE: {
+            eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
+            if (!eltPos) {
+
+
+              NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_CAPTION:
-            case NS_HTML5TREE_BUILDER_COL:
-            case NS_HTML5TREE_BUILDER_COLGROUP:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+            clearStackBackTo(eltPos);
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH:
+          case NS_HTML5TREE_BUILDER_TR: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_TABLE: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TABLE: {
+            eltPos = findLast(nsHtml5Atoms::table);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
 
               NS_HTML5_BREAK(endtagloop);
             }
-            default:
-              ; // fall through
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            resetTheInsertionMode();
+            NS_HTML5_BREAK(endtagloop);
           }
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH:
+          case NS_HTML5TREE_BUILDER_TR: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default:
+            ; // fall through
         }
-        case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
-              eltPos = findLastOrRoot(name);
-              if (!eltPos) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              clearStackBackTo(eltPos);
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+      }
+      case NS_HTML5TREE_BUILDER_IN_CAPTION: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_CAPTION: {
+            eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_TABLE: {
-              eltPos = findLastInTableScopeOrRootTbodyTheadTfoot();
-              if (!eltPos) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              clearStackBackTo(eltPos);
+            generateImpliedEndTags();
+
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_TABLE: {
+
+            eltPos = findLastInTableScope(nsHtml5Atoms::caption);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              NS_HTML5_BREAK(endtagloop);
+            }
+            generateImpliedEndTags();
+
+            while (currentPtr >= eltPos) {
               pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
-              continue;
             }
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_CAPTION:
-            case NS_HTML5TREE_BUILDER_COL:
-            case NS_HTML5TREE_BUILDER_COLGROUP:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_TD_OR_TH:
-            case NS_HTML5TREE_BUILDER_TR: {
+            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH:
+          case NS_HTML5TREE_BUILDER_TR: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default:
+            ; // fall through
+        }
+      }
+      case NS_HTML5TREE_BUILDER_IN_CELL: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+            eltPos = findLastInTableScope(name);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
 
               NS_HTML5_BREAK(endtagloop);
             }
-            default:
-              ; // fall through
+            generateImpliedEndTags();
+
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+            mode = NS_HTML5TREE_BUILDER_IN_ROW;
+            NS_HTML5_BREAK(endtagloop);
           }
-        }
-        case NS_HTML5TREE_BUILDER_IN_TABLE: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_TABLE: {
-              eltPos = findLast(nsHtml5Atoms::table);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              while (currentPtr >= eltPos) {
-                pop();
-              }
-              resetTheInsertionMode();
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_CAPTION:
-            case NS_HTML5TREE_BUILDER_COL:
-            case NS_HTML5TREE_BUILDER_COLGROUP:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
-            case NS_HTML5TREE_BUILDER_TD_OR_TH:
-            case NS_HTML5TREE_BUILDER_TR: {
+          case NS_HTML5TREE_BUILDER_TABLE:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TR: {
+            if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
 
               NS_HTML5_BREAK(endtagloop);
             }
-            default:
-              ; // fall through
+            closeTheCell(findLastInTableScopeTdTh());
+            continue;
           }
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_COL:
+          case NS_HTML5TREE_BUILDER_COLGROUP:
+          case NS_HTML5TREE_BUILDER_HTML: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default:
+            ; // fall through
         }
-        case NS_HTML5TREE_BUILDER_IN_CAPTION: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_CAPTION: {
-              eltPos = findLastInTableScope(nsHtml5Atoms::caption);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                NS_HTML5_BREAK(endtagloop);
-              }
-              generateImpliedEndTags();
-
-              while (currentPtr >= eltPos) {
-                pop();
-              }
-              clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+      }
+      case NS_HTML5TREE_BUILDER_FRAMESET_OK:
+      case NS_HTML5TREE_BUILDER_IN_BODY: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_BODY: {
+            if (!isSecondOnStackBody()) {
+
+
               NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_TABLE: {
-
-              eltPos = findLastInTableScope(nsHtml5Atoms::caption);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                NS_HTML5_BREAK(endtagloop);
-              }
+
+
+            mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_HTML: {
+            if (!isSecondOnStackBody()) {
+
+
+              NS_HTML5_BREAK(endtagloop);
+            }
+
+            mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
+            continue;
+          }
+          case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
+          case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
+          case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
+          case NS_HTML5TREE_BUILDER_FIELDSET:
+          case NS_HTML5TREE_BUILDER_BUTTON:
+          case NS_HTML5TREE_BUILDER_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 != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               generateImpliedEndTags();
 
               while (currentPtr >= eltPos) {
                 pop();
               }
-              clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
-              continue;
             }
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_COL:
-            case NS_HTML5TREE_BUILDER_COLGROUP:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
-            case NS_HTML5TREE_BUILDER_TD_OR_TH:
-            case NS_HTML5TREE_BUILDER_TR: {
-
-              NS_HTML5_BREAK(endtagloop);
-            }
-            default:
-              ; // fall through
+            NS_HTML5_BREAK(endtagloop);
           }
-        }
-        case NS_HTML5TREE_BUILDER_IN_CELL: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_TD_OR_TH: {
-              eltPos = findLastInTableScope(name);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              generateImpliedEndTags();
-
-              while (currentPtr >= eltPos) {
-                pop();
-              }
-              clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-              mode = NS_HTML5TREE_BUILDER_IN_ROW;
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_TABLE:
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
-            case NS_HTML5TREE_BUILDER_TR: {
-              if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              closeTheCell(findLastInTableScopeTdTh());
-              continue;
-            }
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_CAPTION:
-            case NS_HTML5TREE_BUILDER_COL:
-            case NS_HTML5TREE_BUILDER_COLGROUP:
-            case NS_HTML5TREE_BUILDER_HTML: {
+          case NS_HTML5TREE_BUILDER_FORM: {
+            if (!formPointer) {
 
               NS_HTML5_BREAK(endtagloop);
             }
-            default:
-              ; // fall through
-          }
-        }
-        case NS_HTML5TREE_BUILDER_FRAMESET_OK:
-        case NS_HTML5TREE_BUILDER_IN_BODY: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_BODY: {
-              if (!isSecondOnStackBody()) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-
-
-              mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_HTML: {
-              if (!isSecondOnStackBody()) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-
-              mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
-              continue;
-            }
-            case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
-            case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
-            case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
-            case NS_HTML5TREE_BUILDER_FIELDSET:
-            case NS_HTML5TREE_BUILDER_BUTTON:
-            case NS_HTML5TREE_BUILDER_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 != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                generateImpliedEndTags();
-
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_FORM: {
-              if (!formPointer) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              ;
-              formPointer = nsnull;
-              eltPos = findLastInScope(name);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              generateImpliedEndTags();
-
-              removeFromStack(eltPos);
+            ;
+            formPointer = nsnull;
+            eltPos = findLastInScope(name);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
               NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_P: {
-              eltPos = findLastInScope(nsHtml5Atoms::p);
-              if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                if (inForeign) {
-
-                  while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
-                    pop();
-                  }
-                  inForeign = PR_FALSE;
-                }
-                appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
-                NS_HTML5_BREAK(endtagloop);
-              }
-              generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
-
-
-              while (currentPtr >= eltPos) {
-                pop();
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_LI: {
-              eltPos = findLastInListScope(name);
-              if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                generateImpliedEndTagsExceptFor(name);
-
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_DD_OR_DT: {
-              eltPos = findLastInScope(name);
-              if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                generateImpliedEndTagsExceptFor(name);
-
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
-              eltPos = findLastInScopeHn();
-              if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                generateImpliedEndTags();
-
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_A:
-            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_FONT:
-            case NS_HTML5TREE_BUILDER_NOBR: {
-              adoptionAgencyEndTag(name);
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_OBJECT:
-            case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
-              eltPos = findLastInScope(name);
-              if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                generateImpliedEndTags();
-
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-                clearTheListOfActiveFormattingElementsUpToTheLastMarker();
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_BR: {
+            generateImpliedEndTags();
+
+            removeFromStack(eltPos);
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_P: {
+            eltPos = findLastInScope(nsHtml5Atoms::p);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
 
               if (inForeign) {
 
                 while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
                   pop();
                 }
                 inForeign = PR_FALSE;
               }
-              reconstructTheActiveFormattingElements();
               appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
               NS_HTML5_BREAK(endtagloop);
             }
-            case NS_HTML5TREE_BUILDER_AREA_OR_SPACER_OR_WBR:
-            case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE:
-            case NS_HTML5TREE_BUILDER_EMBED_OR_IMG:
-            case NS_HTML5TREE_BUILDER_IMAGE:
-            case NS_HTML5TREE_BUILDER_INPUT:
-            case NS_HTML5TREE_BUILDER_KEYGEN:
-            case NS_HTML5TREE_BUILDER_HR:
-            case NS_HTML5TREE_BUILDER_ISINDEX:
-            case NS_HTML5TREE_BUILDER_IFRAME:
-            case NS_HTML5TREE_BUILDER_NOEMBED:
-            case NS_HTML5TREE_BUILDER_NOFRAMES:
-            case NS_HTML5TREE_BUILDER_SELECT:
-            case NS_HTML5TREE_BUILDER_TABLE:
-            case NS_HTML5TREE_BUILDER_TEXTAREA: {
-
-              NS_HTML5_BREAK(endtagloop);
+            generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
+
+
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_LI: {
+            eltPos = findLastInListScope(name);
+            if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              generateImpliedEndTagsExceptFor(name);
+
+              while (currentPtr >= eltPos) {
+                pop();
+              }
             }
-            case NS_HTML5TREE_BUILDER_NOSCRIPT: {
-              if (scriptingEnabled) {
-
-                NS_HTML5_BREAK(endtagloop);
-              } else {
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_DD_OR_DT: {
+            eltPos = findLastInScope(name);
+            if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              generateImpliedEndTagsExceptFor(name);
+
+              while (currentPtr >= eltPos) {
+                pop();
+              }
+            }
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
+            eltPos = findLastInScopeHn();
+            if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              generateImpliedEndTags();
+
+              while (currentPtr >= eltPos) {
+                pop();
               }
             }
-            default: {
-              if (isCurrent(name)) {
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_A:
+          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_FONT:
+          case NS_HTML5TREE_BUILDER_NOBR: {
+            adoptionAgencyEndTag(name);
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_OBJECT:
+          case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
+            eltPos = findLastInScope(name);
+            if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+              generateImpliedEndTags();
+
+              while (currentPtr >= eltPos) {
                 pop();
-                NS_HTML5_BREAK(endtagloop);
+              }
+              clearTheListOfActiveFormattingElementsUpToTheLastMarker();
+            }
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_BR: {
+
+            if (inForeign) {
+
+              while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
+                pop();
               }
-              eltPos = currentPtr;
-              for (; ; ) {
-                nsHtml5StackNode* node = stack[eltPos];
-                if (node->name == name) {
-                  generateImpliedEndTags();
-
-                  while (currentPtr >= eltPos) {
-                    pop();
-                  }
-                  NS_HTML5_BREAK(endtagloop);
-                } else if (node->scoping || node->special) {
-
-                  NS_HTML5_BREAK(endtagloop);
-                }
-                eltPos--;
-              }
+              inForeign = PR_FALSE;
+            }
+            reconstructTheActiveFormattingElements();
+            appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_AREA_OR_SPACER_OR_WBR:
+          case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE:
+          case NS_HTML5TREE_BUILDER_EMBED_OR_IMG:
+          case NS_HTML5TREE_BUILDER_IMAGE:
+          case NS_HTML5TREE_BUILDER_INPUT:
+          case NS_HTML5TREE_BUILDER_KEYGEN:
+          case NS_HTML5TREE_BUILDER_HR:
+          case NS_HTML5TREE_BUILDER_ISINDEX:
+          case NS_HTML5TREE_BUILDER_IFRAME:
+          case NS_HTML5TREE_BUILDER_NOEMBED:
+          case NS_HTML5TREE_BUILDER_NOFRAMES:
+          case NS_HTML5TREE_BUILDER_SELECT:
+          case NS_HTML5TREE_BUILDER_TABLE:
+          case NS_HTML5TREE_BUILDER_TEXTAREA: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+            if (scriptingEnabled) {
+
+              NS_HTML5_BREAK(endtagloop);
+            } else {
             }
           }
-        }
-        case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_COLGROUP: {
-              if (!currentPtr) {
-
+          default: {
+            if (isCurrent(name)) {
+              pop();
+              NS_HTML5_BREAK(endtagloop);
+            }
+            eltPos = currentPtr;
+            for (; ; ) {
+              nsHtml5StackNode* node = stack[eltPos];
+              if (node->name == name) {
+                generateImpliedEndTags();
+
+                while (currentPtr >= eltPos) {
+                  pop();
+                }
+                NS_HTML5_BREAK(endtagloop);
+              } else if (node->scoping || node->special) {
 
                 NS_HTML5_BREAK(endtagloop);
               }
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_COL: {
-
-              NS_HTML5_BREAK(endtagloop);
-            }
-            default: {
-              if (!currentPtr) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_TABLE;
-              continue;
+              eltPos--;
             }
           }
         }
-        case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_CAPTION:
-            case NS_HTML5TREE_BUILDER_TABLE:
-            case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
-            case NS_HTML5TREE_BUILDER_TR:
-            case NS_HTML5TREE_BUILDER_TD_OR_TH: {
-
-              if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-                eltPos = findLastInTableScope(nsHtml5Atoms::select);
-                if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
-
-                  NS_HTML5_BREAK(endtagloop);
-                }
-                while (currentPtr >= eltPos) {
-                  pop();
-                }
-                resetTheInsertionMode();
-                continue;
-              } else {
-                NS_HTML5_BREAK(endtagloop);
-              }
+      }
+      case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_COLGROUP: {
+            if (!currentPtr) {
+
+
+              NS_HTML5_BREAK(endtagloop);
             }
-            default:
-              ; // fall through
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_COL: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default: {
+            if (!currentPtr) {
+
+
+              NS_HTML5_BREAK(endtagloop);
+            }
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_TABLE;
+            continue;
           }
         }
-        case NS_HTML5TREE_BUILDER_IN_SELECT: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_OPTION: {
-              if (isCurrent(nsHtml5Atoms::option)) {
-                pop();
-                NS_HTML5_BREAK(endtagloop);
-              } else {
-
-                NS_HTML5_BREAK(endtagloop);
-              }
-            }
-            case NS_HTML5TREE_BUILDER_OPTGROUP: {
-              if (isCurrent(nsHtml5Atoms::option) && nsHtml5Atoms::optgroup == stack[currentPtr - 1]->name) {
-                pop();
-              }
-              if (isCurrent(nsHtml5Atoms::optgroup)) {
-                pop();
-              }
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_SELECT: {
+      }
+      case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_CAPTION:
+          case NS_HTML5TREE_BUILDER_TABLE:
+          case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
+          case NS_HTML5TREE_BUILDER_TR:
+          case NS_HTML5TREE_BUILDER_TD_OR_TH: {
+
+            if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
               eltPos = findLastInTableScope(nsHtml5Atoms::select);
               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
 
-
                 NS_HTML5_BREAK(endtagloop);
               }
               while (currentPtr >= eltPos) {
                 pop();
               }
               resetTheInsertionMode();
-              NS_HTML5_BREAK(endtagloop);
-            }
-            default: {
-
+              continue;
+            } else {
               NS_HTML5_BREAK(endtagloop);
             }
           }
+          default:
+            ; // fall through
         }
-        case NS_HTML5TREE_BUILDER_AFTER_BODY: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HTML: {
-              if (fragment) {
-
-                NS_HTML5_BREAK(endtagloop);
-              } else {
-                mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY;
-                NS_HTML5_BREAK(endtagloop);
-              }
-            }
-            default: {
-
-              mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
-              continue;
-            }
-          }
-        }
-        case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_FRAMESET: {
-              if (!currentPtr) {
-
-
-                NS_HTML5_BREAK(endtagloop);
-              }
+      }
+      case NS_HTML5TREE_BUILDER_IN_SELECT: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_OPTION: {
+            if (isCurrent(nsHtml5Atoms::option)) {
               pop();
-              if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) {
-                mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET;
-              }
               NS_HTML5_BREAK(endtagloop);
-            }
-            default: {
-
-              NS_HTML5_BREAK(endtagloop);
-            }
-          }
-        }
-        case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HTML: {
-              mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET;
-              NS_HTML5_BREAK(endtagloop);
-            }
-            default: {
-
-              NS_HTML5_BREAK(endtagloop);
-            }
-          }
-        }
-        case NS_HTML5TREE_BUILDER_INITIAL: {
-          documentModeInternal(QUIRKS_MODE, nsnull, nsnull, PR_FALSE);
-          mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
-          continue;
-        }
-        case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HEAD:
-            case NS_HTML5TREE_BUILDER_BR:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_BODY: {
-              appendHtmlElementToDocumentAndPush();
-              mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
-              continue;
-            }
-            default: {
+            } else {
 
               NS_HTML5_BREAK(endtagloop);
             }
           }
-        }
-        case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HEAD:
-            case NS_HTML5TREE_BUILDER_BR:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_BODY: {
-              appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
-              mode = NS_HTML5TREE_BUILDER_IN_HEAD;
-              continue;
+          case NS_HTML5TREE_BUILDER_OPTGROUP: {
+            if (isCurrent(nsHtml5Atoms::option) && nsHtml5Atoms::optgroup == stack[currentPtr - 1]->name) {
+              pop();
+            }
+            if (isCurrent(nsHtml5Atoms::optgroup)) {
+              pop();
             }
-            default: {
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_SELECT: {
+            eltPos = findLastInTableScope(nsHtml5Atoms::select);
+            if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
+
 
               NS_HTML5_BREAK(endtagloop);
             }
+            while (currentPtr >= eltPos) {
+              pop();
+            }
+            resetTheInsertionMode();
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
           }
         }
-        case NS_HTML5TREE_BUILDER_IN_HEAD: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HEAD: {
-              pop();
-              mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+      }
+      case NS_HTML5TREE_BUILDER_AFTER_BODY: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HTML: {
+            if (fragment) {
+
               NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_BR:
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_BODY: {
-              pop();
-              mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
-              continue;
-            }
-            default: {
-
+            } else {
+              mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY;
               NS_HTML5_BREAK(endtagloop);
             }
           }
-        }
-        case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_NOSCRIPT: {
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_HEAD;
-              NS_HTML5_BREAK(endtagloop);
-            }
-            case NS_HTML5TREE_BUILDER_BR: {
-
-              pop();
-              mode = NS_HTML5TREE_BUILDER_IN_HEAD;
-              continue;
-            }
-            default: {
-
-              NS_HTML5_BREAK(endtagloop);
-            }
+          default: {
+
+            mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+            continue;
           }
         }
-        case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
-          switch(group) {
-            case NS_HTML5TREE_BUILDER_HTML:
-            case NS_HTML5TREE_BUILDER_BODY:
-            case NS_HTML5TREE_BUILDER_BR: {
-              appendToCurrentNodeAndPushBodyElement();
-              mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
-              continue;
-            }
-            default: {
+      }
+      case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_FRAMESET: {
+            if (!currentPtr) {
+
 
               NS_HTML5_BREAK(endtagloop);
             }
+            pop();
+            if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) {
+              mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET;
+            }
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+        }
+      }
+      case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HTML: {
+            mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+        }
+      }
+      case NS_HTML5TREE_BUILDER_INITIAL: {
+        documentModeInternal(QUIRKS_MODE, nsnull, nsnull, PR_FALSE);
+        mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
+        continue;
+      }
+      case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HEAD:
+          case NS_HTML5TREE_BUILDER_BR:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_BODY: {
+            appendHtmlElementToDocumentAndPush();
+            mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
+            continue;
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+        }
+      }
+      case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HEAD:
+          case NS_HTML5TREE_BUILDER_BR:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_BODY: {
+            appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
+            mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+            continue;
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
           }
         }
-        case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
-
-          mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
-          continue;
+      }
+      case NS_HTML5TREE_BUILDER_IN_HEAD: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HEAD: {
+            pop();
+            mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+            NS_HTML5_BREAK(endtagloop);
+          }
+          case NS_HTML5TREE_BUILDER_BR:
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_BODY: {
+            pop();
+            mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
+            continue;
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
         }
-        case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
-
-          mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
-          continue;
-        }
-        case NS_HTML5TREE_BUILDER_TEXT: {
-          pop();
-          if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
-            silentPop();
+      }
+      case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_NOSCRIPT: {
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+            NS_HTML5_BREAK(endtagloop);
           }
-          mode = originalMode;
-          NS_HTML5_BREAK(endtagloop);
+          case NS_HTML5TREE_BUILDER_BR: {
+
+            pop();
+            mode = NS_HTML5TREE_BUILDER_IN_HEAD;
+            continue;
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
         }
       }
-    }
-    endtagloop_end: ;
-    if (inForeign && !hasForeignInScope()) {
-      inForeign = PR_FALSE;
+      case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
+        switch(group) {
+          case NS_HTML5TREE_BUILDER_HTML:
+          case NS_HTML5TREE_BUILDER_BODY:
+          case NS_HTML5TREE_BUILDER_BR: {
+            appendToCurrentNodeAndPushBodyElement();
+            mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
+            continue;
+          }
+          default: {
+
+            NS_HTML5_BREAK(endtagloop);
+          }
+        }
+      }
+      case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
+
+        mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
+        continue;
+      }
+      case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
+
+        mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
+        continue;
+      }
+      case NS_HTML5TREE_BUILDER_TEXT: {
+        pop();
+        if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
+          silentPop();
+        }
+        mode = originalMode;
+        NS_HTML5_BREAK(endtagloop);
+      }
     }
-    if (eltPosForeign != -1) {
-      NS_HTML5_CONTINUE(inforeignloop);
-    }
-    return;
   }
-
+  endtagloop_end: ;
+  if (inForeign && !hasForeignInScope()) {
+    inForeign = PR_FALSE;
+  }
 }
 
 PRInt32 
 nsHtml5TreeBuilder::findLastInTableScopeOrRootTbodyTheadTfoot()
 {
   for (PRInt32 i = currentPtr; i > 0; i--) {
     if (stack[i]->group == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT) {
       return i;
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/574884-1.html
@@ -0,0 +1,1 @@
+<svg></html>
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/574884-2.html
@@ -0,0 +1,1 @@
+<math></html>
--- a/parser/htmlparser/tests/crashtests/crashtests.list
+++ b/parser/htmlparser/tests/crashtests/crashtests.list
@@ -37,8 +37,10 @@ skip load 460706-1.xhtml # Bug 479499
 load 468538-1.xhtml
 load 515278-1.html
 load 515533-1.html
 load 515816-1.html
 load 525229-1.html
 load 522326-1.html
 load 536097-1.html
 load 563514-1.html
+load 574884-1.html
+load 574884-2.html
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug566280-1-ref.html~
@@ -0,0 +1,2 @@
+<body>&#xFFFD;hello world
+
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug577418-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<style>
+html {
+  background-color: lime;
+}
+</style>
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/reftest/bug577418-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;margin:0;border:0;overflow:hidden">
+<body style="width:100%;height:100%;margin:0;border:0;overflow:hidden">
+<svg>
+ <rect height="100%" width="100%" fill="red"/>
+   <foreignObject>
+     <html>
+       <body>
+       </body>
+     </html>
+    </foreignObject>
+  <rect height="100%" width="100%" fill="lime"/>
+</svg>
+</body>
+</html>
--- a/parser/htmlparser/tests/reftest/reftest.list
+++ b/parser/htmlparser/tests/reftest/reftest.list
@@ -1,3 +1,4 @@
 == bug566280-1.html bug566280-1-ref.html
+== bug577418-1.html bug577418-1-ref.html
 == bug582788-1.html bug582788-1-ref.html
 == bug582940-1.html bug582940-1-ref.html