private CanContainAttributeType _canContainAttribute(String namespace,
                                                       @NotNull XmlTag tag,
                                                       @Nullable String qName,
                                                       Set<String> visited,
                                                       @Nullable Set<Object> dependencies) {
    if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "anyAttribute")) {
      if (dependencies != null) {
        dependencies.add(tag.getContainingFile());
      }
      String ns = tag.getAttributeValue("namespace");
      CanContainAttributeType canContainAttributeType = CanContainAttributeType.CanContainButDoNotSkip;
      if ("skip".equals(tag.getAttributeValue("processContents"))) canContainAttributeType= CanContainAttributeType.CanContainButSkip;

      if (OTHER_NAMESPACE_ATTR_VALUE.equals(ns)) {
        return !namespace.equals(myDocumentDescriptor.getDefaultNamespace()) ? canContainAttributeType : CanContainAttributeType.CanNotContain;
      }
      else if (ns == null || "##any".equals(ns)) {
        return CanContainAttributeType.CanContainAny;
      }
      return canContainAttributeType;
    }
    else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attributeGroup")) {
      String ref = tag.getAttributeValue(REF_ATTR_NAME);

      if (ref != null && !visited.contains(ref)) {
        visited.add(ref);
        XmlTag groupTag = myDocumentDescriptor.findAttributeGroup(ref);

        if (groupTag != null) {
          if (dependencies != null) {
            dependencies.add(groupTag.getContainingFile());
          }
          final CanContainAttributeType containAttributeType = _canContainAttribute(namespace, groupTag, qName, visited, dependencies);
          if (containAttributeType != CanContainAttributeType.CanNotContain) return containAttributeType;
        }
      }
    }
    else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attribute")) {
      if (qName != null && qName.equals(tag.getAttributeValue(REF_ATTR_NAME))) {
        return CanContainAttributeType.CanContainButDoNotSkip;
      }
    }
    else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, RESTRICTION_TAG_NAME) ||
             XmlNSDescriptorImpl.equalsToSchemaName(tag, EXTENSION_TAG_NAME)) {
      String base = tag.getAttributeValue(BASE_ATTR_NAME);

      if (base != null && !visited.contains(base)) {
        visited.add(base);
        TypeDescriptor descriptor = myDocumentDescriptor.findTypeDescriptor(base);

        if (descriptor instanceof ComplexTypeDescriptor complexTypeDescriptor) {
          if (dependencies != null) {
            XmlTag declaration = complexTypeDescriptor.getDeclaration();
            dependencies.add(declaration.getContainingFile());
          }

          final CanContainAttributeType containAttributeType =
            complexTypeDescriptor._canContainAttribute(namespace, complexTypeDescriptor.getDeclaration(), qName, visited, dependencies);
          if (containAttributeType != CanContainAttributeType.CanNotContain) return containAttributeType;
        }
      }
    }

    final XmlTag[] subTags = tag.getSubTags();
    for (XmlTag subTag : subTags) {
      final CanContainAttributeType containAttributeType = _canContainAttribute(namespace, subTag, qName, visited, dependencies);
      if (containAttributeType != CanContainAttributeType.CanNotContain) return containAttributeType;
    }

    return CanContainAttributeType.CanNotContain;
  }
private CanContainAttributeType _canContainAttribute(String namespace,
                                                       @NotNull XmlTag tag,
                                                       @Nullable String qName,
                                                       Set<String> visited,
                                                       @Nullable Set<Object> dependencies)