@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
 public static List<PsiElement> resolveFromImportStatementSource(
     @NotNull PyFromImportStatement fromImportStatement, @Nullable QualifiedName qName) {
   final boolean absoluteImportEnabled = isAbsoluteImportEnabledFor(fromImportStatement);
   final PsiFile file = fromImportStatement.getContainingFile();
   return resolveModule(
       qName, file, absoluteImportEnabled, fromImportStatement.getRelativeLevel());
 }
  @NotNull
  public static List<RatedResolveResult> resolveNameInFromImport(
      PyFromImportStatement importStatement, @NotNull QualifiedName qName) {
    PsiFile file = importStatement.getContainingFile().getOriginalFile();
    String name = qName.getComponents().get(0);

    final List<PsiElement> candidates = importStatement.resolveImportSourceCandidates();
    List<PsiElement> resultList = new ArrayList<PsiElement>();
    for (PsiElement candidate : candidates) {
      if (!candidate.isValid()) {
        throw new PsiInvalidElementAccessException(
            candidate,
            "Got an invalid candidate from resolveImportSourceCandidates(): "
                + candidate.getClass());
      }
      if (candidate instanceof PsiDirectory) {
        candidate = PyUtil.getPackageElement((PsiDirectory) candidate, importStatement);
      }
      List<RatedResolveResult> results = resolveChildren(candidate, name, file, false, true);
      if (!results.isEmpty()) {
        for (RatedResolveResult result : results) {
          final PsiElement element = result.getElement();
          if (element != null) {
            if (!element.isValid()) {
              throw new PsiInvalidElementAccessException(
                  element, "Got an invalid candidate from resolveChild(): " + element.getClass());
            }
            resultList.add(element);
          }
        }
      }
    }
    if (!resultList.isEmpty()) {
      return rateResults(resultList);
    }
    return Collections.emptyList();
  }
 @NotNull
 public String getPresentableText(@NotNull String myName) {
   final StringBuilder sb = new StringBuilder(getQualifiedName(myName, myPath, myImportElement));
   PsiElement parent = null;
   if (myImportElement != null) {
     parent = myImportElement.getParent();
   }
   if (myImportable instanceof PyFunction) {
     sb.append(((PyFunction) myImportable).getParameterList().getPresentableText(false));
   } else if (myImportable instanceof PyClass) {
     final List<String> supers =
         ContainerUtil.mapNotNull(
             ((PyClass) myImportable).getSuperClasses(),
             new Function<PyClass, String>() {
               @Override
               public String fun(PyClass cls) {
                 return PyUtil.isObjectClass(cls) ? null : cls.getName();
               }
             });
     if (!supers.isEmpty()) {
       sb.append("(");
       StringUtil.join(supers, ", ", sb);
       sb.append(")");
     }
   }
   if (parent instanceof PyFromImportStatement) {
     sb.append(" from ");
     final PyFromImportStatement fromImportStatement = (PyFromImportStatement) parent;
     sb.append(StringUtil.repeat(".", fromImportStatement.getRelativeLevel()));
     final PyReferenceExpression source = fromImportStatement.getImportSource();
     if (source != null) {
       sb.append(source.getReferencedName());
     }
   }
   return sb.toString();
 }