@NotNull
  public KotlinTypeInfo getBlockReturnedType(
      @NotNull KtBlockExpression expression,
      @NotNull CoercionStrategy coercionStrategyForLastExpression,
      @NotNull ExpressionTypingContext context) {
    List<KtExpression> block = StatementFilterKt.filterStatements(statementFilter, expression);

    DeclarationDescriptor containingDescriptor = context.scope.getOwnerDescriptor();
    LexicalWritableScope scope =
        new LexicalWritableScope(
            context.scope,
            containingDescriptor,
            false,
            null,
            new TraceBasedRedeclarationHandler(context.trace),
            LexicalScopeKind.CODE_BLOCK);
    scope.changeLockLevel(LexicalWritableScope.LockLevel.BOTH);

    KotlinTypeInfo r;
    if (block.isEmpty()) {
      r =
          expressionTypingComponents.dataFlowAnalyzer.createCheckedTypeInfo(
              expressionTypingComponents.builtIns.getUnitType(), context, expression);
    } else {
      r =
          getBlockReturnedTypeWithWritableScope(
              scope,
              block,
              coercionStrategyForLastExpression,
              context.replaceStatementFilter(statementFilter));
    }
    scope.changeLockLevel(LexicalWritableScope.LockLevel.READING);

    if (containingDescriptor instanceof ScriptDescriptor) {
      context.trace.record(
          BindingContext.SCRIPT_SCOPE, (ScriptDescriptor) containingDescriptor, scope);
    }

    return r;
  }