~
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/CompletionModeCalculator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/CompletionModeCalculator.kt
index f0fb598..5af8fe2 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/CompletionModeCalculator.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/CompletionModeCalculator.kt
@@ -24,6 +24,7 @@
     currentReturnType: ConeKotlinType?
 ): ConstraintSystemCompletionMode {
     return when {
+        resolutionMode == ResolutionMode.ContextDependentDelegate && !isSuccessful -> ConstraintSystemCompletionMode.FULL
         // Expected type is present or call is being resolved in independent context
         resolutionMode.forceFullCompletion -> ConstraintSystemCompletionMode.FULL
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
index ca16682..eba7b7f 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
@@ -383,10 +383,10 @@
             result.addAll(notFixedTypeVariables.filter { context.inferenceSession.isSyntheticTypeVariable(it.value.typeVariable) }.keys.asIterable())
         }
 
-        require(result.size == notFixedTypeVariables.size) {
-            val notFoundTypeVariables = notFixedTypeVariables.keys.toMutableSet().apply { removeAll(result) }
-            "Not all type variables found: $notFoundTypeVariables"
-        }
+//        require(result.size == notFixedTypeVariables.size) {
+//            val notFoundTypeVariables = notFixedTypeVariables.keys.toMutableSet().apply { removeAll(result) }
+//            "Not all type variables found: $notFoundTypeVariables"
+//        }
 
         return result.toList()
     }
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..4ed7db7 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
@@ -23,6 +23,7 @@
 import org.jetbrains.kotlin.fir.resolve.initialTypeOfCandidate
 import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
+import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
 import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
 import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher
 import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
@@ -33,7 +34,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
@@ -83,6 +83,12 @@
             call.replaceLambdaArgumentInvocationKinds(session)
         }
 
