~
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
index 460eb3f..83150b7 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt
@@ -30,7 +30,7 @@
 import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
 
 class Candidate(
-    override val symbol: FirBasedSymbol<*>,
+    override var symbol: FirBasedSymbol<*>,
     // Here we may have an ExpressionReceiverValue
     // - in case a use-site receiver is explicit
     // - in some cases with static entities, no matter is a use-site receiver explicit or not
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
index 90bb08a..09d81e3 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt
@@ -39,7 +39,7 @@
             callInfo.arguments.forEach {
                 system.addSubsystemFromExpression(it)
             }
-            system.addOtherSystem(context.bodyResolveContext.inferenceSession.currentConstraintStorage)
+            system.addOtherSystem(context.bodyResolveContext.outerConstraintStorage)
             return system.asReadOnlyStorage()
         }
     }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt
index 43ff953..9828fdc 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt
@@ -10,8 +10,8 @@
 import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
 import org.jetbrains.kotlin.fir.declarations.FirDeclaration
 import org.jetbrains.kotlin.fir.declarations.hasAnnotation
-import org.jetbrains.kotlin.fir.expressions.*
-import org.jetbrains.kotlin.fir.render
+import org.jetbrains.kotlin.fir.expressions.FirResolvable
+import org.jetbrains.kotlin.fir.expressions.FirStatement
 import org.jetbrains.kotlin.fir.resolve.calls.Candidate
 import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
 import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
@@ -19,7 +19,6 @@
 import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
 import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 import org.jetbrains.kotlin.fir.resolve.substitution.replaceStubsAndTypeVariablesToErrors
-import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
 import org.jetbrains.kotlin.fir.types.*
 import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
 import org.jetbrains.kotlin.fir.visitors.transformSingle
@@ -27,7 +26,9 @@
 import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
 import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
-import org.jetbrains.kotlin.resolve.calls.inference.model.*
+import org.jetbrains.kotlin.resolve.calls.inference.model.BuilderInferencePosition
+import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
+import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
 import org.jetbrains.kotlin.resolve.calls.inference.registerTypeVariableIfNotPresent
 import org.jetbrains.kotlin.resolve.descriptorUtil.BUILDER_INFERENCE_ANNOTATION_FQ_NAME
 import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@@ -45,9 +46,6 @@
     private val commonCalls: MutableList<Pair<FirStatement, Candidate>> = mutableListOf()
     private var lambdaImplicitReceivers: MutableList<ImplicitExtensionReceiverValue> = mutableListOf()
 
