@NotNull
  private static List<RatedResolveResult> resolveInDirectory(
      @NotNull final String referencedName,
      @Nullable final PsiFile containingFile,
      final PsiDirectory dir,
      boolean isFileOnly,
      boolean checkForPackage) {
    final PsiDirectory subdir = dir.findSubdirectory(referencedName);
    if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir, containingFile))) {
      return ResolveResultList.to(subdir);
    }

    final PsiFile module = findPyFileInDir(dir, referencedName);
    if (module != null) {
      return ResolveResultList.to(module);
    }

    if (!isFileOnly) {
      // not a subdir, not a file; could be a name in parent/__init__.py
      final PsiFile initPy = dir.findFile(PyNames.INIT_DOT_PY);
      if (initPy == containingFile) {
        return Collections.emptyList(); // don't dive into the file we're in
      }
      if (initPy instanceof PyFile) {
        return ((PyFile) initPy).multiResolveName(referencedName);
      }
    }
    return Collections.emptyList();
  }
 @Override
 public Icon getIcon(@NotNull PsiElement element, int flags) {
   if (element instanceof PsiDirectory) {
     final PsiDirectory directory = (PsiDirectory) element;
     if (PyUtil.isPackage(directory, null) && !isSpecialDirectory(directory)) {
       return PlatformIcons.PACKAGE_ICON;
     }
   }
   return null;
 }
 /**
  * Finds a directory that many levels above a given file, making sure that every level has an
  * __init__.py.
  *
  * @param base file that works as a reference.
  * @param depth must be positive, 1 means the dir that contains base, 2 is one dir above, etc.
  * @return found directory, or null.
  */
 @Nullable
 public static PsiDirectory stepBackFrom(PsiFile base, int depth) {
   if (depth == 0) {
     return base.getContainingDirectory();
   }
   PsiDirectory result;
   if (base != null) {
     base = base.getOriginalFile(); // just to make sure
     result = base.getContainingDirectory();
     int count = 1;
     while (result != null && PyUtil.isPackage(result, base)) {
       if (count >= depth) return result;
       result = result.getParentDirectory();
       count += 1;
     }
   }
   return null;
 }
 @Nullable
 @Override
 public List<? extends RatedResolveResult> resolveMember(
     @NotNull String name,
     @Nullable PyExpression location,
     @NotNull AccessDirection direction,
     @NotNull PyResolveContext resolveContext) {
   final PsiElement resolved = myImportedModule.resolve();
   if (resolved != null) {
     final PsiFile containingFile = location != null ? location.getContainingFile() : null;
     List<PsiElement> elements =
         Collections.singletonList(
             ResolveImportUtil.resolveChild(resolved, name, containingFile, false, true));
     final PyImportElement importElement = myImportedModule.getImportElement();
     final PyFile resolvedFile = PyUtil.as(resolved, PyFile.class);
     if (location != null
         && importElement != null
         && PyUtil.inSameFile(location, importElement)
         && ResolveImportUtil.getPointInImport(location) == PointInImport.NONE
         && resolved instanceof PsiFileSystemItem
         && (resolvedFile == null
             || !PyUtil.isPackage(resolvedFile)
             || resolvedFile.getElementNamed(name) == null)) {
       final List<PsiElement> importedSubmodules =
           PyModuleType.collectImportedSubmodules((PsiFileSystemItem) resolved, location);
       if (importedSubmodules != null) {
         final Set<PsiElement> imported = Sets.newHashSet(importedSubmodules);
         elements =
             ContainerUtil.filter(
                 elements,
                 new Condition<PsiElement>() {
                   @Override
                   public boolean value(PsiElement element) {
                     return imported.contains(element);
                   }
                 });
       }
     }
     return ResolveImportUtil.rateResults(elements);
   }
   return null;
 }
 public Object[] getCompletionVariants(
     String completionPrefix, PsiElement location, ProcessingContext context) {
   final List<LookupElement> result = new ArrayList<LookupElement>();
   final PsiElement resolved = myImportedModule.resolve();
   if (resolved instanceof PyFile) {
     final PyModuleType moduleType = new PyModuleType((PyFile) resolved, myImportedModule);
     result.addAll(
         moduleType.getCompletionVariantsAsLookupElements(location, context, false, false));
   } else if (resolved instanceof PsiDirectory) {
     final PsiDirectory dir = (PsiDirectory) resolved;
     if (PyUtil.isPackage(dir, location)) {
       if (ResolveImportUtil.getPointInImport(location) != PointInImport.NONE) {
         result.addAll(PyModuleType.getSubModuleVariants(dir, location, null));
       } else {
         result.addAll(
             PyModuleType.collectImportedSubmodulesAsLookupElements(
                 dir, location, context.get(CTX_NAMES)));
       }
     }
   }
   return ArrayUtil.toObjectArray(result);
 }
 @Nullable
 public static PyType getTypeFromTarget(
     @NotNull final PsiElement target,
     final TypeEvalContext context,
     PyReferenceExpression anchor) {
   if (!(target
       instanceof PyTargetExpression)) { // PyTargetExpression will ask about its type itself
     final PyType pyType = getReferenceTypeFromProviders(target, context, anchor);
     if (pyType != null) {
       return pyType;
     }
   }
   if (target instanceof PyTargetExpression) {
     final String name = ((PyTargetExpression) target).getName();
     if (PyNames.NONE.equals(name)) {
       return PyNoneType.INSTANCE;
     }
     if (PyNames.TRUE.equals(name) || PyNames.FALSE.equals(name)) {
       return PyBuiltinCache.getInstance(target).getBoolType();
     }
   }
   if (target instanceof PyFile) {
     return new PyModuleType((PyFile) target);
   }
   if (target instanceof PyImportedModule) {
     return new PyImportedModuleType((PyImportedModule) target);
   }
   if ((target instanceof PyTargetExpression || target instanceof PyNamedParameter)
       && anchor != null
       && context.allowDataFlow(anchor)) {
     final ScopeOwner scopeOwner = PsiTreeUtil.getStubOrPsiParentOfType(anchor, ScopeOwner.class);
     if (scopeOwner != null
         && scopeOwner == PsiTreeUtil.getStubOrPsiParentOfType(target, ScopeOwner.class)) {
       final String name = ((PyElement) target).getName();
       if (name != null) {
         final PyType type = getTypeByControlFlow(name, context, anchor, scopeOwner);
         if (type != null) {
           return type;
         }
       }
     }
   }
   if (target instanceof PyFunction) {
     final PyDecoratorList decoratorList = ((PyFunction) target).getDecoratorList();
     if (decoratorList != null) {
       final PyDecorator propertyDecorator = decoratorList.findDecorator(PyNames.PROPERTY);
       if (propertyDecorator != null) {
         return PyBuiltinCache.getInstance(target).getObjectType(PyNames.PROPERTY);
       }
       for (PyDecorator decorator : decoratorList.getDecorators()) {
         final QualifiedName qName = decorator.getQualifiedName();
         if (qName != null
             && (qName.endsWith(PyNames.SETTER)
                 || qName.endsWith(PyNames.DELETER)
                 || qName.endsWith(PyNames.GETTER))) {
           return PyBuiltinCache.getInstance(target).getObjectType(PyNames.PROPERTY);
         }
       }
     }
   }
   if (target instanceof PyTypedElement) {
     return context.getType((PyTypedElement) target);
   }
   if (target instanceof PsiDirectory) {
     final PsiDirectory dir = (PsiDirectory) target;
     PsiFile file = dir.findFile(PyNames.INIT_DOT_PY);
     if (file != null) {
       return getTypeFromTarget(file, context, anchor);
     }
     if (PyUtil.isPackage(dir, anchor)) {
       final PsiFile containingFile = anchor.getContainingFile();
       if (containingFile instanceof PyFile) {
         final QualifiedName qualifiedName = QualifiedNameFinder.findShortestImportableQName(dir);
         if (qualifiedName != null) {
           final PyImportedModule module =
               new PyImportedModule(null, (PyFile) containingFile, qualifiedName);
           return new PyImportedModuleType(module);
         }
       }
     }
   }
   return null;
 }