protected function attributeValue() {
        if ($this->scanner->current() != '=') {
            return null;
        }
        $this->scanner->next();
        // 8.1.2.3
        $this->scanner->whitespace();

        $tok = $this->scanner->current();
        switch ($tok) {
            case "\n":
            case "\f":
            case " ":
            case "\t":
                // Whitespace here indicates an empty value.
                return null;
            case '"':
            case "'":
                $this->scanner->next();
                return $this->quotedAttributeValue($tok);
            case '>':
                // case '/': // 8.2.4.37 seems to allow foo=/ as a valid attr.
                $this->parseError("Expected attribute value, got tag end.");
                return null;
            case '=':
            case '`':
                $this->parseError("Expecting quotes, got %s.", $tok);
                return $this->unquotedAttributeValue();
            default:
                return $this->unquotedAttributeValue();
        }
    }