public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                switch (t.Type)
                {
                    case Token.TokenType.Character:

                        Token.Character c = t.AsCharacter();
                        if (c.Data.ToString().Equals(_nullString))
                        {
                            tb.Error(this);
                            return false;
                        }
                        else
                        {
                            tb.Insert(c);
                        }
                        break;
                    case Token.TokenType.Comment:
                        tb.Insert(t.AsComment());
                        break;
                    case Token.TokenType.Doctype:
                        tb.Error(this);
                        return false;
                    case Token.TokenType.StartTag:
                        Token.StartTag start = t.AsStartTag();
                        string name = start.Name();
                        if (name.Equals("html"))
                            return tb.Process(start, InBody);
                        else if (name.Equals("option"))
                        {
                            tb.Process(new Token.EndTag("option"));
                            tb.Insert(start);
                        }
                        else if (name.Equals("optgroup"))
                        {
                            if (tb.CurrentElement.NodeName.Equals("option"))
                            {
                                tb.Process(new Token.EndTag("option"));
                            }
                            else if (tb.CurrentElement.NodeName.Equals("optgroup"))
                            {
                                tb.Process(new Token.EndTag("optgroup"));
                            }
                            tb.Insert(start);
                        }
                        else if (name.Equals("select"))
                        {
                            tb.Error(this);
                            return tb.Process(new Token.EndTag("select"));
                        }
                        else if (StringUtil.In(name, "input", "keygen", "textarea"))
                        {
                            tb.Error(this);

                            if (!tb.InSelectScope("select"))
                            {
                                return false; // frag
                            }

                            tb.Process(new Token.EndTag("select"));
                            return tb.Process(start);
                        }
                        else if (name.Equals("script"))
                        {
                            return tb.Process(t, InHead);
                        }
                        else
                        {
                            return AnythingElse(t, tb);
                        }
                        break;
                    case Token.TokenType.EndTag:
                        Token.EndTag end = t.AsEndTag();
                        name = end.Name();
                        if (name.Equals("optgroup"))
                        {
                            if (tb.CurrentElement.NodeName.Equals("option") && tb.AboveOnStack(tb.CurrentElement) != null && tb.AboveOnStack(tb.CurrentElement).NodeName.Equals("optgroup"))
                            {
                                tb.Process(new Token.EndTag("option"));
                            }
                            if (tb.CurrentElement.NodeName.Equals("optgroup"))
                            {
                                tb.Pop();
                            }
                            else
                            {
                                tb.Error(this);
                            }
                        }
                        else if (name.Equals("option"))
                        {
                            if (tb.CurrentElement.NodeName.Equals("option"))
                            {
                                tb.Pop();
                            }
                            else
                            {
                                tb.Error(this);
                            }
                        }
                        else if (name.Equals("select"))
                        {
                            if (!tb.InSelectScope(name))
                            {
                                tb.Error(this);
                                return false;
                            }
                            else
                            {
                                tb.PopStackToClose(name);
                                tb.ResetInsertionMode();
                            }
                        }
                        else
                        {
                            return AnythingElse(t, tb);
                        }
                        break;
                    case Token.TokenType.EOF:
                        if (!tb.CurrentElement.NodeName.Equals("html"))
                        {
                            tb.Error(this);
                        }
                        break;
                    default:
                        return AnythingElse(t, tb);
                }
                return true;
            }
            public override bool Process(Token t, HtmlTreeBuilder tb)
            {
                if (t.IsCharacter())
                {
                    tb.NewPendingTableCharacters();
                    tb.MarkInsertionMode();
                    tb.Transition(InTableText);
                    return tb.Process(t);
                }
                else if (t.IsComment())
                {
                    tb.Insert(t.AsComment());
                    return true;
                }
                else if (t.IsDoctype())
                {
                    tb.Error(this);
                    return false;
                }
                else if (t.IsStartTag())
                {
                    Token.StartTag startTag = t.AsStartTag();
                    string name = startTag.Name();
                    if (name.Equals("caption"))
                    {
                        tb.ClearStackToTableContext();
                        tb.InsertMarkerToFormattingElements();
                        tb.Insert(startTag);
                        tb.Transition(InCaption);
                    }
                    else if (name.Equals("colgroup"))
                    {
                        tb.ClearStackToTableContext();
                        tb.Insert(startTag);
                        tb.Transition(InColumnGroup);
                    }
                    else if (name.Equals("col"))
                    {
                        tb.Process(new Token.StartTag("colgroup"));
                        return tb.Process(t);
                    }
                    else if (StringUtil.In(name, "tbody", "tfoot", "thead"))
                    {
                        tb.ClearStackToTableContext();
                        tb.Insert(startTag);
                        tb.Transition(InTableBody);
                    }
                    else if (StringUtil.In(name, "td", "th", "tr"))
                    {
                        tb.Process(new Token.StartTag("tbody"));
                        return tb.Process(t);
                    }
                    else if (name.Equals("table"))
                    {
                        tb.Error(this);
                        bool processed = tb.Process(new Token.EndTag("table"));
                        if (processed) // only ignored if in fragment
                        {
                            return tb.Process(t);
                        }
                    }
                    else if (StringUtil.In(name, "style", "script"))
                    {
                        return tb.Process(t, InHead);
                    }
                    else if (name.Equals("input"))
                    {
                        if (!startTag.Attributes["type"].Equals("hidden", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return AnythingElse(t, tb);
                        }
                        else
                        {
                            tb.InsertEmpty(startTag);
                        }
                    }
                    else if (name.Equals("form"))
                    {
                        tb.Error(this);
                        if (tb.FormElement != null)
                            return false;
                        else
                        {
                            Element form = tb.InsertEmpty(startTag);
                            tb.FormElement = form;
                        }
                    }
                    else
                    {
                        return AnythingElse(t, tb);
                    }
                }
                else if (t.IsEndTag())
                {
                    Token.EndTag endTag = t.AsEndTag();
                    string name = endTag.Name();

                    if (name.Equals("table"))
                    {
                        if (!tb.InTableScope(name))
                        {
                            tb.Error(this);
                            return false;
                        }
                        else
                        {
                            tb.PopStackToClose("table");
                        }
                        tb.ResetInsertionMode();
                    }
                    else if (StringUtil.In(name,
                            "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr"))
                    {
                        tb.Error(this);
                        return false;
                    }
                    else
                    {
                        return AnythingElse(t, tb);
                    }
                }
                else if (t.IsEOF())
                {
                    if (tb.CurrentElement.NodeName.Equals("html"))
                        tb.Error(this);
                    return true; // stops parsing
                }
                return AnythingElse(t, tb);
            }