protected function tagName() {
        $tok = $this->scanner->current();
        if (!ctype_alpha($tok)) {
            return false;
        }

        // We know this is at least one char.
        $name = strtolower($this->scanner->charsWhile(":_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
        $attributes = array();
        $selfClose = false;

        // Handle attribute parse exceptions here so that we can
        // react by trying to build a sensible parse tree.
        try {
            do {
                $this->scanner->whitespace();
                $this->attribute($attributes);
            } while (!$this->isTagEnd($selfClose));
        } catch (HTML5_Parser_Exception $e) {
            $selfClose = false;
        }

        $mode = $this->events->startTag($name, $attributes, $selfClose);
        // Should we do this? What does this buy that selfClose doesn't?
        if ($selfClose) {
            $this->events->endTag($name);
        } elseif (is_int($mode)) {
            // fprintf(STDOUT, "Event response says move into mode %d for tag %s", $mode, $name);
            $this->setTextMode($mode, $name);
        }

        $this->scanner->next();

        return true;
    }