private void resolveUpperBoundsFromWhereClause(Set<JetType> upperBounds) {
    JetClassOrObject classOrObject =
        JetStubbedPsiUtil.getPsiOrStubParent(jetTypeParameter, JetClassOrObject.class, true);
    if (classOrObject instanceof JetClass) {
      JetClass jetClass = (JetClass) classOrObject;
      for (JetTypeConstraint jetTypeConstraint : jetClass.getTypeConstraints()) {
        DescriptorResolver.reportUnsupportedClassObjectConstraint(
            resolveSession.getTrace(), jetTypeConstraint);

        JetSimpleNameExpression constrainedParameterName =
            jetTypeConstraint.getSubjectTypeParameterName();
        if (constrainedParameterName != null) {
          if (getName().equals(constrainedParameterName.getReferencedNameAsName())) {
            resolveSession
                .getTrace()
                .record(BindingContext.REFERENCE_TARGET, constrainedParameterName, this);

            JetTypeReference boundTypeReference = jetTypeConstraint.getBoundTypeReference();
            if (boundTypeReference != null) {
              JetType boundType = resolveBoundType(boundTypeReference);
              if (!jetTypeConstraint.isClassObjectConstraint()) {
                upperBounds.add(boundType);
              }
            }
          }
        }
      }
    }
  }
 private JetType resolveBoundType(@NotNull JetTypeReference boundTypeReference) {
   return resolveSession
       .getTypeResolver()
       .resolveType(
           getContainingDeclaration().getScopeForClassHeaderResolution(),
           boundTypeReference,
           resolveSession.getTrace(),
           false);
 }
 @NotNull
 private List<AnnotationDescriptor> resolveAnnotations() {
   JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
   JetModifierList modifierList = classInfo.getModifierList();
   if (modifierList != null) {
     AnnotationResolver annotationResolver = resolveSession.getInjector().getAnnotationResolver();
     JetScope scopeForDeclaration =
         getScopeProvider().getResolutionScopeForDeclaration(classInfo.getScopeAnchor());
     return annotationResolver.resolveAnnotationsWithArguments(
         scopeForDeclaration, modifierList, resolveSession.getTrace());
   } else {
     return Collections.emptyList();
   }
 }
  private JetClassLikeInfo enumClassObjectInfo(JetClassLikeInfo classLikeInfo) {
    return new FilteringClassLikeInfo(
        resolveSession.getStorageManager(), classLikeInfo, ONLY_ENUM_ENTRIES) {
      @Override
      public JetClassOrObject getCorrespondingClassOrObject() {
        return null;
      }

      @NotNull
      @Override
      public ClassKind getClassKind() {
        return ClassKind.CLASS_OBJECT;
      }

      @NotNull
      @Override
      public List<? extends JetParameter> getPrimaryConstructorParameters() {
        return Collections.emptyList();
      }

      @NotNull
      @Override
      public List<JetTypeParameter> getTypeParameters() {
        return Collections.emptyList();
      }
    };
  }
  // TODO: Make it work for properties
  public Collection<DeclarationDescriptor> getJetCallableExtensions(
      @NotNull Condition<String> acceptedNameCondition,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope searchScope) {
    Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetExpression receiverExpression = expression.getReceiverExpression();

    if (receiverExpression != null) {
      JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
      JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);

      if (expressionType != null && scope != null) {
        Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope);

        Set<FqName> functionFQNs = new java.util.HashSet<FqName>();

        // Collect all possible extension function qualified names
        for (String name : extensionFunctionsNames) {
          if (acceptedNameCondition.value(name)) {
            Collection<PsiElement> extensionFunctions =
                getJetExtensionFunctionsByName(name, searchScope);

            for (PsiElement extensionFunction : extensionFunctions) {
              if (extensionFunction instanceof JetNamedFunction) {
                functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
              } else if (extensionFunction instanceof PsiMethod) {
                FqName functionFQN =
                    JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(
                        (PsiMethod) extensionFunction);
                if (functionFQN != null) {
                  functionFQNs.add(functionFQN);
                }
              }
            }
          }
        }

        // Iterate through the function with attempt to resolve found functions
        for (FqName functionFQN : functionFQNs) {
          for (CallableDescriptor functionDescriptor :
              ExpressionTypingUtils.canFindSuitableCall(
                  functionFQN,
                  project,
                  receiverExpression,
                  expressionType,
                  scope,
                  resolveSession.getModuleConfiguration())) {

            resultDescriptors.add(functionDescriptor);
          }
        }
      }
    }

    return resultDescriptors;
  }
  public LazyTypeParameterDescriptor(
      @NotNull ResolveSession resolveSession,
      @NotNull LazyClassDescriptor containingDeclaration,
      @NotNull JetTypeParameter jetTypeParameter,
      int index) {
    super(
        resolveSession.getStorageManager(),
        containingDeclaration,
        jetTypeParameter.getNameAsSafeName(),
        jetTypeParameter.getVariance(),
        jetTypeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
        index,
        toSourceElement(jetTypeParameter));
    this.resolveSession = resolveSession;
    this.jetTypeParameter = jetTypeParameter;

    this.resolveSession.getTrace().record(BindingContext.TYPE_PARAMETER, jetTypeParameter, this);
  }
 @NotNull
 @Override
 public DeclarationDescriptor resolveToDescriptor(JetDeclaration declaration) {
   return resolveSession.resolveToDescriptor(declaration);
 }
 public LazyPackageMemberScope(
     @NotNull ResolveSession resolveSession,
     @NotNull PackageMemberDeclarationProvider declarationProvider,
     @NotNull PackageFragmentDescriptor thisPackage) {
   super(resolveSession, declarationProvider, thisPackage, resolveSession.getTrace());
 }
 @Override
 public long getModificationCount() {
   return resolveSession.getExceptionTracker().getModificationCount();
 }
  @NotNull
  public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(
      @NotNull String name,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope scope) {
    // name parameter can differ from expression.getReferenceName() when expression contains
    // completion suffix
    Name referenceName =
        expression.getIdentifier() == null
            ? JetPsiUtil.getConventionName(expression)
            : Name.identifier(name);
    if (referenceName == null || referenceName.toString().isEmpty()) {
      return Collections.emptyList();
    }

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);

    if (jetScope == null) {
      return Collections.emptyList();
    }

    Set<FunctionDescriptor> result = Sets.newHashSet();

    Collection<PsiMethod> topLevelFunctionPrototypes =
        JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(
            referenceName.getName(), project, scope);
    for (PsiMethod method : topLevelFunctionPrototypes) {
      FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
      if (functionFQN != null) {
        JetImportDirective importDirective =
            JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false));
        Collection<? extends DeclarationDescriptor> declarationDescriptors =
            new QualifiedExpressionResolver()
                .analyseImportReference(
                    importDirective,
                    jetScope,
                    new BindingTraceContext(),
                    resolveSession.getModuleConfiguration());
        for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
          if (declarationDescriptor instanceof FunctionDescriptor) {
            result.add((FunctionDescriptor) declarationDescriptor);
          }
        }
      }
    }

    Set<FqName> affectedPackages = Sets.newHashSet();
    Collection<JetNamedFunction> jetNamedFunctions =
        JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope);
    for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
      PsiFile containingFile = jetNamedFunction.getContainingFile();
      if (containingFile instanceof JetFile) {
        JetFile jetFile = (JetFile) containingFile;
        String packageName = jetFile.getPackageName();
        if (packageName != null) {
          affectedPackages.add(new FqName(packageName));
        }
      }
    }

    for (FqName affectedPackage : affectedPackages) {
      NamespaceDescriptor packageDescriptor =
          resolveSession.getPackageDescriptorByFqName(affectedPackage);
      assert packageDescriptor != null
          : "There's a function in stub index with invalid package: " + affectedPackage;
      JetScope memberScope = packageDescriptor.getMemberScope();
      result.addAll(memberScope.getFunctions(referenceName));
    }

    return result;
  }
 private JetClassLikeInfo noEnumEntries(JetClassLikeInfo classLikeInfo) {
   return new FilteringClassLikeInfo(
       resolveSession.getStorageManager(), classLikeInfo, Predicates.not(ONLY_ENUM_ENTRIES));
 }
 @Override
 public void forceResolveAll() {
   resolveSession.forceResolveAll();
 }
 @NotNull
 @Override
 public BindingContext getBindingContext() {
   return resolveSession.getBindingContext();
 }
 @NotNull
 @Override
 public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
   return resolveSession.getClassDescriptor(classOrObject);
 }
 @NotNull
 @Override
 public ModuleDescriptor getModuleDescriptor() {
   return resolveSession.getModuleDescriptor();
 }
  public LazyClassDescriptor(
      @NotNull ResolveSession resolveSession,
      @NotNull DeclarationDescriptor containingDeclaration,
      @NotNull Name name,
      @NotNull JetClassLikeInfo classLikeInfo) {
    super(containingDeclaration, name);
    this.resolveSession = resolveSession;

    if (classLikeInfo.getCorrespondingClassOrObject() != null) {
      this.resolveSession
          .getTrace()
          .record(BindingContext.CLASS, classLikeInfo.getCorrespondingClassOrObject(), this);
    }

    this.originalClassInfo = classLikeInfo;
    JetClassLikeInfo classLikeInfoForMembers =
        classLikeInfo.getClassKind() != ClassKind.ENUM_CLASS
            ? classLikeInfo
            : noEnumEntries(classLikeInfo);
    this.declarationProvider =
        resolveSession
            .getDeclarationProviderFactory()
            .getClassMemberDeclarationProvider(classLikeInfoForMembers);

    this.unsubstitutedMemberScope =
        new LazyClassMemberScope(resolveSession, declarationProvider, this);
    this.unsubstitutedInnerClassesScope = new InnerClassesScopeWrapper(unsubstitutedMemberScope);

    this.typeConstructor = new LazyClassTypeConstructor();

    JetModifierList modifierList = classLikeInfo.getModifierList();
    this.kind = classLikeInfo.getClassKind();
    if (kind.isObject()) {
      this.modality = Modality.FINAL;
    } else {
      Modality defaultModality = kind == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
      this.modality = resolveModalityFromModifiers(modifierList, defaultModality);
    }
    this.visibility = resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
    this.isInner = isInnerClass(modifierList);

    StorageManager storageManager = resolveSession.getStorageManager();
    this.thisAsReceiverParameter =
        storageManager.createLazyValue(
            new Function0<ReceiverParameterDescriptor>() {
              @Override
              public ReceiverParameterDescriptor invoke() {
                return DescriptorFactory.createLazyReceiverParameterDescriptor(
                    LazyClassDescriptor.this);
              }
            });
    this.annotations =
        storageManager.createLazyValue(
            new Function0<List<AnnotationDescriptor>>() {
              @Override
              public List<AnnotationDescriptor> invoke() {
                return resolveAnnotations();
              }
            });
    this.classObjectDescriptor =
        storageManager.createNullableLazyValue(
            new Function0<ClassDescriptor>() {
              @Override
              public ClassDescriptor invoke() {
                return computeClassObjectDescriptor();
              }
            });
    this.scopeForClassHeaderResolution =
        storageManager.createLazyValue(
            new Function0<JetScope>() {
              @Override
              public JetScope invoke() {
                return computeScopeForClassHeaderResolution();
              }
            });
    this.scopeForMemberDeclarationResolution =
        storageManager.createLazyValue(
            new Function0<JetScope>() {
              @Override
              public JetScope invoke() {
                return computeScopeForMemberDeclarationResolution();
              }
            });
    this.scopeForPropertyInitializerResolution =
        storageManager.createLazyValue(
            new Function0<JetScope>() {
              @Override
              public JetScope invoke() {
                return computeScopeForPropertyInitializerResolution();
              }
            });
  }
 private ScopeProvider getScopeProvider() {
   return resolveSession.getInjector().getScopeProvider();
 }