public override BaseInsertionModeState ProcessToken(HtmlTokenizer tokenizer, ITokenQueue queue, BaseToken token, IDocument doc)
        {
            if (IsWhitespace(token))
            {
                return this;
            }

            CommentToken commentToken = token as CommentToken;
            if (commentToken != null)
            {
                IComment commentNode = new Comment(doc, commentToken.Comment);
                doc.appendChild(commentNode);
                return this;
            }

            DocTypeToken docTypeToken = token as DocTypeToken;
            if (docTypeToken != null)
            {
                if (docTypeToken.Name != "html" ||
                    docTypeToken.PublicIdentifier != null ||
                    (docTypeToken.SystemIdentifier != null && docTypeToken.SystemIdentifier != "about:legacy-compat"))
                {
                    if (docTypeToken.Name == "html")
                    {
                        string pair = string.Concat("<", docTypeToken.PublicIdentifier, ">-<", docTypeToken.SystemIdentifier, ">");
                        if (!s_allowedDoctypeSets.Contains(pair))
                        {
                            ReportParseError();
                            return this;
                        }
                    }
                }

                IDocumentType docTypeNode = new DocumentType(doc, docTypeToken.Name, docTypeToken.PublicIdentifier, docTypeToken.SystemIdentifier);
                doc.appendChild(docTypeNode);

                // Append a DocumentType node to the Document node,
                // with the name attribute set to the name given in the DOCTYPE token,
                //      or the empty string if the name was missing;
                // the publicId attribute set to the public identifier given in the DOCTYPE token,
                //      or the empty string if the public identifier was missing;
                // the systemId attribute set to the system identifier given in the DOCTYPE token,
                //      or the empty string if the system identifier was missing;

                // TODO - and the other attributes specific to DocumentType objects set to null and empty lists as appropriate.

                if (doc.nodeName != "iframe")
                {
                    if (docTypeToken.ForceQuirks ||
                        docTypeToken.Name != "html" ||
                        docTypeToken.PublicIdentifier.StartsWith(@"+//Silmaril//dtd html Pro v0r11 19970101//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//AS//DTD HTML 3.0 asWedit + extensions//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0 Level 1//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0 Level 2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0 Strict Level 1//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0 Strict Level 2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0 Strict//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 2.1E//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 3.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 3.2 Final//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 3.2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML 3//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Level 0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Level 1//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Level 2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Level 3//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Strict Level 0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Strict Level 1//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Strict Level 2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Strict Level 3//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML Strict//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//IETF//DTD HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Metrius//DTD Metrius Presentational//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 2.0 HTML Strict//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 2.0 HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 2.0 Tables//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 3.0 HTML Strict//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 3.0 HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Microsoft//DTD Internet Explorer 3.0 Tables//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Netscape Comm. Corp.//DTD HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Netscape Comm. Corp.//DTD Strict HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//O'Reilly and Associates//DTD HTML 2.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//O'Reilly and Associates//DTD HTML Extended 1.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Spyglass//DTD HTML 2.0 Extended//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//SQ//DTD HTML 2.0 HoTMetaL + extensions//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Sun Microsystems Corp.//DTD HotJava HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//Sun Microsystems Corp.//DTD HotJava Strict HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 3 1995-03-24//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 3.2 Draft//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 3.2 Final//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 3.2//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 3.2S Draft//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.0 Frameset//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.0 Transitional//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML Experimental 19960712//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML Experimental 970421//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD W3 HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3O//DTD W3 HTML 3.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.Equals(@"-//W3O//DTD W3 HTML Strict 3.0//EN//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//WebTechs//DTD Mozilla HTML 2.0//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//WebTechs//DTD Mozilla HTML//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.Equals(@"-/W3C/DTD HTML 4.0 Transitional/EN", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.Equals(@"HTML", StringComparison.Ordinal) ||
                        docTypeToken.SystemIdentifier.Equals(@"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", StringComparison.Ordinal) ||
                        (docTypeToken.SystemIdentifier == null && docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.01 Frameset//", StringComparison.Ordinal)) ||
                        (docTypeToken.SystemIdentifier == null && docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.01 Transitional//", StringComparison.Ordinal)))
                    {
                        // TODO - set the Document to quirks mode
                    } else if (
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD XHTML 1.0 Frameset//", StringComparison.Ordinal) ||
                        docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD XHTML 1.0 Transitional//", StringComparison.Ordinal) ||
                        (docTypeToken.SystemIdentifier != null && docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.01 Frameset//", StringComparison.Ordinal)) ||
                        (docTypeToken.SystemIdentifier != null && docTypeToken.PublicIdentifier.StartsWith(@"-//W3C//DTD HTML 4.01 Transitional//", StringComparison.Ordinal)))
                    {
                        // TODO - set the Document to limited-quirks mode
                    }
                    return BeforeHTMLInsertionModeState.Instance;
                }
            }

            // TODO: If the document is not an iframe srcdoc document, then this is a parse error; set the Document to quirks mode.
            //if (this.Document.Type != "srcdoc")
            //{
            // TODO - set the Document to quirks mode
            //}

            // In any case, switch the insertion mode to "before html", then reprocess the token.
            queue.EnqueueTokenForReprocessing(token);
            return BeforeHTMLInsertionModeState.Instance;
        }
 // http://www.w3.org/TR/html5/syntax.html#insert-a-comment
 public void InsertComment(CommentToken token, IDocument doc)
 {
     //TODO - make sure the steps conform with the specs in the link above.
     IComment commentNode = new Comment(doc, token.Comment);
     doc.appendChild(commentNode);
 }
        public override BaseInsertionModeState ProcessToken(HtmlTokenizer tokenizer, ITokenQueue queue, BaseToken token, IDocument doc)
        {
            if (token is DocTypeToken)
            {
                ReportParseError();
                return this;
            }

            CommentToken commentToken = token as CommentToken;
            if (commentToken != null)
            {
                IComment commentNode = new Comment(doc, commentToken.Comment);
                doc.appendChild(commentNode);
                return this;
            }

            if (IsWhitespace(token))
            {
                return this;
            }

            // * A start tag whose tag name is "html":
            StartTagToken startTagToken = token as StartTagToken;
            if (startTagToken != null && startTagToken.TagName == "html")
            {

                //   Create an element for the token (http://www.w3.org/TR/html5/syntax.html#create-an-element-for-the-token)
                //   in the HTML namespace, with the Document as the intended parent.
                //   Append it to the Document object. Put this element in the stack of open elements.
                //
                //   If the Document is being loaded as part of navigation of a browsing context,
                //   then: if the newly created element has a manifest attribute whose value is not the empty string,
                //   then resolve the value of that attribute to an absolute URL, relative to the newly created element,
                //   and if that is successful, run the application cache selection algorithm with the result of applying
                //   the URL serializer algorithm to the resulting parsed URL with the exclude fragment flag set; otherwise,
                //   if there is no such attribute, or its value is the empty string, or resolving its value fails, run the
                //   application cache selection algorithm with no manifest. The algorithm must be passed the Document object.

                // If the Document is being loaded as part of navigation of a browsing context:
                // RunApplicationCacheSelectionAlgorithm();
            }

            // * An end tag whose tag name is one of: "head", "body", "html", "br"
            //   Act as described in the "anything else" entry below.
            //
            // * Any other end tag
            //   Parse error. Ignore the token.
            EndTagToken endTagToken = token as EndTagToken;
            if (endTagToken != null &&
                endTagToken.TagName != "head" &&
                endTagToken.TagName != "body" &&
                endTagToken.TagName != "html" &&
                endTagToken.TagName != "br")
            {
                ReportParseError();
                return this;
            }

            // * Anything else
            //   Create an html element whose ownerDocument is the Document object. Append it to the Document object.
            //   Put this element in the stack of open elements.
            //
            //   If the Document is being loaded as part of navigation of a browsing context,
            //   then: run the application cache selection algorithm with no manifest, passing it the Document object.
            //
            //   Switch the insertion mode to "before head", then reprocess the token.
            //
            // The root element can end up being removed from the Document object, e.g. by scripts; nothing in particular
            // happens in such cases, content continues being appended to the nodes as described in the next section.

            HTMLElement htmlElement = new HTMLElement(doc, ((TagToken)token).TagName);
            doc.appendChild(htmlElement);
            TreeConstruction.Instance.StackOfOpenElements.Push(htmlElement);

            // If the Document is being loaded as part of navigation of a browsing context:
            // RunApplicationCacheSelectionAlgorithm();

            return BeforeHeadInsertionModeState.Instance;
        }