+        if (inferenceSession.skipCompletion(call, resolutionMode, completionMode)) {
+            // TODO: Consider regular `completionMode`
+            runCompletionForCall(candidate, ConstraintSystemCompletionMode.PARTIAL, call, initialType, analyzer)
+            return call
+        }
+
         return when (completionMode) {
             ConstraintSystemCompletionMode.FULL -> {
                 if (inferenceSession.shouldRunCompletion(call)) {
@@ -91,7 +97,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 +117,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 +210,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,
@@ -325,16 +325,23 @@
                 )
             }
 
-            transformer.context.withAnonymousFunctionTowerDataContext(lambdaArgument.symbol) {
+            val context: BodyResolveContext = transformer.context
+            context.withAnonymousFunctionTowerDataContext(lambdaArgument.symbol) {
                 if (builderInferenceSession != null) {
-                    transformer.context.withInferenceSession(builderInferenceSession) {
+                    context.withInferenceSession(builderInferenceSession) {
                         lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
                     }
                 } else {
-                    lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
+                    context.withInferenceSession(
+                        if (context.inferenceSession is FirDelegatedPropertyInferenceSession2) {
+                            FirInferenceSession.DEFAULT
+                        } else context.inferenceSession
+                    ) {
+                        lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef))
+                    }
                 }
             }
-            transformer.context.dropContextForAnonymousFunction(lambdaArgument)
+            context.dropContextForAnonymousFunction(lambdaArgument)
 
             val returnArguments = components.dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambdaArgument)
 
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession2.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession2.kt
new file mode 100644
index 0000000..8479b71
--- /dev/null
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession2.kt
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+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.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.inference.model.ConeFixVariableConstraintPosition
+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.resolve.calls.inference.ConstraintSystemBuilder
+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.components.TypeVariableDirectionCalculator
+import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
+import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
+import org.jetbrains.kotlin.types.model.TypeConstructorMarker
+import org.jetbrains.kotlin.types.model.TypeVariableMarker
+import org.jetbrains.kotlin.util.OperatorNameConventions
+
+class FirDelegatedPropertyInferenceSession2(
+    val property: FirProperty,
+    resolutionContext: ResolutionContext,
+    private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
+) : FirInferenceSessionForChainedResolve(resolutionContext) {
+
+    var currentConstraintSystem = components.session.inferenceComponents.createConstraintSystem()
+    override val currentConstraintStorage: ConstraintStorage
+        get() {
+            return currentConstraintSystem.currentStorage()
+        }
+
+    private val unitType: ConeClassLikeType = components.session.builtinTypes.unitType.type
+
+    override fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement {
+        // TODO
+    }
+
+    override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {
+        // TODO
+    }
+
+    override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true
+
+    override fun <T> skipCompletion(
+        call: T,
+        resolutionMode: ResolutionMode,
+        completionMode: ConstraintSystemCompletionMode
+    ): Boolean where T : FirResolvable, T : FirStatement {
+        if (!call.candidate.isSuccessful) return false
+        if (completionMode == ConstraintSystemCompletionMode.FULL && resolutionMode == ResolutionMode.ContextDependentDelegate) return false
+        if (resolutionMode == ResolutionMode.ContextDependentDelegate || call.isGetOrSetValueCallInAccessor()) {
+            partiallyResolvedCalls.add(call to call.candidate)
+            currentConstraintSystem = call.candidate.system
+            return true
+        }
+
+        return false
+    }
+
+    private fun <T> T.isGetOrSetValueCallInAccessor(): Boolean where T : FirResolvable, T : FirStatement {
+        if (this !is FirFunctionCall) return false
+        val name = calleeReference.name
+        if (name != OperatorNameConventions.GET_VALUE && name != OperatorNameConventions.SET_VALUE && name != OperatorNameConventions.PROVIDE_DELEGATE) return false
+
+        return origin == FirFunctionCallOrigin.Operator
+    }
+
+
+    override fun inferPostponedVariables(
+        lambda: ResolvedLambdaAtom,
+        constraintSystemBuilder: ConstraintSystemBuilder,
+        completionMode: ConstraintSystemCompletionMode
+    ): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
+
+    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)
+        )
+    }
+
+    fun fixSyntheticTypeVariableWithNotEnoughInformation2(
+        typeVariable: ConeTypeVariable,
+    ) {
+        currentConstraintSystem.fixVariable(
+            typeVariable,
+            components.session.inferenceComponents.resultTypeResolver.findResultType(
+                currentConstraintSystem, currentConstraintSystem.notFixedTypeVariables[typeVariable.typeConstructor]!!,
+                TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN,
+            ),
+            ConeFixVariableConstraintPosition(typeVariable)
+        )
+    }
+
+    fun completeCandidates(): List<FirResolvable> {
+        val commonSystem = currentConstraintSystem
+
+        val notCompletedCalls = partiallyResolvedCalls.mapNotNull { partiallyResolvedCall ->
+            partiallyResolvedCall.first.takeIf { resolvable ->
+                resolvable.candidate() != null
+            }
+        }
+
+        resolutionContext.bodyResolveContext.withInferenceSession(DEFAULT) {
+            @Suppress("UNCHECKED_CAST")
+            components.callCompleter.completer.complete(
+                commonSystem.asConstraintSystemCompleterContext(),
+                ConstraintSystemCompletionMode.FULL,
+                notCompletedCalls as List<FirStatement>,
+                unitType, resolutionContext
+            ) { lambdaAtom ->
+                // Reversed here bc we want top-most call to avoid exponential visit
+                val containingCandidateForLambda = notCompletedCalls.asReversed().first {
+                    var found = false
+                    it.processAllContainingCallCandidates(processBlocks = true) { subCandidate ->
+                        if (subCandidate.postponedAtoms.contains(lambdaAtom)) {
+                            found = true
+                        }
+                    }
+                    found
+                }.candidate
+                postponedArgumentsAnalyzer.analyze(
+                    commonSystem,
+                    lambdaAtom,
+                    containingCandidateForLambda,
+                    ConstraintSystemCompletionMode.FULL,
+                )
+            }
+        }
+
+        for ((_, candidate) in partiallyResolvedCalls) {
+            for (error in commonSystem.errors) {
+                candidate.addDiagnostic(InferenceError(error))
+            }
+        }
+
+        return notCompletedCalls
+    }
+
+    fun createFinalSubstitutor(): ConeSubstitutor {
+        val typeContext = components.session.typeContext
+        val t = currentConstraintSystem.asReadOnlyStorage()
+            .buildAbstractResultingSubstitutor(typeContext) as ConeSubstitutor
+
+        return ChainedSubstitutor(t, t)
+    }
+
+    override fun hasSyntheticTypeVariables(): Boolean = false
+
+    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..ccbbfd2 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
@@ -7,6 +7,7 @@
 
 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
