public static @Nullable PsiNamedElement findRealNamedElement(final @NotNull PsiNamedElement _element) {
    PsiElement currentElement = _element;
    final XmlEntityRef lastEntityRef = PsiTreeUtil.getParentOfType(currentElement, XmlEntityRef.class);

    while (!(currentElement instanceof XmlFile)) {
      PsiElement dependingElement = currentElement.getUserData(XmlElement.DEPENDING_ELEMENT);
      if (dependingElement == null) dependingElement = currentElement.getContext();
      currentElement = dependingElement;
      if (dependingElement == null) break;
    }

    if (currentElement != null) {
      final String name = _element.getName();
      if (_element instanceof XmlEntityDecl) {
        final XmlEntityDecl cachedEntity = XmlEntityCache.getCachedEntity((PsiFile)currentElement, name);
        if (cachedEntity != null) return cachedEntity;
      }

      final PsiNamedElement[] result = new PsiNamedElement[1];

      processXmlElements((XmlFile)currentElement, element -> {
        if (element instanceof PsiNamedElement) {
          final String elementName = ((PsiNamedElement)element).getName();

          if (elementName.equals(name) && _element.getClass().isInstance(element)
              || lastEntityRef != null && element instanceof XmlEntityDecl &&
                 elementName.equals(lastEntityRef.getText().substring(1, lastEntityRef.getTextLength() - 1))) {
            result[0] = (PsiNamedElement)element;
            return false;
          }
        }

        return true;
      }, true);

      return result[0];
    }

    return null;
  }
public static @Nullable PsiNamedElement findRealNamedElement(final @NotNull PsiNamedElement _element)