@Nullable
  private static Name getCallerName(@NotNull JetFunctionLiteralExpression expression) {
    JetCallExpression callExpression = getContainingCallExpression(expression);
    if (callExpression == null) return null;

    JetExpression calleeExpression = callExpression.getCalleeExpression();
    if (calleeExpression instanceof JetSimpleNameExpression) {
      JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression;
      return nameExpression.getReferencedNameAsName();
    }

    return null;
  }
  @Nullable
  private NamespaceType lookupNamespaceType(
      @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) {
    Name name = expression.getReferencedNameAsName();
    NamespaceDescriptor namespace = context.scope.getNamespace(name);
    if (namespace == null) {
      return null;
    }
    context.trace.record(REFERENCE_TARGET, expression, namespace);

    // Construct a NamespaceType with everything from the namespace and with nested classes of the
    // corresponding class (if any)
    JetScope scope;
    ClassifierDescriptor classifier = context.scope.getClassifier(name);
    if (classifier instanceof ClassDescriptor) {
      scope =
          new ChainedScope(
              namespace,
              namespace.getMemberScope(),
              getStaticNestedClassesScope((ClassDescriptor) classifier));
    } else {
      scope = namespace.getMemberScope();
    }
    return new NamespaceType(name, scope);
  }
  @Nullable
  private JetType lookupNamespaceOrClassObject(
      @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) {
    Name referencedName = expression.getReferencedNameAsName();
    final ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
    if (classifier != null) {
      JetType classObjectType = classifier.getClassObjectType();
      if (classObjectType != null) {
        context.trace.record(REFERENCE_TARGET, expression, classifier);
        JetType result =
            getExtendedClassObjectType(classObjectType, referencedName, classifier, context);
        if (result == null) {
          context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
        }
        return DataFlowUtils.checkType(result, expression, context);
      }
    }
    JetType[] result = new JetType[1];
    TemporaryBindingTrace temporaryTrace =
        TemporaryBindingTrace.create(
            context.trace, "trace for namespace/class object lookup of name", referencedName);
    if (furtherNameLookup(expression, result, context.replaceBindingTrace(temporaryTrace))) {
      temporaryTrace.commit();
      return DataFlowUtils.checkType(result[0], expression, context);
    }
    // To report NO_CLASS_OBJECT when no namespace found
    if (classifier != null) {
      if (classifier instanceof TypeParameterDescriptor) {
        if (context.expressionPosition == ExpressionPosition.FREE) {
          context.trace.report(
              TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on(
                  expression, (TypeParameterDescriptor) classifier));
        } else {
          context.trace.report(
              TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, (TypeParameterDescriptor) classifier));
        }
      } else if (context.expressionPosition == ExpressionPosition.FREE) {
        context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
      }
      context.trace.record(REFERENCE_TARGET, expression, classifier);
      JetScope scopeForStaticMembersResolution =
          classifier instanceof ClassDescriptor
              ? getStaticNestedClassesScope((ClassDescriptor) classifier)
              : new JetScopeImpl() {
                @NotNull
                @Override
                public DeclarationDescriptor getContainingDeclaration() {
                  return classifier;
                }

                @Override
                public String toString() {
                  return "Scope for the type parameter on the left hand side of dot";
                }
              };
      return new NamespaceType(referencedName, scopeForStaticMembersResolution);
    }
    temporaryTrace.commit();
    return result[0];
  }
 @Nullable
 private JetType lookupNamespaceOrClassObject(
     @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) {
   Name referencedName = expression.getReferencedNameAsName();
   ClassifierDescriptor classifier = context.scope.getClassifier(referencedName);
   if (classifier != null) {
     JetType classObjectType = classifier.getClassObjectType();
     if (classObjectType != null) {
       context.trace.record(REFERENCE_TARGET, expression, classifier);
       JetType result;
       if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT
           && classifier instanceof ClassDescriptor) {
         JetScope scope =
             new ChainedScope(
                 classifier,
                 classObjectType.getMemberScope(),
                 getStaticNestedClassesScope((ClassDescriptor) classifier));
         result = new NamespaceType(referencedName, scope);
       } else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT
           || classifier.isClassObjectAValue()) {
         result = classObjectType;
       } else {
         context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
         result = null;
       }
       return DataFlowUtils.checkType(result, expression, context);
     }
   }
   JetType[] result = new JetType[1];
   TemporaryBindingTrace temporaryTrace =
       TemporaryBindingTrace.create(
           context.trace, "trace for namespace/class object lookup of name", referencedName);
   if (furtherNameLookup(expression, result, context.replaceBindingTrace(temporaryTrace))) {
     temporaryTrace.commit();
     return DataFlowUtils.checkType(result[0], expression, context);
   }
   // To report NO_CLASS_OBJECT when no namespace found
   if (classifier != null) {
     if (context.expressionPosition == ExpressionPosition.FREE) {
       context.trace.report(NO_CLASS_OBJECT.on(expression, classifier));
     }
     context.trace.record(REFERENCE_TARGET, expression, classifier);
     JetScope scopeForStaticMembersResolution =
         classifier instanceof ClassDescriptor
             ? getStaticNestedClassesScope((ClassDescriptor) classifier)
             : JetScope.EMPTY;
     return new NamespaceType(referencedName, scopeForStaticMembersResolution);
   }
   temporaryTrace.commit();
   return result[0];
 }
 private boolean furtherNameLookup(
     @NotNull JetSimpleNameExpression expression,
     @NotNull JetType[] result,
     @NotNull ResolutionContext context) {
   NamespaceType namespaceType = lookupNamespaceType(expression, context);
   if (namespaceType == null) {
     return false;
   }
   if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT) {
     result[0] = namespaceType;
     return true;
   }
   context.trace.report(EXPRESSION_EXPECTED_NAMESPACE_FOUND.on(expression));
   result[0] = ErrorUtils.createErrorType("Type for " + expression.getReferencedNameAsName());
   return false;
 }