@Nullable
 private PyType resolveQualifierType(
     @NotNull List<Token<PyElementType>> tokens,
     @NotNull PyFile file,
     @NotNull TypeEvalContext context,
     @NotNull Map<TextRange, PyType> types,
     @NotNull Map<PyType, TextRange> fullRanges,
     @NotNull Map<PyType, PyImportElement> imports) {
   if (tokens.isEmpty()) {
     return null;
   }
   final Token<PyElementType> firstToken = tokens.get(0);
   final String firstText = firstToken.getText().toString();
   final TextRange firstRange = firstToken.getRange();
   final List<RatedResolveResult> resolveResults = file.multiResolveName(firstText);
   if (resolveResults.isEmpty()) {
     return getImplicitlyResolvedType(tokens, context, types, fullRanges, firstRange);
   }
   final List<PyType> members = Lists.newArrayList();
   for (RatedResolveResult result : resolveResults) {
     final PsiElement resolved = result.getElement();
     PyType type = null;
     if (resolved instanceof PyTargetExpression) {
       type =
           PyTypingTypeProvider.getTypeFromTargetExpression(
               (PyTargetExpression) resolved, context);
     }
     if (type == null && resolved instanceof PyTypedElement) {
       type = context.getType((PyTypedElement) resolved);
     }
     if (type != null) {
       if (!allowResolveToType(type)) {
         continue;
       }
       if (type instanceof PyClassLikeType) {
         type = ((PyClassLikeType) type).toInstance();
       }
       types.put(firstRange, type);
       fullRanges.put(type, firstRange);
       for (PyFromImportStatement fromImportStatement : file.getFromImports()) {
         for (PyImportElement importElement : fromImportStatement.getImportElements()) {
           if (firstText.equals(importElement.getVisibleName())) {
             imports.put(type, importElement);
           }
         }
       }
       for (PyImportElement importElement : file.getImportTargets()) {
         if (firstText.equals(importElement.getVisibleName())) {
           imports.put(type, importElement);
         }
       }
     }
     members.add(type);
   }
   if (!members.isEmpty()) {
     tokens.remove(0);
   }
   return PyUnionType.union(members);
 }
  @NotNull
  @Override
  public ResolveResult[] multiResolve(boolean incompleteCode) {
    ResolveResult[] results = super.multiResolve(incompleteCode);
    if (results.length == 0) {
      PsiFile file = myElement.getContainingFile();
      final InjectedLanguageManager languageManager =
          InjectedLanguageManager.getInstance(myElement.getProject());
      final PsiLanguageInjectionHost host = languageManager.getInjectionHost(myElement);
      if (host != null) file = host.getContainingFile();
      final String referencedName = myElement.getReferencedName();
      if (referencedName == null) return ResolveResult.EMPTY_ARRAY;

      if (host != null) {
        final List<Pair<PsiElement, TextRange>> files = languageManager.getInjectedPsiFiles(host);
        if (files != null) {
          for (Pair<PsiElement, TextRange> pair : files) {
            ResolveProcessor processor = new ResolveProcessor(referencedName);

            PyResolveUtil.scopeCrawlUp(
                processor, (ScopeOwner) pair.getFirst(), referencedName, pair.getFirst());
            final List<RatedResolveResult> resultList =
                getResultsFromProcessor(
                    referencedName, processor, pair.getFirst(), pair.getFirst());
            if (resultList.size() > 0) {
              List<RatedResolveResult> ret = RatedResolveResult.sorted(resultList);
              return ret.toArray(new RatedResolveResult[ret.size()]);
            }
          }
        }
      }

      ResolveProcessor processor = new ResolveProcessor(referencedName);

      if (file instanceof ScopeOwner)
        PyResolveUtil.scopeCrawlUp(processor, (ScopeOwner) file, referencedName, file);
      final List<RatedResolveResult> resultList =
          getResultsFromProcessor(referencedName, processor, file, file);
      if (resultList.size() > 0) {
        List<RatedResolveResult> ret = RatedResolveResult.sorted(resultList);
        return ret.toArray(new RatedResolveResult[ret.size()]);
      }
    }
    return results;
  }