private static Collection<SchemaTypeInfo> gatherInheritors(XmlTag xml) {
    XmlAttribute name = getNameAttr(xml);
    if (name == null || StringUtil.isEmptyOrSpaces(name.getValue())) return null;
    String localName = name.getValue();
    final boolean hasPrefix = localName.contains(":");
    localName = hasPrefix ? localName.substring(localName.indexOf(':') + 1) : localName;
    final String nsPrefix = hasPrefix ? name.getValue().substring(0, name.getValue().indexOf(':')) : null;

    final XmlFile file = XmlUtil.getContainingFile(xml);
    if (file == null) return null;
    final Project project = file.getProject();

    final Set<SchemaTypeInfo> result = new HashSet<>();
    final ArrayDeque<SchemaTypeInfo> queue = new ArrayDeque<>();

    String nsUri;
    if (! hasPrefix) {
      nsUri = getDefaultNs(file);
    } else {
      nsUri = XmlUtil.findNamespaceByPrefix(nsPrefix, file.getRootTag());
    }
    if (nsUri == null) return null;

    queue.add(new SchemaTypeInfo(localName, true, nsUri));

    final BiFunction<String, String, List<Set<SchemaTypeInfo>>> worker =
      SchemaTypeInheritanceIndex.getWorker(project, file.getContainingFile().getVirtualFile());
    while (! queue.isEmpty()) {
      final SchemaTypeInfo info = queue.removeFirst();
      final List<Set<SchemaTypeInfo>> childrenOfType = worker.apply(info.getNamespaceUri(), info.getTagName());
      for (Set<SchemaTypeInfo> infos : childrenOfType) {
        for (SchemaTypeInfo typeInfo : infos) {
          if (typeInfo.isIsTypeName()) {
            queue.add(typeInfo);
          }
          result.add(typeInfo);
        }
      }
    }
    return result;
  }
private static Collection<SchemaTypeInfo> gatherInheritors(XmlTag xml)