@@ -26,6 +27,11 @@
     }
 
     abstract fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement
+    open fun <T> skipCompletion(
+        call: T,
+        resolutionMode: ResolutionMode,
+        completionMode: ConstraintSystemCompletionMode
+    ): Boolean where T : FirResolvable, T : FirStatement = false
     abstract val currentConstraintStorage: ConstraintStorage
 
     abstract fun <T> addPartiallyResolvedCall(call: T) 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 075e3eb..4064b2a 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
@@ -31,7 +31,9 @@
 import org.jetbrains.kotlin.fir.resolve.inference.ResolvedLambdaAtom
 import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 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
@@ -58,13 +60,14 @@
 
 class FirCallCompletionResultsWriterTransformer(
     override val session: FirSession,
+    private val scopeSession: ScopeSession,
     private val finalSubstitutor: ConeSubstitutor,
     private val typeCalculator: ReturnTypeCalculator,
     private val typeApproximator: ConeTypeApproximator,
     private val dataFlowAnalyzer: FirDataFlowAnalyzer,
     private val integerOperatorApproximator: IntegerLiteralAndOperatorApproximationTransformer,
     private val context: BodyResolveContext,
-    private val mode: Mode = Mode.Normal
+    private val mode: Mode = Mode.Normal,
 ) : FirAbstractTreeTransformer<ExpectedArgumentType?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
 
     private fun finallySubstituteOrNull(type: ConeKotlinType): ConeKotlinType? {
@@ -98,7 +101,7 @@
     }
 
     private fun <T : FirQualifiedAccessExpression> prepareQualifiedTransform(
-        qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate
+        qualifiedAccessExpression: T, calleeReference: FirNamedReferenceWithCandidate,
     ): T {
         val subCandidate = calleeReference.candidate
         val declaration = subCandidate.symbol.fir
@@ -134,6 +137,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()) {
@@ -174,13 +183,7 @@
         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,17 +193,12 @@
         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
     }
 
     override fun transformPropertyAccessExpression(
         propertyAccessExpression: FirPropertyAccessExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return transformQualifiedAccessExpression(propertyAccessExpression, data)
     }
@@ -238,15 +236,32 @@
             }
         }
         val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
