protected void parseAttributeValue() {
    final PsiBuilder.Marker attValue = mark();
    if (token() == XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER) {
      while (true) {
        final IElementType tt = token();
        if (tt == null
            || tt == XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER
            || tt == XmlTokenType.XML_END_TAG_START
            || tt == XmlTokenType.XML_EMPTY_ELEMENT_END
            || tt == XmlTokenType.XML_START_TAG_START) {
          break;
        }

        if (tt == XmlTokenType.XML_BAD_CHARACTER) {
          final PsiBuilder.Marker error = mark();
          advance();
          error.error(XmlPsiBundle.message("xml.parsing.unescaped.ampersand.or.nonterminated.character.entity.reference"));
        }
        else if (tt == XmlTokenType.XML_ENTITY_REF_TOKEN) {
          parseReference();
        }
        else if (hasCustomAttributeValueContent()) {
          parseCustomAttributeValueContent();
        }
        else {
          maybeRemapCurrentToken(tt);
          advance();
        }
      }

      if (token() == XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER) {
        advance();
      }
      else {
        error(XmlPsiBundle.message("xml.parsing.unclosed.attribute.value"));
      }
    }
    else if (hasCustomAttributeValue()) {
      parseCustomAttributeValue();
    }
    else {
      IElementType tt = token();
      if (tt != XmlTokenType.XML_TAG_END && tt != XmlTokenType.XML_EMPTY_ELEMENT_END) {
        if (tt != null) maybeRemapCurrentToken(tt);
        advance(); // Single token att value
      }
    }

    attValue.done(getHtmlAttributeValueElementType());
  }
protected void parseAttributeValue()