@NotNull
  public static Collection<ClassDescriptor> getClassOrObjectDescriptorsByFqName(
      @NotNull ResolveSession resolveSession,
      @NotNull FqName fqName,
      boolean includeObjectDeclarations) {
    if (fqName.isRoot()) {
      return Collections.emptyList();
    }

    Collection<ClassDescriptor> classDescriptors = Lists.newArrayList();

    FqName packageFqName = fqName.parent();
    while (true) {
      NamespaceDescriptor packageDescriptor =
          resolveSession.getPackageDescriptorByFqName(packageFqName);
      if (packageDescriptor != null) {
        FqName classInPackagePath = new FqName(QualifiedNamesUtil.tail(packageFqName, fqName));
        Collection<ClassDescriptor> descriptors =
            getClassOrObjectDescriptorsByFqName(
                packageDescriptor, classInPackagePath, includeObjectDeclarations);
        classDescriptors.addAll(descriptors);
      }

      if (packageFqName.isRoot()) {
        break;
      } else {
        packageFqName = packageFqName.parent();
      }
    }

    return classDescriptors;
  }
  public static JetScope getExpressionMemberScope(
      @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
    DelegatingBindingTrace trace =
        new DelegatingBindingTrace(
            resolveSession.getBindingContext(),
            "trace to resolve a member scope of expression",
            expression);

    if (expression instanceof JetReferenceExpression) {
      QualifiedExpressionResolver qualifiedExpressionResolver =
          resolveSession.getInjector().getQualifiedExpressionResolver();

      // In some type declaration
      if (expression.getParent() instanceof JetUserType) {
        JetUserType qualifier = ((JetUserType) expression.getParent()).getQualifier();
        if (qualifier != null) {
          Collection<? extends DeclarationDescriptor> descriptors =
              qualifiedExpressionResolver.lookupDescriptorsForUserType(
                  qualifier, getExpressionResolutionScope(resolveSession, expression), trace);

          for (DeclarationDescriptor descriptor : descriptors) {
            if (descriptor instanceof LazyPackageDescriptor) {
              return ((LazyPackageDescriptor) descriptor).getMemberScope();
            }
          }
        }
      }

      // Inside import
      if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class, false) != null) {
        NamespaceDescriptor rootPackage = resolveSession.getPackageDescriptorByFqName(FqName.ROOT);
        assert rootPackage != null;

        if (expression.getParent() instanceof JetDotQualifiedExpression) {
          JetExpression element =
              ((JetDotQualifiedExpression) expression.getParent()).getReceiverExpression();
          String name = ((JetFile) expression.getContainingFile()).getPackageName();

          NamespaceDescriptor filePackage =
              name != null
                  ? resolveSession.getPackageDescriptorByFqName(new FqName(name))
                  : rootPackage;
          assert filePackage != null : "File package should be already resolved and be found";

          JetScope scope = filePackage.getMemberScope();
          Collection<? extends DeclarationDescriptor> descriptors;

          if (element instanceof JetDotQualifiedExpression) {
            descriptors =
                qualifiedExpressionResolver.lookupDescriptorsForQualifiedExpression(
                    (JetDotQualifiedExpression) element,
                    rootPackage.getMemberScope(),
                    scope,
                    trace,
                    false,
                    false);
          } else {
            descriptors =
                qualifiedExpressionResolver.lookupDescriptorsForSimpleNameReference(
                    (JetSimpleNameExpression) element,
                    rootPackage.getMemberScope(),
                    scope,
                    trace,
                    false,
                    false,
                    false);
          }

          for (DeclarationDescriptor descriptor : descriptors) {
            if (descriptor instanceof NamespaceDescriptor) {
              return ((NamespaceDescriptor) descriptor).getMemberScope();
            }
          }
        } else {
          return rootPackage.getMemberScope();
        }
      }

      // Inside package declaration
      JetNamespaceHeader namespaceHeader =
          PsiTreeUtil.getParentOfType(expression, JetNamespaceHeader.class, false);
      if (namespaceHeader != null) {
        NamespaceDescriptor packageDescriptor =
            resolveSession.getPackageDescriptorByFqName(
                namespaceHeader.getParentFqName((JetReferenceExpression) expression));
        if (packageDescriptor != null) {
          return packageDescriptor.getMemberScope();
        }
      }
    }

    return null;
  }