private @Nullable TypeDescriptor findTypeDescriptorImpl(@Nullable XmlTag rootTag, final String name, String namespace) {
    if (rootTag == null) return null;
    return RecursionManager.doPreventingRecursion(Trinity.create(rootTag, name, namespace), true, () -> {
      XmlNSDescriptorImpl responsibleDescriptor = this;
      if (namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) {
        final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true);

        if (nsDescriptor instanceof XmlNSDescriptorImpl) {
          responsibleDescriptor = (XmlNSDescriptorImpl)nsDescriptor;
        }
      }

      if (responsibleDescriptor != this) {
        return responsibleDescriptor.findTypeDescriptor(name, namespace);
      }

      final Pair<QNameKey, XmlTag> pair = Pair.create(new QNameKey(name, namespace), rootTag);
      final CachedValue<TypeDescriptor> descriptor = myTypesMap.get(pair);
      if (descriptor != null) {
        TypeDescriptor value = descriptor.getValue();
        if (value == null ||
            (value instanceof ComplexTypeDescriptor &&
             ((ComplexTypeDescriptor)value).getDeclaration().isValid()
            )
          ) {
          return value;
        }
      }

      XmlTag[] tags = rootTag.getSubTags();
      return doFindIn(tags, name, namespace, pair, rootTag);
    });
  }
private @Nullable TypeDescriptor findTypeDescriptorImpl(@Nullable XmlTag rootTag, final String name, String namespace)