@NotNull
  @Override
  public PsiReference[] getReferencesByElement(
      @NotNull PsiElement element, @NotNull ProcessingContext context) {

    if (XmlSchemaTagsProcessor.PROCESSING_FLAG.get() != null || context.get(SUPPRESS) != null) {
      return PsiReference.EMPTY_ARRAY;
    }
    @SuppressWarnings("unchecked")
    PsiElement host = getHost((T) element);
    if (host instanceof PsiLanguageInjectionHost
        && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost) host)) {
      return PsiReference.EMPTY_ARRAY;
    }
    String unquotedValue = ElementManipulators.getValueText(element);
    if (XmlHighlightVisitor.skipValidation(element)
        || !XmlUtil.isSimpleValue(unquotedValue, element)) {
      return PsiReference.EMPTY_ARRAY;
    }
    @SuppressWarnings("unchecked")
    final Object descriptor = getDescriptor((T) element);
    if (descriptor instanceof XmlEnumerationDescriptor) {
      XmlEnumerationDescriptor enumerationDescriptor = (XmlEnumerationDescriptor) descriptor;

      if (enumerationDescriptor.isFixed()
          || enumerationDescriptor.isEnumerated((XmlElement) element)) {
        //noinspection unchecked
        return enumerationDescriptor.getValueReferences((XmlElement) element, unquotedValue);
      } else if (unquotedValue.equals(
          enumerationDescriptor.getDefaultValue())) { // todo case insensitive
        return ContainerUtil.map2Array(
            enumerationDescriptor.getValueReferences((XmlElement) element, unquotedValue),
            PsiReference.class,
            reference -> PsiDelegateReference.createSoft(reference, true));
      }
    }
    return PsiReference.EMPTY_ARRAY;
  }
  @Override
  protected void checkTag(
      @NotNull final XmlTag tag, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
    if (!(tag instanceof HtmlTag)
        || !XmlHighlightVisitor.shouldBeValidated(tag)
        || isInSpecialHtml5Namespace(tag)) {
      return;
    }

    XmlElementDescriptor descriptorFromContext = XmlUtil.getDescriptorFromContext(tag);

    PsiElement parent = tag.getParent();
    XmlElementDescriptor parentDescriptor =
        parent instanceof XmlTag ? ((XmlTag) parent).getDescriptor() : null;

    XmlElementDescriptor ownDescriptor =
        isAbstractDescriptor(descriptorFromContext) ? tag.getDescriptor() : descriptorFromContext;

    if (isAbstractDescriptor(ownDescriptor)
        || (parentDescriptor instanceof HtmlElementDescriptorImpl
            && ownDescriptor instanceof HtmlElementDescriptorImpl
            && isAbstractDescriptor(descriptorFromContext))) {

      final String name = tag.getName();

      if (!isCustomValuesEnabled() || !isCustomValue(name)) {
        final AddCustomTagOrAttributeIntentionAction action =
            new AddCustomTagOrAttributeIntentionAction(
                TAG_KEY, name, XmlEntitiesInspection.UNKNOWN_TAG);

        // todo: support "element is not allowed" message for html5
        // some tags in html5 cannot be found in xhtml5.xsd if they are located in incorrect
        // context, so they get any-element descriptor (ex. "canvas: tag)
        final String message =
            isAbstractDescriptor(ownDescriptor)
                ? XmlErrorMessages.message("unknown.html.tag", name)
                : XmlErrorMessages.message("element.is.not.allowed.here", name);

        final PsiElement startTagName = XmlTagUtil.getStartTagNameElement(tag);
        assert startTagName != null;
        final PsiElement endTagName = XmlTagUtil.getEndTagNameElement(tag);

        List<LocalQuickFix> quickfixes = new ArrayList<LocalQuickFix>();
        quickfixes.add(action);
        if (isOnTheFly) {
          ContainerUtil.addIfNotNull(
              CreateNSDeclarationIntentionFix.createFix(startTagName, ""), quickfixes);
        }
        if (HtmlUtil.isHtml5Tag(name) && !HtmlUtil.hasNonHtml5Doctype(tag)) {
          quickfixes.add(new SwitchToHtml5WithHighPriorityAction());
        }
        ProblemHighlightType highlightType =
            tag.getContainingFile().getContext() == null
                ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING
                : ProblemHighlightType.INFORMATION;
        if (startTagName.getTextLength() > 0) {
          holder.registerProblem(
              startTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }

        if (endTagName != null) {
          holder.registerProblem(
              endTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }
      }
    }
  }