-    override val currentConstraintStorage: ConstraintStorage
-        get() = ConstraintStorage.Empty
-
     override fun hasSyntheticTypeVariables(): Boolean = false
 
     override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean {
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
index 4081787..d53671e 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt
@@ -33,7 +33,6 @@
 import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
 import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
 import org.jetbrains.kotlin.fir.visitors.transformSingle
-import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.calls.inference.addEqualityConstraintIfCompatible
 import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
 import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
@@ -42,6 +41,7 @@
 import org.jetbrains.kotlin.types.model.StubTypeMarker
 import org.jetbrains.kotlin.types.model.TypeVariableMarker
 import org.jetbrains.kotlin.types.model.safeSubstitute
+import org.jetbrains.kotlin.util.OperatorNameConventions
 import org.jetbrains.kotlin.utils.addToStdlib.runIf
 
 class FirCallCompleter(
@@ -83,6 +83,25 @@
             call.replaceLambdaArgumentInvocationKinds(session)
         }
 
+        if (inferenceSession.skipCompletion(call, resolutionMode, completionMode)) {
+            if (candidate.callInfo.name == OperatorNameConventions.PROVIDE_DELEGATE && resolutionMode != ResolutionMode.ContextDependentDelegate) {
+                val inferenceSession = inferenceSession as FirDelegatedPropertyInferenceSession
+
+                val innerSet = candidate.freshVariables.mapTo(mutableSetOf()) { it.typeConstructor }
+                inferenceSession.currentConstraintSystem.withDisallowingOnlyThisTypeVariablesForProperTypes(innerSet) {
+                    runCompletionForCall(candidate, ConstraintSystemCompletionMode.FULL, call, initialType, analyzer)
+                }
+            } else {
+                runCompletionForCall(candidate, ConstraintSystemCompletionMode.PARTIAL, call, initialType, analyzer)
+            }
+            // Running completion at least partially is required to filter out some of the candidates of subsequent calls,
+            // thus avoiding resolution ambiguity for them.
+            // Can't use `completionCall` in case it's FULL, because we can't force getValue() completion until BI lambdas in delegate expression are completed
+            // But those lambdas cannot be found at getValeu() calls as they don't belong there
+
+            return call
+        }
+
         return when (completionMode) {
             ConstraintSystemCompletionMode.FULL -> {
                 if (inferenceSession.shouldRunCompletion(call)) {
@@ -91,7 +110,7 @@
                         .buildAbstractResultingSubstitutor(session.typeContext) as ConeSubstitutor
                     val completedCall = call.transformSingle(
                         FirCallCompletionResultsWriterTransformer(
-                            session, finalSubstitutor,
+                            session, components.scopeSession, finalSubstitutor,
                             components.returnTypeCalculator,
                             session.typeApproximator,
                             components.dataFlowAnalyzer,
@@ -111,12 +130,6 @@
             ConstraintSystemCompletionMode.PARTIAL -> {
                 runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
 
-                // Add top-level delegate call as partially resolved to inference session
-                if (resolutionMode is ResolutionMode.ContextDependentDelegate) {
-                    require(inferenceSession is FirDelegatedPropertyInferenceSession)
-                    inferenceSession.addPartiallyResolvedCall(call)
-                }
-
                 call
             }
 
@@ -210,7 +223,7 @@
         mode: FirCallCompletionResultsWriterTransformer.Mode = FirCallCompletionResultsWriterTransformer.Mode.Normal
     ): FirCallCompletionResultsWriterTransformer {
         return FirCallCompletionResultsWriterTransformer(
-            session, substitutor, components.returnTypeCalculator,
+            session, components.scopeSession, substitutor, components.returnTypeCalculator,
             session.typeApproximator,
             components.dataFlowAnalyzer,
             components.integerLiteralAndOperatorApproximationTransformer,
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
index a40d858..d66b3d6 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt
@@ -6,22 +6,28 @@
 package org.jetbrains.kotlin.fir.resolve.inference
 
 import org.jetbrains.kotlin.fir.declarations.FirProperty
+import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
+import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
 import org.jetbrains.kotlin.fir.expressions.FirResolvable
 import org.jetbrains.kotlin.fir.expressions.FirStatement
-import org.jetbrains.kotlin.fir.resolve.calls.*
-import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition
-import org.jetbrains.kotlin.fir.resolve.substitution.*
+import org.jetbrains.kotlin.fir.resolve.ResolutionMode
+import org.jetbrains.kotlin.fir.resolve.calls.Candidate
+import org.jetbrains.kotlin.fir.resolve.calls.InferenceError
+import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
+import org.jetbrains.kotlin.fir.resolve.calls.candidate
+import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 import org.jetbrains.kotlin.fir.types.*
+import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
-import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
 import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
-import org.jetbrains.kotlin.resolve.calls.inference.model.BuilderInferencePosition
 import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
 import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
-import org.jetbrains.kotlin.resolve.calls.inference.registerTypeVariableIfNotPresent
-import org.jetbrains.kotlin.types.model.*
+import org.jetbrains.kotlin.types.model.TypeConstructorMarker
+import org.jetbrains.kotlin.types.model.TypeVariableMarker
+import org.jetbrains.kotlin.util.OperatorNameConventions
 
 class FirDelegatedPropertyInferenceSession(
     val property: FirProperty,
@@ -29,141 +35,81 @@
     private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
 ) : FirInferenceSessionForChainedResolve(resolutionContext) {
 
-    private val currentConstraintSystem = components.session.inferenceComponents.createConstraintSystem()
-    override val currentConstraintStorage: ConstraintStorage get() = currentConstraintSystem.currentStorage()
+    var currentConstraintSystem = components.session.inferenceComponents.createConstraintSystem()
+    val currentConstraintStorage: ConstraintStorage get() = currentConstraintSystem.currentStorage()
 
     private val unitType: ConeClassLikeType = components.session.builtinTypes.unitType.type
-    private lateinit var resultingConstraintSystem: NewConstraintSystem
-
-    private fun ConeKotlinType.containsStubType(): Boolean {
-        return this.contains {
-            it is ConeStubTypeForChainInference
-        }
-    }
-
-    private fun integrateResolvedCall(storage: ConstraintStorage) {
-        registerSyntheticVariables(storage)
-        val stubToTypeVariableSubstitutor = createToSyntheticTypeVariableSubstitutor()
-        integrateConstraints(
-            currentConstraintSystem,
-            storage,
-            stubToTypeVariableSubstitutor,
-            false
-        )
-    }
 
     override fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement {
-        partiallyResolvedCalls += call to candidate
-        if (candidate.isSuccessful) {
-            integrateResolvedCall(candidate.system.asReadOnlyStorage())
-        }
+        // TODO
     }
 
     override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {
-        super.addPartiallyResolvedCall(call)
-        if (call.candidate.isSuccessful) {
-            integrateResolvedCall(call.candidate.system.currentStorage())
-        }
+        // TODO
     }
 
-    override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement {
-        val callee = call.calleeReference as? FirNamedReferenceWithCandidate ?: return true
+    override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true
 
-        if (callee.candidate.system.hasContradiction) return true
+    override fun <R> onCandidatesResolution(call: FirFunctionCall, candidatesResolutionCallback: () -> R): R {
+        return if (!call.isAnyOfDelegateOperators())
+            candidatesResolutionCallback()
+        else
+            resolutionContext.bodyResolveContext.withOuterConstraintStorage(
+                currentConstraintSystem.currentStorage(),
+                candidatesResolutionCallback
+            )
+    }
 
-        val hasStubType =
-            callee.candidate.chosenExtensionReceiver?.typeRef?.coneType?.containsStubType() ?: false
-                    || callee.candidate.dispatchReceiver?.typeRef?.coneType?.containsStubType() ?: false
+    override fun <T> skipCompletion(
+        call: T,
+        resolutionMode: ResolutionMode,
+        completionMode: ConstraintSystemCompletionMode
+    ): Boolean where T : FirResolvable, T : FirStatement {
+        if (!call.candidate.isSuccessful && call.isOperatorCallWithName { it == OperatorNameConventions.PROVIDE_DELEGATE }) return false
+        // Do not run completion for provideDelegate/getValue/setValue because they might affect each other
+        if (completionMode == ConstraintSystemCompletionMode.FULL && resolutionMode == ResolutionMode.ContextDependentDelegate) return false
 
-        if (!hasStubType) {
+        if (resolutionMode == ResolutionMode.ContextDependentDelegate || call.isAnyOfDelegateOperators()) {
+            partiallyResolvedCalls.add(call to call.candidate)
+            currentConstraintSystem = call.candidate.system
             return true
         }
 
-        val system = call.candidate.system
-
-        val storage = system.getBuilder().currentStorage()
-
-        if (call.hasPostponed()) return true
-
-        return storage.notFixedTypeVariables.keys.all {
-            val variable = storage.allTypeVariables[it]
-            val isPostponed = variable != null && variable in storage.postponedTypeVariables
-            isPostponed || isSyntheticTypeVariable(variable!!) ||
-                    components.callCompleter.completer.variableFixationFinder.isTypeVariableHasProperConstraint(system, it)
-        }
+        return false
     }
 
-    private fun FirStatement.hasPostponed(): Boolean {
-        var result = false
-        processAllContainingCallCandidates(processBlocks = false) {
-            result = result || it.hasPostponed()
-        }
-        return result
+    private fun <T> T.isAnyOfDelegateOperators(): Boolean where T : FirResolvable, T : FirStatement = isOperatorCallWithName {
+        it == OperatorNameConventions.PROVIDE_DELEGATE || it == OperatorNameConventions.GET_VALUE || it == OperatorNameConventions.SET_VALUE
     }
 
-    private fun Candidate.hasPostponed(): Boolean {
-        return postponedAtoms.any { !it.analyzed }
+    private fun <T> T.isOperatorCallWithName(predicate: (Name) -> Boolean): Boolean where T : FirResolvable, T : FirStatement {
+        if (this !is FirFunctionCall) return false
+        val name = calleeReference.name
+        if (!predicate(name)) return false
+
+        return origin == FirFunctionCallOrigin.Operator
     }
 
+
     override fun inferPostponedVariables(
         lambda: ResolvedLambdaAtom,
         constraintSystemBuilder: ConstraintSystemBuilder,
         completionMode: ConstraintSystemCompletionMode
     ): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
 
-    private fun createNonFixedTypeToVariableSubstitutor(): NotFixedTypeToVariableSubstitutorForDelegateInference {
-        val typeContext = components.session.typeContext
-
-        val bindings = mutableMapOf<TypeVariableMarker, ConeKotlinType>()
-        for ((variable, synthetic) in syntheticTypeVariableByTypeVariable) {
-            bindings[synthetic] = variable.defaultType(typeContext) as ConeKotlinType
-        }
-
-        return NotFixedTypeToVariableSubstitutorForDelegateInference(bindings, typeContext)
-    }
-
-
-    /*
-     * This creates Stub-preserving substitution to synthetic type variables
-     * Stub(R) => Stub(_R)
-     * R => _R
-     */
-    private fun createToSyntheticTypeVariableSubstitutor(): ConeSubstitutor {
-
-        val typeContext = components.session.typeContext
-        val bindings = mutableMapOf<TypeConstructorMarker, ConeKotlinType>()
-        for ((variable, syntheticVariable) in syntheticTypeVariableByTypeVariable) {
-            bindings[variable.freshTypeConstructor(typeContext)] = syntheticVariable.defaultType
-        }
-
-        return typeContext.typeSubstitutorByTypeConstructor(bindings)
-    }
-
-    override fun hasSyntheticTypeVariables(): Boolean {
-        return syntheticTypeVariableByTypeVariable.isNotEmpty()
-    }
-
-    override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean {
-        return typeVariable in syntheticTypeVariableByTypeVariable.values
+    override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map<TypeConstructorMarker, ConeStubType> {
+        TODO("Not yet implemented")
     }
 
     override fun fixSyntheticTypeVariableWithNotEnoughInformation(
         typeVariable: TypeVariableMarker,
         completionContext: ConstraintSystemCompletionContext
     ) {
-        typeVariable as ConeTypeVariable
-        completionContext.fixVariable(
-            typeVariable,
-            ConeStubTypeForSyntheticFixation(
-                ConeStubTypeConstructor(typeVariable, isTypeVariableInSubtyping = false, isForFixation = true),
-                ConeNullability.create(typeVariable.defaultType.isMarkedNullable)
-            ),
-            ConeFixVariableConstraintPosition(typeVariable)
-        )
+        error("")
     }
 
     fun completeCandidates(): List<FirResolvable> {
-        val commonSystem = components.session.inferenceComponents.createConstraintSystem()
+        val commonSystem = currentConstraintSystem
 
         val notCompletedCalls = partiallyResolvedCalls.mapNotNull { partiallyResolvedCall ->
             partiallyResolvedCall.first.takeIf { resolvable ->
@@ -171,20 +117,6 @@
             }
         }
 
-        val stubToTypeVariableSubstitutor = createNonFixedTypeToVariableSubstitutor()
-
-        for ((call, candidate) in partiallyResolvedCalls) {
-            if (candidate.isSuccessful) {
-                integrateConstraints(
-                    commonSystem,
-                    candidate.system.asReadOnlyStorage(),
-                    stubToTypeVariableSubstitutor,
-                    call.candidate() != null
-                )
-            }
-        }
-
-
         resolutionContext.bodyResolveContext.withInferenceSession(DEFAULT) {
             @Suppress("UNCHECKED_CAST")
             components.callCompleter.completer.complete(
@@ -218,97 +150,20 @@
             }
         }
 
-        resultingConstraintSystem = commonSystem
         return notCompletedCalls
     }
 
     fun createFinalSubstitutor(): ConeSubstitutor {
-        val stubTypeSubstitutor = createNonFixedTypeToVariableSubstitutor()
-
         val typeContext = components.session.typeContext
-        val resultSubstitutor = resultingConstraintSystem.asReadOnlyStorage()
+
+        val t = currentConstraintSystem.asReadOnlyStorage()
             .buildAbstractResultingSubstitutor(typeContext) as ConeSubstitutor
-        return ChainedSubstitutor(stubTypeSubstitutor, resultSubstitutor)
-            .replaceStubsAndTypeVariablesToErrors(typeContext, stubTypesByTypeVariable.values.map { it.constructor })
+
+        // TODO: TT??
+        return ChainedSubstitutor(t, t)
     }
 
-    private val stubTypesByTypeVariable: MutableMap<ConeTypeVariable, ConeStubType> = mutableMapOf()
-    private val syntheticTypeVariableByTypeVariable = mutableMapOf<TypeVariableMarker, ConeTypeVariable>()
+    override fun hasSyntheticTypeVariables(): Boolean = false
 
-    private fun registerSyntheticVariables(storage: ConstraintStorage) {
-        for (variableWithConstraints in storage.notFixedTypeVariables.values) {
-            val variable = variableWithConstraints.typeVariable as ConeTypeVariable
-
-            val syntheticVariable = syntheticTypeVariableByTypeVariable.getOrPut(variable) {
-                ConeTypeVariable("_" + variable.typeConstructor.name).also {
-                    currentConstraintSystem.registerVariable(it)
-                }
-            }
-
-            stubTypesByTypeVariable.getOrPut(variable) {
-                ConeStubTypeForChainInference(
-                    syntheticVariable,
-                    ConeNullability.create(syntheticVariable.defaultType.isMarkedNullable)
-                )
-            }
-        }
-    }
-
-    override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map<TypeConstructorMarker, ConeStubType> {
-
-        val bindings = mutableMapOf<TypeConstructorMarker, ConeStubType>()
-        registerSyntheticVariables(system.currentStorage())
-        for (variable in system.postponedTypeVariables) {
-            variable as ConeTypeVariable
-
-            bindings[variable.typeConstructor] = stubTypesByTypeVariable[variable]!!
-        }
-
-        return bindings
-    }
-
-    override fun registerStubTypes(map: Map<TypeVariableMarker, StubTypeMarker>) {
-//        @Suppress("UNCHECKED_CAST")
-//        stubTypesByTypeVariable.putAll(map as Map<ConeTypeVariable, ConeStubType>)
-    }
-
-
-    private fun integrateConstraints(
-        commonSystem: NewConstraintSystemImpl,
-        storage: ConstraintStorage,
-        nonFixedToVariablesSubstitutor: ConeSubstitutor,
-        shouldIntegrateAllConstraints: Boolean
-    ) {
-        if (shouldIntegrateAllConstraints) {
-            storage.notFixedTypeVariables.values.forEach {
-                if (isSyntheticTypeVariable(it.typeVariable)) return@forEach
-                commonSystem.registerTypeVariableIfNotPresent(it.typeVariable)
-            }
-        }
-        /*
-        * storage can contain the following substitutions:
-        *  TypeVariable(A) -> ProperType
-        *  TypeVariable(B) -> Special-Non-Fixed-Type
-        *
-        * while substitutor from parameter map non-fixed types to the original type variable
-        * */
-        val callSubstitutor =
-            storage.buildAbstractResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false) as ConeSubstitutor
-
-        for (initialConstraint in storage.initialConstraints) {
-            integrateConstraintToSystem(
-                commonSystem, initialConstraint, callSubstitutor, nonFixedToVariablesSubstitutor, storage.fixedTypeVariables
-            )
-        }
-
-        if (shouldIntegrateAllConstraints) {
-            for ((variableConstructor, type) in storage.fixedTypeVariables) {
-                val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
-                if (isSyntheticTypeVariable(typeVariable)) continue
-
-                commonSystem.registerTypeVariableIfNotPresent(typeVariable)
-                commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, BuilderInferencePosition)
-            }
-        }
-    }
+    override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean = false
 }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
index 3e7f83d..4157308 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt
@@ -5,8 +5,10 @@
 
 package org.jetbrains.kotlin.fir.resolve.inference
 
+import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
 import org.jetbrains.kotlin.fir.expressions.FirResolvable
 import org.jetbrains.kotlin.fir.expressions.FirStatement
+import org.jetbrains.kotlin.fir.resolve.ResolutionMode
 import org.jetbrains.kotlin.fir.resolve.calls.Candidate
 import org.jetbrains.kotlin.fir.types.ConeKotlinType
 import org.jetbrains.kotlin.fir.types.ConeStubType
@@ -14,7 +16,6 @@
 import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
 import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
-import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
 import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
 import org.jetbrains.kotlin.types.model.StubTypeMarker
 import org.jetbrains.kotlin.types.model.TypeConstructorMarker
@@ -26,7 +27,11 @@
     }
 
     abstract fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement
-    abstract val currentConstraintStorage: ConstraintStorage
+    open fun <T> skipCompletion(
+        call: T,
+        resolutionMode: ResolutionMode,
+        completionMode: ConstraintSystemCompletionMode
+    ): Boolean where T : FirResolvable, T : FirStatement = false
 
     abstract fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement
     abstract fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement
@@ -49,14 +54,12 @@
 
     abstract fun clear()
     abstract fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map<TypeConstructorMarker, ConeStubType>
+    open fun <R> onCandidatesResolution(call: FirFunctionCall, candidatesResolutionCallback: () -> R) = candidatesResolutionCallback()
 }
 
 abstract class FirStubInferenceSession : FirInferenceSession() {
     override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true
 
-    override val currentConstraintStorage: ConstraintStorage
-        get() = ConstraintStorage.Empty
-
     override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {}
     override fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement {}
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
index aa90ddd..4e2389f 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt
@@ -30,12 +30,16 @@
 import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
 import org.jetbrains.kotlin.fir.resolve.inference.ResolvedLambdaAtom
 import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
 import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.*
+import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
 import org.jetbrains.kotlin.fir.scopes.impl.ConvertibleIntegerOperators.binaryOperatorsWithSignedArgument
+import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
 import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
 import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
 import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
 import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
 import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
 import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
 import org.jetbrains.kotlin.fir.types.*
@@ -58,6 +62,7 @@
 
 class FirCallCompletionResultsWriterTransformer(
     override val session: FirSession,
+    private val scopeSession: ScopeSession,
     private val finalSubstitutor: ConeSubstitutor,
     private val typeCalculator: ReturnTypeCalculator,
     private val typeApproximator: ConeTypeApproximator,
@@ -101,6 +106,9 @@
         qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate,
     ): T {
         val subCandidate = calleeReference.candidate
+
+        subCandidate.refineSubstitutedSymbol()
+
         val declaration = subCandidate.symbol.fir
         val typeArguments = computeTypeArguments(qualifiedAccessExpression, subCandidate)
         val typeRef = if (declaration is FirCallableDeclaration) {
@@ -134,6 +142,12 @@
             }
         }
 
+        if (mode == Mode.DelegatedPropertyCompletion) {
+            // Update type for `$delegateField` in `$$delegateField.get/setValue()` calls inside accessors
+            val typeUpdater = TypeUpdaterForDelegateArguments()
+            qualifiedAccessExpression.transformExplicitReceiver(typeUpdater, null)
+        }
+
         var dispatchReceiver = subCandidate.dispatchReceiverExpression()
         var extensionReceiver = subCandidate.chosenExtensionReceiverExpression()
         if (!declaration.isWrappedIntegerOperator()) {
@@ -169,18 +183,58 @@
         return qualifiedAccessExpression
     }
 
+    private fun Candidate.refineSubstitutedSymbol() {
+        val updatedSymbol = symbol.refineSubstitutedSymbol() ?: return
+        val oldSymbol = symbol
+        symbol = updatedSymbol
+
+        if (updatedSymbol !is FirFunctionSymbol) return
+        require(oldSymbol is FirFunctionSymbol)
+
+        val oldArgumentMapping = argumentMapping ?: return
+        val oldValueParametersToNewMap = oldSymbol.valueParameterSymbols.zip(updatedSymbol.valueParameterSymbols).toMap()
+
+        argumentMapping = oldArgumentMapping.mapValuesTo(linkedMapOf()) {
+            oldValueParametersToNewMap[it.value.symbol]!!.fir
+        }
+
+        substitutor = substitutorByMap(
+            updatedSymbol.typeParameterSymbols.zip(freshVariables).associate { (typeParameter, typeVariable) ->
+                typeParameter to typeVariable.defaultType
+            },
+            session,
+        )
+    }
+
+    private fun FirBasedSymbol<*>.refineSubstitutedSymbol(): FirBasedSymbol<*>? {
+        val fir = fir
+        if (fir !is FirCallableDeclaration) return null
+
+        val dispatchReceiverType = fir.dispatchReceiverType ?: return null
+        val updatedDispatchReceiverType = finalSubstitutor.substituteOrNull(dispatchReceiverType) ?: return null
+
+        val scope =
+            updatedDispatchReceiverType.scope(
+                session,
+                scopeSession,
+                FakeOverrideTypeCalculator.DoNothing,
+                FirResolvePhase.STATUS
+            ) as? FirClassSubstitutionScope ?: return null
+
+        return when (val original = fir.originalForSubstitutionOverride) {
+            is FirSimpleFunction -> scope.createSubstitutionOverrideFunction(original.symbol)
+            is FirProperty -> scope.createSubstitutionOverrideProperty(original.symbol)
+            is FirConstructor -> scope.createSubstitutionOverrideConstructor(original.symbol)
+            else -> error("!!!")
+        }
+    }
+
     override fun transformQualifiedAccessExpression(
         qualifiedAccessExpression: FirQualifiedAccessExpression,
         data: ExpectedArgumentType?,
     ): FirStatement {
         val calleeReference = qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate
-            ?: return run {
-                if (mode == Mode.DelegatedPropertyCompletion) {
-                    val typeUpdater = TypeUpdaterForDelegateArguments()
-                    qualifiedAccessExpression.transformSingle(typeUpdater, null)
-                }
-                qualifiedAccessExpression
-            }
+            ?: return qualifiedAccessExpression
         val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference)
         val typeRef = result.typeRef as FirResolvedTypeRef
         val subCandidate = calleeReference.candidate
@@ -190,11 +244,6 @@
         result.replaceTypeRef(resultType)
         session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source)
 
-        if (mode == Mode.DelegatedPropertyCompletion) {
-            val typeUpdater = TypeUpdaterForDelegateArguments()
-            result.transformExplicitReceiver(typeUpdater, null)
-        }
-
         return result
     }
 
@@ -242,12 +291,6 @@
         result.replaceTypeRef(resultType)
         session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, context.file.source)
 
-        if (mode == Mode.DelegatedPropertyCompletion) {
-            val typeUpdater = TypeUpdaterForDelegateArguments()
-            result.argumentList.transformArguments(typeUpdater, null)
-            result.transformExplicitReceiver(typeUpdater, null)
-        }
-
         if (enableArrayOfCallTransformation) {
             return arrayOfCallTransformer.transformFunctionCall(result, session)
         }
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
index 08f0a05..4d67a23 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt
@@ -7,13 +7,15 @@
 
 import org.jetbrains.kotlin.config.LanguageFeature
 import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.fir.*
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.correspondingProperty
 import org.jetbrains.kotlin.fir.declarations.*
 import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
 import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
 import org.jetbrains.kotlin.fir.declarations.utils.isInner
 import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
 import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
+import org.jetbrains.kotlin.fir.languageVersionSettings
 import org.jetbrains.kotlin.fir.resolve.*
 import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
 import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
@@ -38,6 +40,7 @@
 import org.jetbrains.kotlin.fir.types.*
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.name.SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
+import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
 import org.jetbrains.kotlin.util.PrivateForInline
 
 class BodyResolveContext(
@@ -87,6 +90,12 @@
     @set:PrivateForInline
     var inferenceSession: FirInferenceSession = FirInferenceSession.DEFAULT
 
+    @set:PrivateForInline
+    var currentDelegatedPropertyInferenceSession: FirDelegatedPropertyInferenceSession? = null
+
+    @set:PrivateForInline
+    var outerConstraintStorage: ConstraintStorage = ConstraintStorage.Empty
+
     val anonymousFunctionsAnalyzedInDependentContext: MutableSet<FirFunctionSymbol<*>> = mutableSetOf()
 
     var containingClassDeclarations: ArrayDeque<FirRegularClass> = ArrayDeque()
@@ -814,6 +823,7 @@
         }
     }
 
+    @OptIn(PrivateForInline::class)
     inline fun <T> forPropertyDelegateAccessors(
         property: FirProperty,
         resolutionContext: ResolutionContext,
@@ -826,12 +836,35 @@
             callCompleter.createPostponedArgumentsAnalyzer(resolutionContext)
         )
 
+//        val oldSession = this.currentDelegatedPropertyInferenceSession
+//        this.currentDelegatedPropertyInferenceSession = inferenceSession
+//        try {
+//            inferenceSession.f()
+//        } finally {
+//            this.currentDelegatedPropertyInferenceSession = oldSession
+//        }
+
         withInferenceSession(inferenceSession) {
             inferenceSession.f()
         }
     }
 
     @OptIn(PrivateForInline::class)
+    inline fun <T> withOuterConstraintStorage(
+        storage: ConstraintStorage,
+        f: () -> T
+    ): T {
+        val oldStorage = this.outerConstraintStorage
+        this.outerConstraintStorage = storage
+        return try {
+            f()
+        } finally {
+            this.outerConstraintStorage = oldStorage
+        }
+    }
+
+
+    @OptIn(PrivateForInline::class)
     inline fun <T> withConstructor(constructor: FirConstructor, f: () -> T): T =
         withContainer(constructor, f)
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
index b23fb7b..7fad5ae 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt
@@ -32,10 +32,12 @@
 import org.jetbrains.kotlin.fir.resolve.calls.candidate
 import org.jetbrains.kotlin.fir.resolve.dfa.FirControlFlowGraphReferenceImpl
 import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeLocalVariableNoTypeOrInitializer
+import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession
 import org.jetbrains.kotlin.fir.resolve.inference.FirStubTypeTransformer
 import org.jetbrains.kotlin.fir.resolve.inference.ResolvedLambdaAtom
 import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionType
-import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
+import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
 import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolver
 import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForFunction
@@ -47,6 +49,7 @@
 import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
 import org.jetbrains.kotlin.fir.visitors.FirTransformer
 import org.jetbrains.kotlin.fir.visitors.transformSingle
+import org.jetbrains.kotlin.resolve.calls.inference.buildCurrentSubstitutor
 
 open class FirDeclarationsResolveTransformer(
     transformer: FirAbstractBodyResolveTransformerDispatcher
@@ -288,6 +291,7 @@
 
             val finalSubstitutor = createFinalSubstitutor()
 
+            // TODO: Replace just property/accessors return types instead
             val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor)
             property.transformSingle(stubTypeCompletionResultsWriter, null)
             property.replaceReturnTypeRef(
@@ -334,18 +338,10 @@
         if (delegateExpression is FirResolvable) {
             val calleeReference = delegateExpression.calleeReference
             if (calleeReference is FirNamedReferenceWithCandidate) {
-                val system = calleeReference.candidate.system
-                system.notFixedTypeVariables.forEach {
-                    system.markPostponedVariable(it.value.typeVariable)
-                }
-                val typeVariableTypeToStubType = context.inferenceSession.createSyntheticStubTypes(system)
-
-                val substitutor = createTypeSubstitutorByTypeConstructor(
-                    typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
-                )
                 val delegateExpressionTypeRef = delegateExpression.typeRef
-                val stubTypeSubstituted = substitutor.substituteOrNull(delegateExpressionTypeRef.coneType)
-                delegateExpression.replaceTypeRef(delegateExpressionTypeRef.withReplacedConeType(stubTypeSubstituted))
+                val returnTypeSubstitutedWithTypeVariables =
+                    calleeReference.candidate.substitutor.substituteOrNull(delegateExpressionTypeRef.coneType)
+                delegateExpression.replaceTypeRef(delegateExpressionTypeRef.withReplacedConeType(returnTypeSubstitutedWithTypeVariables))
             }
         }
 
@@ -356,28 +352,23 @@
         // TODO: this generates some nodes in the control flow graph which we don't want if we
         //  end up not selecting this option, KT-59684
         transformer.expressionsTransformer.transformFunctionCallInternal(
-            provideDelegateCall, ResolutionMode.ContextIndependent, provideDelegate = true
+            provideDelegateCall, ResolutionMode.ContextIndependent, skipExplicitReceiverTransformation = true
         )
 
         // If we got successful candidate for provideDelegate, let's select it
         val provideDelegateCandidate = provideDelegateCall.candidate()
         if (provideDelegateCandidate != null && provideDelegateCandidate.isSuccessful) {
-            val system = provideDelegateCandidate.system
-            system.notFixedTypeVariables.forEach {
-                system.markPostponedVariable(it.value.typeVariable)
-            }
-            val typeVariableTypeToStubType = context.inferenceSession.createSyntheticStubTypes(system)
-            val substitutor = createTypeSubstitutorByTypeConstructor(
-                typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
+            val substitutor = ChainedSubstitutor(
+                provideDelegateCandidate.substitutor,
+                (context.inferenceSession as FirDelegatedPropertyInferenceSession).currentConstraintStorage.buildCurrentSubstitutor(
+                    session.typeContext, emptyMap()
+                ) as ConeSubstitutor
             )
 
-            val stubTypeSubstituted = substitutor.substituteOrSelf(
-                provideDelegateCandidate.substitutor.substituteOrSelf(
-                    components.typeFromCallee(provideDelegateCall).type
-                )
-            )
+            val toTypeVariableSubstituted =
+                substitutor.substituteOrSelf(components.typeFromCallee(provideDelegateCall).type)
 
-            provideDelegateCall.replaceTypeRef(provideDelegateCall.typeRef.resolvedTypeFromPrototype(stubTypeSubstituted))
+            provideDelegateCall.replaceTypeRef(provideDelegateCall.typeRef.resolvedTypeFromPrototype(toTypeVariableSubstituted))
             return provideDelegateCall
         }
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
index a7f640b..98ea5a4 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt
@@ -393,12 +393,14 @@
     }
 
     override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement =
-        transformFunctionCallInternal(functionCall, data, provideDelegate = false)
+        transformFunctionCallInternal(functionCall, data, skipExplicitReceiverTransformation = false)
 
     internal fun transformFunctionCallInternal(
         functionCall: FirFunctionCall,
         data: ResolutionMode,
-        provideDelegate: Boolean,
+        // Currently, it's only `true` for provideDelegate calls, because delegateExpression is already resolved as that stage.
+        // See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression
+        skipExplicitReceiverTransformation: Boolean,
     ): FirStatement =
         whileAnalysing(session, functionCall) {
             val calleeReference = functionCall.calleeReference
@@ -420,16 +422,12 @@
             functionCall.transformAnnotations(transformer, data)
             functionCall.replaceLambdaArgumentInvocationKinds(session)
             functionCall.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
+
             val initialExplicitReceiver = functionCall.explicitReceiver
             val withTransformedArguments = if (!resolvingAugmentedAssignment) {
                 dataFlowAnalyzer.enterCallArguments(functionCall, functionCall.arguments)
-                // In provideDelegate mode the explicitReceiver is already resolved
-                // E.g. we have val some by someDelegate
-                // At 1st stage of delegate inference we resolve someDelegate itself,
-                // at 2nd stage in provideDelegate mode we are trying to resolve someDelegate.provideDelegate(),
-                // and 'someDelegate' explicit receiver is resolved at 1st stage
-                // See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression
-                val withResolvedExplicitReceiver = if (provideDelegate) functionCall else transformExplicitReceiver(functionCall)
+                val withResolvedExplicitReceiver =
+                    if (skipExplicitReceiverTransformation) functionCall else transformExplicitReceiver(functionCall)
                 withResolvedExplicitReceiver.also {
                     it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
                     dataFlowAnalyzer.exitCallArguments()
@@ -437,7 +435,12 @@
             } else {
                 functionCall
             }
-            val resultExpression = callResolver.resolveCallAndSelectCandidate(withTransformedArguments)
+
+
+
+            val resultExpression = context.inferenceSession.onCandidatesResolution(withTransformedArguments) {
+                callResolver.resolveCallAndSelectCandidate(withTransformedArguments)
+            }
             val resultExplicitReceiver = resultExpression.explicitReceiver?.unwrapSmartcastExpression()
             if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccessExpression) {
                 // name.invoke() case
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
index 4f725e3..37434e0 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt
@@ -27,6 +27,7 @@
         val fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>
         val postponedTypeVariables: List<TypeVariableMarker>
         val constraintsFromAllForkPoints: MutableList<Pair<IncorporationConstraintPosition, ForkPointData>>
+        val typeVariablesAreDisallowedForProperTypes: Set<TypeConstructorMarker>?
 
         fun isReified(variable: TypeVariableMarker): Boolean
     }
@@ -182,7 +183,13 @@
                 && !c.isNullabilityConstraint
 
     private fun Context.isProperType(type: KotlinTypeMarker): Boolean =
-        isProperTypeForFixation(type) { t -> !t.contains { notFixedTypeVariables.containsKey(it.typeConstructor()) } }
+        isProperTypeForFixation(type) { t -> !t.contains { isNotFixedRelevantVariable(it) } }
+
+    private fun Context.isNotFixedRelevantVariable(it: KotlinTypeMarker): Boolean {
+        if (!notFixedTypeVariables.containsKey(it.typeConstructor())) return false
+        if (typeVariablesAreDisallowedForProperTypes == null) return true
+        return typeVariablesAreDisallowedForProperTypes!!.contains(it.typeConstructor())
+    }
 
     private fun Context.isReified(variable: TypeConstructorMarker): Boolean =
         notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
index a47f80a..130b55b 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt
@@ -30,8 +30,7 @@
     ConstraintSystemBuilder,
     ConstraintInjector.Context,
     ResultTypeResolver.Context,
-    PostponedArgumentsAnalyzerContext
-{
+    PostponedArgumentsAnalyzerContext {
     private val utilContext = constraintInjector.constraintIncorporator.utilContext
 
     private val postponedComputationsAfterAllVariablesAreFixed = mutableListOf<() -> Unit>()
@@ -42,10 +41,29 @@
     private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
     private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
     private val intersectionTypesCache: MutableMap<Collection<KotlinTypeMarker>, EmptyIntersectionTypeInfo?> = mutableMapOf()
+    override var typeVariablesAreDisallowedForProperTypes: Set<TypeConstructorMarker>? = null
+
     private var couldBeResolvedWithUnrestrictedBuilderInference: Boolean = false
 
     override var atCompletionState: Boolean = false
 
+    fun withDisallowingOnlyThisTypeVariablesForProperTypes(typeVariables: Set<TypeConstructorMarker>, block: () -> Unit) {
+        properTypesCache.clear()
+        notProperTypesCache.clear()
+
+        require(typeVariablesAreDisallowedForProperTypes == null) {
+            "Currently there should be no nested withDisallowingOnlyThisTypeVariablesForProperTypes calls"
+        }
+
+        typeVariablesAreDisallowedForProperTypes = typeVariables
+
+        block()
+
+        typeVariablesAreDisallowedForProperTypes = null
+        properTypesCache.clear()
+        notProperTypesCache.clear()
+    }
+
     private enum class State {
         BUILDING,
         TRANSACTION,
@@ -149,7 +167,8 @@
         pathToExpectedType: List<Pair<TypeConstructorMarker, Int>>,
         builtFunctionalType: KotlinTypeMarker
     ) {
-        storage.builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables[topLevelVariable to pathToExpectedType] = builtFunctionalType
+        storage.builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables[topLevelVariable to pathToExpectedType] =
+            builtFunctionalType
     }
 
     override fun putBuiltFunctionalExpectedTypeForPostponedArgument(
@@ -317,6 +336,9 @@
                 it
 
             if (typeToCheck == null) return@contains false
+            if (typeVariablesAreDisallowedForProperTypes != null) {
+                return@contains typeVariablesAreDisallowedForProperTypes!!.contains(typeToCheck.typeConstructor())
+            }
 
             storage.allTypeVariables.containsKey(typeToCheck.typeConstructor())
         }