@NotNull
  public JetTypeInfo getSimpleNameExpressionTypeInfo(
      @NotNull JetSimpleNameExpression nameExpression,
      @NotNull ReceiverValue receiver,
      @Nullable ASTNode callOperationNode,
      @NotNull ResolutionContext context) {
    boolean[] result = new boolean[1];

    TemporaryBindingTrace traceForVariable =
        TemporaryBindingTrace.create(context.trace, "trace to resolve as variable", nameExpression);
    JetType type =
        getVariableType(
            nameExpression,
            receiver,
            callOperationNode,
            context.replaceBindingTrace(traceForVariable),
            result);
    if (result[0]) {
      traceForVariable.commit();
      if (type instanceof NamespaceType && context.expressionPosition == ExpressionPosition.FREE) {
        type = null;
      }
      return JetTypeInfo.create(type, context.dataFlowInfo);
    }

    Call call =
        CallMaker.makeCall(
            nameExpression,
            receiver,
            callOperationNode,
            nameExpression,
            Collections.<ValueArgument>emptyList());
    TemporaryBindingTrace traceForFunction =
        TemporaryBindingTrace.create(context.trace, "trace to resolve as function", nameExpression);
    ResolvedCall<FunctionDescriptor> resolvedCall =
        getResolvedCallForFunction(
            call,
            nameExpression,
            receiver,
            context,
            ResolveMode.TOP_LEVEL_CALL,
            ResolutionResultsCache.create(),
            result);
    if (result[0]) {
      FunctionDescriptor functionDescriptor =
          resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
      traceForFunction.commit();
      boolean hasValueParameters =
          functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0;
      context.trace.report(
          FUNCTION_CALL_EXPECTED.on(nameExpression, nameExpression, hasValueParameters));
      type = functionDescriptor != null ? functionDescriptor.getReturnType() : null;
      return JetTypeInfo.create(type, context.dataFlowInfo);
    }

    traceForVariable.commit();
    return JetTypeInfo.create(null, context.dataFlowInfo);
  }
  @NotNull
  public TypeInfoForCall getCallExpressionTypeInfoForCallWithoutFinalTypeCheck(
      @NotNull JetCallExpression callExpression,
      @NotNull ReceiverValue receiver,
      @Nullable ASTNode callOperationNode,
      @NotNull ResolutionContext context,
      @NotNull ResolveMode resolveMode) {
    boolean[] result = new boolean[1];
    Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression);

    TemporaryBindingTrace traceForFunction =
        TemporaryBindingTrace.create(
            context.trace, "trace to resolve as function call", callExpression);
    ResolvedCall<FunctionDescriptor> resolvedCall =
        getResolvedCallForFunction(
            call,
            callExpression,
            receiver,
            context.replaceBindingTrace(traceForFunction),
            resolveMode,
            result);
    if (result[0]) {
      FunctionDescriptor functionDescriptor =
          resolvedCall != null ? resolvedCall.getResultingDescriptor() : null;
      traceForFunction.commit();
      if (callExpression.getValueArgumentList() == null
          && callExpression.getFunctionLiteralArguments().isEmpty()) {
        // there are only type arguments
        boolean hasValueParameters =
            functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0;
        context.trace.report(
            FUNCTION_CALL_EXPECTED.on(callExpression, callExpression, hasValueParameters));
      }
      if (functionDescriptor == null) {
        return TypeInfoForCall.create(null, context.dataFlowInfo);
      }
      JetType type = functionDescriptor.getReturnType();

      return TypeInfoForCall.create(
          type, resolvedCall.getDataFlowInfo(), resolvedCall, call, context, resolveMode);
    }

    JetExpression calleeExpression = callExpression.getCalleeExpression();
    if (calleeExpression instanceof JetSimpleNameExpression
        && callExpression.getTypeArgumentList() == null) {
      TemporaryBindingTrace traceForVariable =
          TemporaryBindingTrace.create(
              context.trace, "trace to resolve as variable with 'invoke' call", callExpression);
      JetType type =
          getVariableType(
              (JetSimpleNameExpression) calleeExpression,
              receiver,
              callOperationNode,
              context.replaceBindingTrace(traceForVariable),
              result);
      if (result[0]) {
        traceForVariable.commit();
        context.trace.report(
            FUNCTION_EXPECTED.on(
                (JetReferenceExpression) calleeExpression,
                calleeExpression,
                type != null ? type : ErrorUtils.createErrorType("")));
        return TypeInfoForCall.create(null, context.dataFlowInfo);
      }
    }
    traceForFunction.commit();
    return TypeInfoForCall.create(null, context.dataFlowInfo);
  }