private TypeDescriptor doFindIn(final XmlTag[] tags,
                                  final String name,
                                  final String namespace,
                                  final Pair<QNameKey, XmlTag> pair,
                                  final XmlTag rootTag) {
    for (final XmlTag tag : tags) {
      if (equalsToSchemaName(tag, "complexType")) {
        if (name == null) {
          CachedValue<TypeDescriptor> value = createAndPutTypesCachedValue(tag, pair);
          return value.getValue();
        }

        String nameAttribute = tag.getAttributeValue("name");

        if (isSameName(name, namespace, nameAttribute)) {
          CachedValue<TypeDescriptor> cachedValue = createAndPutTypesCachedValue(tag, pair);
          return cachedValue.getValue();
        }
      }
      else if (equalsToSchemaName(tag, "simpleType")) {

        if (name == null) {
          CachedValue<TypeDescriptor> value = createAndPutTypesCachedValueSimpleType(tag, pair);
          return value.getValue();
        }

        String nameAttribute = tag.getAttributeValue("name");

        if (isSameName(name, namespace, nameAttribute)) {
          CachedValue<TypeDescriptor> cachedValue = createAndPutTypesCachedValue(tag, pair);
          return cachedValue.getValue();
        }
      }
      else if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) ||
               (equalsToSchemaName(tag, IMPORT_TAG_NAME) &&
                (namespace == null || !namespace.equals(getDefaultNamespace()))
               )
              ) {
        final String schemaLocation = tag.getAttributeValue("schemaLocation");
        if (schemaLocation != null) {
          final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);

          if (xmlFile != null) {
            final XmlDocument document = xmlFile.getDocument();

            if (document != null) {

              final CachedValue<TypeDescriptor> value = CachedValuesManager.getManager(tag.getProject()).createCachedValue(() -> {
                final String currentName = tag.getAttributeValue("name");

                if (( currentName != null &&
                      !currentName.equals(XmlUtil.findLocalNameByQualifiedName(name)) ) ||
                     !xmlFile.isValid() ||
                     xmlFile.getDocument() == null
                   ) {
                  myTypesMap.remove(pair);
                  return new CachedValueProvider.Result<>(null, PsiModificationTracker.MODIFICATION_COUNT);
                }

                final XmlDocument document1 = xmlFile.getDocument();
                final XmlNSDescriptorImpl nsDescriptor = findNSDescriptor(tag, document1);

                if (nsDescriptor == null) {
                  myTypesMap.remove(pair);
                  return new CachedValueProvider.Result<>(null, PsiModificationTracker.MODIFICATION_COUNT);
                }

                final XmlTag rTag = document1.getRootTag();

                final TypeDescriptor complexTypeDescriptor = nsDescriptor.findTypeDescriptorImpl(rTag, name, namespace);
                return new CachedValueProvider.Result<>(complexTypeDescriptor, rTag);
              }, false
              );

              TypeDescriptor type = value.getValue();
              if (type != null) {
                myTypesMap.put(pair, value);
                return type;
              }
            }
          }
        }
      }
      else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) {
        final XmlTag[] subTags = tag.getSubTags();
        TypeDescriptor descriptor = doFindIn(subTags, name, namespace, pair, rootTag);
        if (descriptor != null) return descriptor;

        final XmlNSDescriptorImpl nsDescriptor = getRedefinedElementDescriptor(tag);
        if (nsDescriptor != null) {
          final XmlTag redefinedRootTag = ((XmlDocument)nsDescriptor.getDeclaration()).getRootTag();
          descriptor = doFindIn(redefinedRootTag.getSubTags(), name, namespace, pair, redefinedRootTag);
          if (descriptor instanceof ComplexTypeDescriptor) {
            TypeDescriptor finalDescriptor = descriptor;
            CachedValue<TypeDescriptor> value = CachedValuesManager.getManager(tag.getProject()).createCachedValue(() -> {
              RedefinedTypeDescriptor typeDescriptor = new RedefinedTypeDescriptor((ComplexTypeDescriptor)finalDescriptor, this, nsDescriptor);
              return CachedValueProvider.Result.create(typeDescriptor, PsiModificationTracker.MODIFICATION_COUNT);
            });
            myTypesMap.put(pair, value);
            return value.getValue();
          }
          if (descriptor != null) {
            return descriptor;
          }
        }
      }
    }
    return null;
  }
private TypeDescriptor doFindIn(final XmlTag[] tags,
                                  final String name,
                                  final String namespace,
                                  final Pair<QNameKey, XmlTag> pair,
                                  final XmlTag rootTag)