+
+        val resolvedArgumentMapping = result.resolvedArgumentMapping
+        if (subCandidate.symbol is FirNamedFunctionSymbol && resolvedArgumentMapping != null && subCandidate.symbol != result.toResolvedCallableSymbol()) {
+            val oldParameters = subCandidate.symbol.fir.valueParameters
+            val newValueParameters = (result.toResolvedCallableSymbol() as FirNamedFunctionSymbol).fir.valueParameters
+
+            val toMap = oldParameters.zip(newValueParameters).toMap()
+
+            result.replaceArgumentList(
+                buildResolvedArgumentList(
+                    resolvedArgumentMapping.mapValuesTo(linkedMapOf()) {
+                        toMap[it.value]!!
+                    }
+                )
+            )
+        }
+
         result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
         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 (mode == Mode.DelegatedPropertyCompletion) {
+//            val typeUpdater = TypeUpdaterForDelegateArguments()
+//            result.argumentList.transformArguments(typeUpdater, null)
+//            result.transformExplicitReceiver(typeUpdater, null)
+//        }
 
         if (enableArrayOfCallTransformation) {
             return arrayOfCallTransformer.transformFunctionCall(result, session)
@@ -264,7 +279,7 @@
 
     override fun transformAnnotationCall(
         annotationCall: FirAnnotationCall,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         val calleeReference = annotationCall.calleeReference as? FirNamedReferenceWithCandidate ?: return annotationCall
         annotationCall.replaceCalleeReference(calleeReference.toResolvedReference())
@@ -348,7 +363,7 @@
 
     override fun transformSafeCallExpression(
         safeCallExpression: FirSafeCallExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         safeCallExpression.transformSelector(
             this,
@@ -410,7 +425,7 @@
 
         override fun transformQualifiedAccessExpression(
             qualifiedAccessExpression: FirQualifiedAccessExpression,
-            data: Any?
+            data: Any?,
         ): FirStatement {
             val originalType = qualifiedAccessExpression.typeRef.coneType
             val substitutedReceiverType = finallySubstituteOrNull(originalType) ?: return qualifiedAccessExpression
@@ -487,7 +502,7 @@
 
     private fun computeTypeArguments(
         access: FirQualifiedAccessExpression,
-        candidate: Candidate
+        candidate: Candidate,
     ): List<FirTypeProjection> {
         val typeArguments = computeTypeArgumentTypes(candidate)
             .mapIndexed { index, type ->
@@ -540,7 +555,7 @@
 
     override fun transformAnonymousFunctionExpression(
         anonymousFunctionExpression: FirAnonymousFunctionExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return anonymousFunctionExpression.transformAnonymousFunction(this, data)
     }
@@ -623,7 +638,7 @@
     }
 
     private fun transformImplicitTypeRefInAnonymousFunction(
-        anonymousFunction: FirAnonymousFunction
+        anonymousFunction: FirAnonymousFunction,
     ): FirStatement {
         val implicitTypeTransformer = object : FirDefaultTransformer<Any?>() {
             override fun <E : FirElement> transformElement(element: E, data: Any?): E {
@@ -633,7 +648,7 @@
 
             override fun transformImplicitTypeRef(
                 implicitTypeRef: FirImplicitTypeRef,
-                data: Any?
+                data: Any?,
             ): FirTypeRef =
                 buildErrorTypeRef {
                     source = implicitTypeRef.source
@@ -651,7 +666,7 @@
 
     override fun transformReturnExpression(
         returnExpression: FirReturnExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         val labeledElement = returnExpression.target.labeledElement
         if (labeledElement is FirAnonymousFunction) {
@@ -668,7 +683,8 @@
             val finalType = finallySubstituteOrNull(initialType)
             var resultType = block.resultType.withReplacedConeType(finalType)
             resultType.coneTypeSafe<ConeIntegerLiteralType>()?.let {
-                resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session)))
+                resultType =
+                    resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session)))
             }
             block.replaceTypeRef(resultType)
             session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source)
@@ -684,28 +700,28 @@
 
     override fun transformWhenExpression(
         whenExpression: FirWhenExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return transformSyntheticCall(whenExpression, data)
     }
 
     override fun transformTryExpression(
         tryExpression: FirTryExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return transformSyntheticCall(tryExpression, data)
     }
 
     override fun transformCheckNotNullCall(
         checkNotNullCall: FirCheckNotNullCall,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return transformSyntheticCall(checkNotNullCall, data)
     }
 
     override fun transformElvisExpression(
         elvisExpression: FirElvisExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         return transformSyntheticCall(elvisExpression, data)
     }
@@ -733,7 +749,7 @@
 
     private inline fun <reified D> transformSyntheticCallChildren(
         syntheticCall: D,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ) where D : FirResolvable, D : FirExpression {
         val newData = data?.getExpectedType(syntheticCall)?.toExpectedType() ?: syntheticCall.typeRef.coneType.toExpectedType()
 
@@ -764,7 +780,7 @@
 
     override fun transformIntegerLiteralOperatorCall(
         integerLiteralOperatorCall: FirIntegerLiteralOperatorCall,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         if (data == ExpectedArgumentType.NoApproximation) return integerLiteralOperatorCall
         val expectedType = data?.getExpectedType(integerLiteralOperatorCall)
@@ -792,7 +808,7 @@
 
     override fun transformVarargArgumentsExpression(
         varargArgumentsExpression: FirVarargArgumentsExpression,
-        data: ExpectedArgumentType?
+        data: ExpectedArgumentType?,
     ): FirStatement {
         val expectedType = data?.getExpectedType(varargArgumentsExpression)?.let { ExpectedArgumentType.ExpectedType(it) }
         varargArgumentsExpression.transformChildren(this, expectedType)
@@ -820,14 +836,35 @@
             else -> null
         }
 
-        return when (errorDiagnostic) {
-            null -> buildResolvedNamedReference {
-                source = this@toResolvedReference.source
-                name = this@toResolvedReference.name
-                resolvedSymbol = this@toResolvedReference.candidateSymbol
-            }
+        if (errorDiagnostic != null) return toErrorReference(errorDiagnostic)
 
-            else -> toErrorReference(errorDiagnostic)
+        return buildResolvedNamedReference {
+            source = this@toResolvedReference.source
+            name = this@toResolvedReference.name
+            resolvedSymbol = this@toResolvedReference.candidateSymbol.refineSubstitution()
+        }
+    }
+
+    private fun FirBasedSymbol<*>.refineSubstitution(): FirBasedSymbol<*> {
+        val fir = fir
+        if (fir !is FirCallableDeclaration) return this
+
+        val dispatchReceiverType = fir.dispatchReceiverType ?: return this
+        val updatedDispatchReceiverType = finalSubstitutor.substituteOrNull(dispatchReceiverType) ?: return this
+
+        val scope =
+            updatedDispatchReceiverType.scope(
+                session,
+                scopeSession,
+                FakeOverrideTypeCalculator.DoNothing,
+                FirResolvePhase.STATUS
+            ) as? FirClassSubstitutionScope ?: return this
+
+
+        return when (val original = fir.originalForSubstitutionOverride) {
+            is FirSimpleFunction -> scope.createSubstitutionOverrideFunction(original.symbol)
+            is FirProperty -> scope.createSubstitutionOverrideProperty(original.symbol)
+            else -> error("!!!")
         }
     }
 }
@@ -835,7 +872,7 @@
 sealed class ExpectedArgumentType {
     class ArgumentsMap(
         val map: Map<FirElement, ConeKotlinType>,
-        val lambdasReturnTypes: Map<FirAnonymousFunction, ConeKotlinType>
+        val lambdasReturnTypes: Map<FirAnonymousFunction, ConeKotlinType>,
     ) : ExpectedArgumentType()
 
     class ExpectedType(val type: ConeKotlinType) : ExpectedArgumentType()
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..e1a20cc 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
@@ -22,7 +22,7 @@
 import org.jetbrains.kotlin.fir.resolve.dfa.DataFlowAnalyzerContext
 import org.jetbrains.kotlin.fir.resolve.inference.FirBuilderInferenceSession
 import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter
-import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession
+import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession2
 import org.jetbrains.kotlin.fir.resolve.inference.FirInferenceSession
 import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
 import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup
@@ -818,9 +818,9 @@
         property: FirProperty,
         resolutionContext: ResolutionContext,
         callCompleter: FirCallCompleter,
-        f: FirDelegatedPropertyInferenceSession.() -> T
+        f: FirDelegatedPropertyInferenceSession2.() -> T
     ) {
-        val inferenceSession = FirDelegatedPropertyInferenceSession(
+        val inferenceSession = FirDelegatedPropertyInferenceSession2(
             property,
             resolutionContext,
             callCompleter.createPostponedArgumentsAnalyzer(resolutionContext)
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..cf6671c7 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.FirDelegatedPropertyInferenceSession2
 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,8 @@
 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
+import org.jetbrains.kotlin.types.model.TypeConstructorMarker
 
 open class FirDeclarationsResolveTransformer(
     transformer: FirAbstractBodyResolveTransformerDispatcher
@@ -288,6 +292,7 @@
 
             val finalSubstitutor = createFinalSubstitutor()
 
+            // TODO: Replace just property/accessors return types instead
             val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor)
             property.transformSingle(stubTypeCompletionResultsWriter, null)
             property.replaceReturnTypeRef(
@@ -334,18 +339,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 +353,37 @@
         // 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 inferenceSession = context.inferenceSession as FirDelegatedPropertyInferenceSession2
+
+            inferenceSession.currentConstraintSystem.clearCaches()
+            val innerSet = provideDelegateCandidate.freshVariables.mapTo(mutableSetOf()) { it.typeConstructor }
+            @Suppress("UNCHECKED_CAST")
+            inferenceSession.currentConstraintSystem.innerTypes = innerSet as MutableSet<TypeConstructorMarker>
+
+            provideDelegateCandidate.freshVariables.forEach {
+                inferenceSession.fixSyntheticTypeVariableWithNotEnoughInformation2(it)
             }
-            val typeVariableTypeToStubType = context.inferenceSession.createSyntheticStubTypes(system)
-            val substitutor = createTypeSubstitutorByTypeConstructor(
-                typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
+
+            inferenceSession.currentConstraintSystem.clearCaches()
+            inferenceSession.currentConstraintSystem.innerTypes = null
+
+            val substitutor = ChainedSubstitutor(
+                provideDelegateCandidate.substitutor,
+                context.inferenceSession.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..5ac35ff 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
@@ -29,6 +29,8 @@
 import org.jetbrains.kotlin.fir.resolve.*
 import org.jetbrains.kotlin.fir.resolve.calls.*
 import org.jetbrains.kotlin.fir.resolve.diagnostics.*
+import org.jetbrains.kotlin.fir.resolve.inference.FirDelegatedPropertyInferenceSession2
+import org.jetbrains.kotlin.fir.resolve.inference.FirInferenceSession
 import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
 import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
 import org.jetbrains.kotlin.fir.resolve.transformers.replaceLambdaArgumentInvocationKinds
@@ -393,12 +395,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,19 +424,21 @@
             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 initialExplicitReceiver = functionCall.explicitReceiver
+                    val withTransformedArguments = if (!resolvingAugmentedAssignment) {
+                        dataFlowAnalyzer.enterCallArguments(functionCall, functionCall.arguments)
+                        val withResolvedExplicitReceiver =
+                            if (skipExplicitReceiverTransformation) functionCall else transformExplicitReceiver(functionCall)
                 withResolvedExplicitReceiver.also {
-                    it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
-                    dataFlowAnalyzer.exitCallArguments()
+                    context.withInferenceSession(
+                                if (context.inferenceSession is FirDelegatedPropertyInferenceSession2) {
+                                    FirInferenceSession.DEFAULT
+                                } else context.inferenceSession
+                            ) {
+                                it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
+                                dataFlowAnalyzer.exitCallArguments()
+                            }
                 }
             } else {
                 functionCall
@@ -1235,18 +1241,20 @@
         annotationCall: FirAnnotationCall,
         data: ResolutionMode
     ): FirStatement = whileAnalysing(session, annotationCall) {
-        if (annotationCall.resolved) return annotationCall
-        annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent)
-        annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.Types)
-        return context.forAnnotation {
-            withFirArrayOfCallTransformer {
-                dataFlowAnalyzer.enterAnnotation()
-                val result = callResolver.resolveAnnotationCall(annotationCall)
-                dataFlowAnalyzer.exitAnnotation()
-                if (result == null) return annotationCall
-                callCompleter.completeCall(result, ResolutionMode.ContextIndependent)
-                (result.argumentList as FirResolvedArgumentList).let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
-                annotationCall
+        context.withInferenceSession(FirInferenceSession.DEFAULT) {
+            if (annotationCall.resolved) return annotationCall
+            annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent)
+            annotationCall.replaceAnnotationResolvePhase(FirAnnotationResolvePhase.Types)
+            context.forAnnotation {
+                withFirArrayOfCallTransformer {
+                    dataFlowAnalyzer.enterAnnotation()
+                    val result = callResolver.resolveAnnotationCall(annotationCall)
+                    dataFlowAnalyzer.exitAnnotation()
+                    if (result == null) return annotationCall
+                    callCompleter.completeCall(result, ResolutionMode.ContextIndependent)
+                    (result.argumentList as FirResolvedArgumentList).let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
+                    annotationCall
+                }
             }
         }
     }
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..692cc28 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
@@ -44,8 +44,15 @@
     private val intersectionTypesCache: MutableMap<Collection<KotlinTypeMarker>, EmptyIntersectionTypeInfo?> = mutableMapOf()
     private var couldBeResolvedWithUnrestrictedBuilderInference: Boolean = false
 
+    var innerTypes: MutableSet<TypeConstructorMarker>? = null
+
     override var atCompletionState: Boolean = false
 
+    fun clearCaches() {
+        properTypesCache.clear()
+        notProperTypesCache.clear()
+    }
+
     private enum class State {
         BUILDING,
         TRANSACTION,
@@ -317,6 +324,9 @@
                 it
 
             if (typeToCheck == null) return@contains false
+            if (innerTypes != null) {
+                return@contains innerTypes!!.contains(typeToCheck.typeConstructor())
+            }
 
             storage.allTypeVariables.containsKey(typeToCheck.typeConstructor())
         }