private static JetScope getExpressionResolutionScope(
     @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
   ScopeProvider provider = resolveSession.getInjector().getScopeProvider();
   JetDeclaration parentDeclaration =
       PsiTreeUtil.getParentOfType(expression, JetDeclaration.class);
   if (parentDeclaration == null) {
     return provider.getFileScopeWithAllImported((JetFile) expression.getContainingFile());
   }
   return provider.getResolutionScopeForDeclaration(parentDeclaration);
 }
 private static void functionAdditionalResolve(
     ResolveSession resolveSession,
     JetNamedFunction namedFunction,
     DelegatingBindingTrace trace,
     JetFile file) {
   BodyResolver bodyResolver =
       createBodyResolverWithEmptyContext(trace, file, resolveSession.getModuleConfiguration());
   JetScope scope =
       resolveSession
           .getInjector()
           .getScopeProvider()
           .getResolutionScopeForDeclaration(namedFunction);
   FunctionDescriptor functionDescriptor =
       (FunctionDescriptor) resolveSession.resolveToDescriptor(namedFunction);
   bodyResolver.resolveFunctionBody(trace, namedFunction, functionDescriptor, scope);
 }
 @Override
 public List<AnnotationDescriptor> getAnnotations() {
   if (annotations == null) {
     JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
     JetModifierList modifierList = classInfo.getModifierList();
     if (modifierList != null) {
       AnnotationResolver annotationResolver =
           resolveSession.getInjector().getAnnotationResolver();
       annotations =
           annotationResolver.resolveAnnotations(
               resolveSession.getResolutionScope(classInfo.getScopeAnchor()),
               modifierList,
               resolveSession.getTrace());
     } else {
       annotations = Collections.emptyList();
     }
   }
   return annotations;
 }
  private static void propertyAdditionalResolve(
      final ResolveSession resolveSession,
      final JetProperty jetProperty,
      DelegatingBindingTrace trace,
      JetFile file) {
    final JetScope propertyResolutionScope =
        resolveSession
            .getInjector()
            .getScopeProvider()
            .getResolutionScopeForDeclaration(jetProperty);

    BodyResolveContextForLazy bodyResolveContext =
        new BodyResolveContextForLazy(
            new Function<JetDeclaration, JetScope>() {
              @Override
              public JetScope apply(JetDeclaration declaration) {
                assert declaration.getParent() == jetProperty
                    : "Must be called only for property accessors, but called for " + declaration;
                return propertyResolutionScope;
              }
            });
    BodyResolver bodyResolver =
        createBodyResolver(
            trace, file, bodyResolveContext, resolveSession.getModuleConfiguration());
    PropertyDescriptor descriptor =
        (PropertyDescriptor) resolveSession.resolveToDescriptor(jetProperty);

    JetExpression propertyInitializer = jetProperty.getInitializer();

    if (propertyInitializer != null) {
      bodyResolver.resolvePropertyInitializer(
          jetProperty, descriptor, propertyInitializer, propertyResolutionScope);
    }

    bodyResolver.resolvePropertyAccessors(jetProperty, descriptor);
  }
  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;
  }