[FIR] Declarations in conditionals, prototype
diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt
index 5b16d6d..90ab745 100644
--- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt
+++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt
@@ -19,6 +19,7 @@
 import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
 import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
 import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
+import org.jetbrains.kotlin.fir.expressions.FirVariableInConditionalExpression
 import org.jetbrains.kotlin.fir.resolve.providers.firProvider
 import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
 import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -116,6 +117,7 @@
     private fun findDeclarationInSourceViaResolve(ktDeclaration: KtExpression): FirBasedSymbol<*> {
         val firDeclaration = when (val fir = getOrBuildFirFor(ktDeclaration)) {
             is FirDeclaration -> fir
+            is FirVariableInConditionalExpression -> fir.declaration
             is FirAnonymousFunctionExpression -> fir.anonymousFunction
             is FirAnonymousObjectExpression -> fir.anonymousObject
             else -> errorWithFirSpecificEntries(
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java
index 910b253..b713e39 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java
@@ -159,6 +159,12 @@
     }
 
     @Test
+    @TestMetadata("DeclarationsInConditionals.kt")
+    public void testDeclarationsInConditionals() {
+      runTest("compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt");
+    }
+
+    @Test
     @TestMetadata("defaultJavaImportHiding.kt")
     public void testDefaultJavaImportHiding() {
       runTest("compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt");
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java
index b18966c..a75d677 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java
@@ -159,6 +159,12 @@
     }
 
     @Test
+    @TestMetadata("DeclarationsInConditionals.kt")
+    public void testDeclarationsInConditionals() {
+      runTest("compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt");
+    }
+
+    @Test
     @TestMetadata("defaultJavaImportHiding.kt")
     public void testDefaultJavaImportHiding() {
       runTest("compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt");
diff --git a/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.fir.txt b/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.fir.txt
new file mode 100644
index 0000000..389d2d8
--- /dev/null
+++ b/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.fir.txt
@@ -0,0 +1,92 @@
+FILE: DeclarationsInConditionals.kt
+    public open class Developer : R|kotlin/Any| {
+        public constructor(): R|Developer| {
+            super<R|kotlin/Any|>()
+        }
+
+    }
+    public final class Person : R|Developer| {
+        public constructor(name: R|kotlin/String|): R|Person| {
+            super<R|Developer|>()
+        }
+
+        public final val name: R|kotlin/String| = R|<local>/name|
+            public get(): R|kotlin/String|
+
+    }
+    public final class Company : R|Developer| {
+        public constructor(legalName: R|kotlin/String|, cto: R|Person|): R|Company| {
+            super<R|Developer|>()
+        }
+
+        public final val legalName: R|kotlin/String| = R|<local>/legalName|
+            public get(): R|kotlin/String|
+
+        public final val cto: R|Person| = R|<local>/cto|
+            public get(): R|Person|
+
+    }
+    public sealed class Download : R|kotlin/Any| {
+        protected constructor(): R|Download| {
+            super<R|kotlin/Any|>()
+        }
+
+    }
+    public final data class App : R|Download| {
+        public constructor(title: R|kotlin/String|, developer: R|Developer|): R|App| {
+            super<R|Download|>()
+        }
+
+        public final val title: R|kotlin/String| = R|<local>/title|
+            public get(): R|kotlin/String|
+
+        public final val developer: R|Developer| = R|<local>/developer|
+            public get(): R|Developer|
+
+        public final operator fun component1(): R|kotlin/String|
+
+        public final operator fun component2(): R|Developer|
+
+        public final fun copy(title: R|kotlin/String| = this@R|/App|.R|/App.title|, developer: R|Developer| = this@R|/App|.R|/App.developer|): R|App|
+
+    }
+    public final data class Movie : R|Download| {
+        public constructor(title: R|kotlin/String|, director: R|Person|): R|Movie| {
+            super<R|Download|>()
+        }
+
+        public final val title: R|kotlin/String| = R|<local>/title|
+            public get(): R|kotlin/String|
+
+        public final val director: R|Person| = R|<local>/director|
+            public get(): R|Person|
+
+        public final operator fun component1(): R|kotlin/String|
+
+        public final operator fun component2(): R|Person|
+
+        public final fun copy(title: R|kotlin/String| = this@R|/Movie|.R|/Movie.title|, director: R|Person| = this@R|/Movie|.R|/Movie.director|): R|Movie|
+
+    }
+    public final fun f(download: R|Download|): R|kotlin/String| {
+        ^f when () {
+            (R|<local>/download| is R|App|) && lval <destruct>: R|Download| = R|<local>/download| && lval title: R|kotlin/String| = R|<local>/<destruct>|.R|/App.component1|() && lval developer: R|Developer| = R|<local>/<destruct>|.R|/App.component2|() && (R|<local>/developer| is R|Person|) && ==(R|<local>/developer|.R|/Person.name|, String(Alice)) ->  {
+                <strcat>(R|<local>/title|, String( in Wonderland))
+            }
+            else ->  {
+                String(Boo)
+            }
+        }
+
+    }
+    public final fun g(download: R|Download|): R|kotlin/String| {
+        ^g when () {
+            lval <isDestructor>: R|Download| = R|<local>/download| && (R|<local>/<isDestructor>| is R|App|) && lval title: R|kotlin/String| = R|<local>/<isDestructor>|.R|/App.component1|() && lval developer: R|Developer| = R|<local>/<isDestructor>|.R|/App.component2|() && (R|<local>/developer| is R|Person|) && ==(R|<local>/developer|.R|/Person.name|, String(Alice)) ->  {
+                <strcat>(R|<local>/title|, String( in Wonderland))
+            }
+            else ->  {
+                String(Boo)
+            }
+        }
+
+    }
diff --git a/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt b/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt
new file mode 100644
index 0000000..8625b17
--- /dev/null
+++ b/compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt
@@ -0,0 +1,22 @@
+open class Developer
+class Person(val name: String) : Developer()
+class Company(val legalName: String, val cto: Person) : Developer()
+
+sealed class Download
+data class App(val title: String, val developer: Developer) : Download()
+data class Movie(val title: String, val director: Person) : Download()
+
+fun f(download: Download) = when {
+  download is App
+    && val (title, developer) = download
+    && developer is Person
+    && developer.name == "Alice" -> "$title in Wonderland"
+  else -> "Boo"
+}
+
+fun g(download: Download) = when {
+  download is App (title, developer)
+    && developer is Person
+    && developer.name == "Alice" -> "$title in Wonderland"
+  else -> "Boo"
+}
diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java
index af16b67..f7626e6 100644
--- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java
+++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java
@@ -159,6 +159,12 @@
     }
 
     @Test
+    @TestMetadata("DeclarationsInConditionals.kt")
+    public void testDeclarationsInConditionals() {
+      runTest("compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt");
+    }
+
+    @Test
     @TestMetadata("defaultJavaImportHiding.kt")
     public void testDefaultJavaImportHiding() {
       runTest("compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt");
diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java
index 4e1d46c..ef70e04 100644
--- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java
+++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java
@@ -159,6 +159,12 @@
     }
 
     @Test
+    @TestMetadata("DeclarationsInConditionals.kt")
+    public void testDeclarationsInConditionals() {
+      runTest("compiler/fir/analysis-tests/testData/resolve/DeclarationsInConditionals.kt");
+    }
+
+    @Test
     @TestMetadata("defaultJavaImportHiding.kt")
     public void testDefaultJavaImportHiding() {
       runTest("compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt");
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt
index ca272b7..09589ab 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt
@@ -113,6 +113,13 @@
         checkers.allWhenExpressionCheckers.check(whenExpression, data)
     }
 
+    override fun visitVariableInConditionalExpression(
+        variableInConditionalExpression: FirVariableInConditionalExpression,
+        data: CheckerContext
+    ) {
+        checkers.allBasicExpressionCheckers.check(variableInConditionalExpression, data)
+    }
+
     override fun visitWhileLoop(whileLoop: FirWhileLoop, data: CheckerContext) {
         checkers.allWhileLoopCheckers.check(whileLoop, data)
     }
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
index df78952..224ac56 100644
--- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
+++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirDeclarationBuilder.kt
@@ -1270,7 +1270,7 @@
     /**
      * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseProperty
      */
-    fun convertPropertyDeclaration(property: LighterASTNode, classWrapper: ClassWrapper? = null): FirDeclaration {
+    fun convertPropertyDeclaration(property: LighterASTNode, classWrapper: ClassWrapper? = null): FirVariable {
         var modifiers: Modifier? = null
         val propertyAnnotations = mutableListOf<FirAnnotationCall>()
         var identifier: String? = null
diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt
index 66b7d7e..2b6dc57 100644
--- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt
+++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/LightTreeRawFirExpressionBuilder.kt
@@ -30,6 +30,7 @@
 import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
 import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
 import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
+import org.jetbrains.kotlin.fir.lightTree.fir.DestructuringEntry
 import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
 import org.jetbrains.kotlin.fir.lightTree.fir.WhenEntry
 import org.jetbrains.kotlin.fir.lightTree.fir.addDestructuringStatements
@@ -106,8 +107,42 @@
             BINARY_WITH_TYPE -> convertBinaryWithTypeRHSExpression(expression) {
                 this.getOperationSymbol().toFirOperation()
             }
-            IS_EXPRESSION -> convertBinaryWithTypeRHSExpression(expression) {
-                if (this == "is") FirOperation.IS else FirOperation.NOT_IS
+            IS_EXPRESSION -> {
+                val destructuringEntries = expression.getChildNodesByType(KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY)
+                when {
+                    destructuringEntries.isNullOrEmpty() -> convertBinaryWithTypeRHSExpression(expression) {
+                        if (this == "is") FirOperation.IS else FirOperation.NOT_IS
+                    }
+                    else -> {
+                        lateinit var operationTokenName: String
+                        var leftArgAsFir: FirExpression? = null
+                        lateinit var firType: FirTypeRef
+                        expression.forEachChildren {
+                            when (it.tokenType) {
+                                OPERATION_REFERENCE -> operationTokenName = it.asText
+                                TYPE_REFERENCE -> firType = declarationBuilder.convertType(it)
+                                else ->
+                                    if (it.isExpression() && it.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY)
+                                        leftArgAsFir = getAsFirExpression(it, "No left operand")
+                            }
+                        }
+                        val entries = declarationBuilder.convertDestructingDeclaration(expression)
+                        buildIsDestructuring(
+                            baseModuleData,
+                            expression.toFirSourceElement(),
+                            DestructuringEntry,
+                            leftArgAsFir!!,
+                            entries.entries,
+                        ) {
+                            buildTypeOperatorCall {
+                                source = expression.toFirSourceElement()
+                                operation = if (operationTokenName == "is") FirOperation.IS else FirOperation.NOT_IS
+                                conversionTypeRef = firType
+                                argumentList = buildUnaryArgumentList(it)
+                            }
+                        }
+                    }
+                }
             }
             LABELED_EXPRESSION -> convertLabeledExpression(expression)
             PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
@@ -142,8 +177,24 @@
 
             OBJECT_LITERAL -> declarationBuilder.convertObjectLiteral(expression)
             FUN -> declarationBuilder.convertFunctionDeclaration(expression)
-            DESTRUCTURING_DECLARATION -> declarationBuilder.convertDestructingDeclaration(expression)
-                .toFirDestructingDeclaration(this, baseModuleData)
+            DESTRUCTURING_DECLARATION -> {
+                val block = declarationBuilder.convertDestructingDeclaration(expression)
+                    .toFirDestructingDeclaration(this, baseModuleData)
+                if (block is FirBlock && block.statements.all { it is FirVariable }) {
+                    block.statements.filterIsInstance<FirVariable>().map<_, FirExpression> {
+                        buildVariableInConditionalExpression {
+                            declaration = it
+                            source = it.source?.realElement()
+                        }
+                    }.reduce { acc, next -> acc.generateLazyLogicalOperation(next, isAnd = true, null) }
+                } else block
+            }
+            PROPERTY -> declarationBuilder.convertPropertyDeclaration(expression).let { property ->
+                buildVariableInConditionalExpression {
+                    declaration = property
+                    source = property.source?.realElement()
+                }
+            }
             else -> buildErrorExpression(
                 expression.toFirSourceElement(KtFakeSourceElementKind.ErrorTypeRef),
                 ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected)
diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt
index 1f02378..2b788da 100644
--- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt
+++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt
@@ -165,3 +165,27 @@
         configure
     )
 }
+
+internal fun AbstractRawFirBuilder<*>.addDestructuringVariables(
+    destination: MutableList<in FirVariable>,
+    c: DestructuringContext<KtDestructuringDeclarationEntry>,
+    moduleData: FirModuleData,
+    entries: List<KtDestructuringDeclarationEntry>,
+    isVar: Boolean,
+    container: FirVariable,
+    tmpVariable: Boolean,
+    forceLocal: Boolean,
+    configure: (FirVariable) -> Unit = {}
+) {
+    addDestructuringVariables(
+        destination,
+        c,
+        moduleData,
+        container,
+        entries,
+        isVar,
+        tmpVariable,
+        forceLocal,
+        configure
+    )
+}
diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt
index dd77f18..fa99ca9 100644
--- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt
+++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt
@@ -312,6 +312,20 @@
 
             return when (val fir = convertElement(this, null)) {
                 is FirExpression -> when {
+                    fir is FirBlock && fir.statements.isNotEmpty() && fir.statements.all { it is FirVariable } -> {
+                        fir.statements.filterIsInstance<FirVariable>().map<_, FirExpression> {
+                            buildVariableInConditionalExpression {
+                                declaration = it
+                                source = it.source
+                            }
+                        }.reduce { acc, next ->
+                            acc.generateLazyLogicalOperation(
+                                next,
+                                isAnd = true,
+                                toFirSourceElement(KtFakeSourceElementKind.WhenCondition)
+                            )
+                        }
+                    }
                     isValidExpression(fir) -> checkSelectorInvariant(fir)
                     else -> buildErrorExpression {
                         nonExpressionElement = fir
@@ -319,10 +333,16 @@
                         source = sourceWhenInvalidExpression?.toFirSourceElement()
                     }
                 }
-                else -> buildErrorExpression {
-                    nonExpressionElement = fir
-                    diagnostic = diagnosticFn()
-                    source = fir?.source?.realElement() ?: toFirSourceElement()
+                else -> when {
+                    fir is FirVariable -> buildVariableInConditionalExpression {
+                        declaration = fir
+                        source = fir.source
+                    }
+                    else -> buildErrorExpression {
+                        nonExpressionElement = fir
+                        diagnostic = diagnosticFn()
+                        source = fir?.source?.realElement() ?: toFirSourceElement()
+                    }
                 }
             }
         }
@@ -2934,14 +2954,30 @@
             }
         }
 
-        override fun visitIsExpression(expression: KtIsExpression, data: FirElement?): FirElement {
-            return buildTypeOperatorCall {
-                source = expression.toFirSourceElement()
-                operation = if (expression.isNegated) FirOperation.NOT_IS else FirOperation.IS
-                conversionTypeRef = expression.typeReference.toFirOrErrorType()
-                argumentList = buildUnaryArgumentList(expression.leftHandSide.toFirExpression("No left operand"))
+        override fun visitIsExpression(expression: KtIsExpression, data: FirElement?): FirElement =
+            if (expression.destructuringEntries.isNullOrEmpty()) {
+                buildTypeOperatorCall {
+                    source = expression.toFirSourceElement()
+                    operation = if (expression.isNegated) FirOperation.NOT_IS else FirOperation.IS
+                    conversionTypeRef = expression.typeReference.toFirOrErrorType()
+                    argumentList = buildUnaryArgumentList(expression.leftHandSide.toFirExpression("No left operand"))
+                }
+            } else {
+                buildIsDestructuring(
+                    baseModuleData,
+                    expression.toFirSourceElement(),
+                    this@Visitor,
+                    expression.leftHandSide.toFirExpression { ConeSyntaxDiagnostic("Initializer required for destructuring declaration") },
+                    expression.destructuringEntries!!
+                ) {
+                    buildTypeOperatorCall {
+                        source = expression.toFirSourceElement()
+                        operation = if (expression.isNegated) FirOperation.NOT_IS else FirOperation.IS
+                        conversionTypeRef = expression.typeReference.toFirOrErrorType()
+                        argumentList = buildUnaryArgumentList(it)
+                    }
+                }
             }
-        }
 
         override fun visitUnaryExpression(expression: KtUnaryExpression, data: FirElement?): FirElement {
             val operationToken = expression.operationToken
diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt
index da3a7f2..4ec8590 100644
--- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt
+++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt
@@ -18,6 +18,12 @@
 import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
 import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
 import org.jetbrains.kotlin.fir.expressions.FirExpression
+import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
+import org.jetbrains.kotlin.fir.expressions.builder.buildBlock
+import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
+import org.jetbrains.kotlin.fir.expressions.builder.buildVariableInConditionalExpression
+import org.jetbrains.kotlin.fir.generateTemporaryVariable
+import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
 import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
 import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
 import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -100,3 +106,58 @@
         }
     }.also(configure)
 }
+
+fun <T> AbstractRawFirBuilder<*>.buildIsDestructuring(
+    moduleData: FirModuleData,
+    originalSource: KtSourceElement?,
+    c: DestructuringContext<T>,
+    leftHandSide: FirExpression,
+    destructuringEntries: List<T>,
+    buildTypeOperator: (FirExpression) -> FirTypeOperatorCall
+): FirExpression {
+    val baseVariable = generateTemporaryVariable(
+        moduleData,
+        originalSource,
+        Name.special("<isDestructor>"),
+        leftHandSide
+    )
+    val wrappedBaseVariable =
+        buildVariableInConditionalExpression {
+            declaration = baseVariable
+            source = baseVariable.source
+        }
+    val variableAccess = buildPropertyAccessExpression {
+        calleeReference = buildResolvedNamedReference {
+            name = baseVariable.name
+            resolvedSymbol = baseVariable.symbol
+        }
+        source = originalSource
+    }
+    val typeOperator = buildTypeOperator(variableAccess)
+    val block = buildBlock {
+        addDestructuringVariables(
+            statements,
+            c,
+            baseModuleData,
+            baseVariable,
+            destructuringEntries,
+            false,
+            false,
+            false
+        )
+    }
+    val code: List<FirExpression> =
+        listOf(wrappedBaseVariable, typeOperator) + block.statements.filterIsInstance<FirVariable>().map<_, FirExpression> {
+            buildVariableInConditionalExpression {
+                declaration = it
+                source = it.source
+            }
+        }
+    return code.reduce { acc, next ->
+        acc.generateLazyLogicalOperation(
+            next,
+            isAnd = true,
+            originalSource
+        )
+    }
+}
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt
index 2f44828..1d1ecb1 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt
@@ -57,6 +57,8 @@
         }
 
         private fun getSubjectType(session: FirSession, whenExpression: FirWhenExpression): ConeKotlinType? {
+            if (whenExpression.subject is FirVariableInConditionalExpression) return null
+
             val subjectType = whenExpression.subjectVariable?.returnTypeRef?.coneType
                 ?: whenExpression.subject?.resolvedType
                 ?: return null
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt
index ca4dd8f..a05b2cb 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformerDispatcher.kt
@@ -639,6 +639,15 @@
         FirControlFlowStatementsResolveTransformer::transformWhenExpression,
     )
 
+    override fun transformVariableInConditionalExpression(
+        variableInConditionalExpression: FirVariableInConditionalExpression,
+        data: ResolutionMode
+    ): FirStatement = controlFlowStatementsTransformation(
+        variableInConditionalExpression,
+        data,
+        FirControlFlowStatementsResolveTransformer::transformVariableInConditionalExpression,
+    )
+
     override fun transformWhenBranch(
         whenBranch: FirWhenBranch,
         data: ResolutionMode,
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt
index dbb12b4..9fb6c14 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt
@@ -127,14 +127,24 @@
         return lastBranch.source != null && lastBranch.condition is FirElseIfTrueCondition && lastBranch.result is FirEmptyExpressionBlock
     }
 
+    override fun transformVariableInConditionalExpression(
+        variableInConditionalExpression: FirVariableInConditionalExpression,
+        data: ResolutionMode
+    ): FirStatement {
+        variableInConditionalExpression.replaceConeTypeOrNull(session.builtinTypes.booleanType.coneTypeUnsafe())
+        variableInConditionalExpression.transformDeclaration(transformer, ResolutionMode.ContextIndependent)
+        return variableInConditionalExpression
+    }
+
     override fun transformWhenBranch(whenBranch: FirWhenBranch, data: ResolutionMode): FirWhenBranch {
         dataFlowAnalyzer.enterWhenBranchCondition(whenBranch)
-        return context.withWhenSubjectImportingScope {
-            whenBranch.transformCondition(transformer, withExpectedType(session.builtinTypes.booleanType))
-        }.also { dataFlowAnalyzer.exitWhenBranchCondition(it) }
-            .transformResult(transformer, data)
-            .also { dataFlowAnalyzer.exitWhenBranchResult(it) }
-
+        return context.forBlock(session) {
+            context.withWhenSubjectImportingScope {
+                whenBranch.transformCondition(transformer, withExpectedType(session.builtinTypes.booleanType))
+            }.also { dataFlowAnalyzer.exitWhenBranchCondition(it) }
+                .transformResult(transformer, data)
+                .also { dataFlowAnalyzer.exitWhenBranchResult(it) }
+        }
     }
 
     override fun transformWhenSubjectExpression(
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirVariableInConditionalExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirVariableInConditionalExpression.kt
new file mode 100644
index 0000000..aa7746a
--- /dev/null
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirVariableInConditionalExpression.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2024 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.
+ */
+
+// This file was generated automatically. See compiler/fir/tree/tree-generator/Readme.md.
+// DO NOT MODIFY IT MANUALLY.
+
+package org.jetbrains.kotlin.fir.expressions
+
+import org.jetbrains.kotlin.KtSourceElement
+import org.jetbrains.kotlin.fir.FirElement
+import org.jetbrains.kotlin.fir.declarations.FirVariable
+import org.jetbrains.kotlin.fir.types.ConeKotlinType
+import org.jetbrains.kotlin.fir.visitors.FirTransformer
+import org.jetbrains.kotlin.fir.visitors.FirVisitor
+
+/**
+ * Generated from: [org.jetbrains.kotlin.fir.tree.generator.FirTree.variableInConditionalExpression]
+ */
+abstract class FirVariableInConditionalExpression : FirExpression() {
+    abstract override val source: KtSourceElement?
+    @UnresolvedExpressionTypeAccess
+    abstract override val coneTypeOrNull: ConeKotlinType?
+    abstract override val annotations: List<FirAnnotation>
+    abstract val declaration: FirVariable
+
+    override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
+        visitor.visitVariableInConditionalExpression(this, data)
+
+    @Suppress("UNCHECKED_CAST")
+    override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
+        transformer.transformVariableInConditionalExpression(this, data) as E
+
+    abstract override fun replaceConeTypeOrNull(newConeTypeOrNull: ConeKotlinType?)
+
+    abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
+
+    abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirVariableInConditionalExpression
+
+    abstract fun <D> transformDeclaration(transformer: FirTransformer<D>, data: D): FirVariableInConditionalExpression
+}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirVariableInConditionalExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirVariableInConditionalExpressionBuilder.kt
new file mode 100644
index 0000000..5212df0
--- /dev/null
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirVariableInConditionalExpressionBuilder.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2024 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.
+ */
+
+// This file was generated automatically. See compiler/fir/tree/tree-generator/Readme.md.
+// DO NOT MODIFY IT MANUALLY.
+
+@file:Suppress("DuplicatedCode", "unused")
+
+package org.jetbrains.kotlin.fir.expressions.builder
+
+import kotlin.contracts.*
+import org.jetbrains.kotlin.KtSourceElement
+import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
+import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
+import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
+import org.jetbrains.kotlin.fir.declarations.FirVariable
+import org.jetbrains.kotlin.fir.expressions.FirAnnotation
+import org.jetbrains.kotlin.fir.expressions.FirVariableInConditionalExpression
+import org.jetbrains.kotlin.fir.expressions.impl.FirVariableInConditionalExpressionImpl
+import org.jetbrains.kotlin.fir.types.ConeKotlinType
+
+@FirBuilderDsl
+class FirVariableInConditionalExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
+    override var source: KtSourceElement? = null
+    override var coneTypeOrNull: ConeKotlinType? = null
+    override val annotations: MutableList<FirAnnotation> = mutableListOf()
+    lateinit var declaration: FirVariable
+
+    override fun build(): FirVariableInConditionalExpression {
+        return FirVariableInConditionalExpressionImpl(
+            source,
+            coneTypeOrNull,
+            annotations.toMutableOrEmpty(),
+            declaration,
+        )
+    }
+
+}
+
+@OptIn(ExperimentalContracts::class)
+inline fun buildVariableInConditionalExpression(init: FirVariableInConditionalExpressionBuilder.() -> Unit): FirVariableInConditionalExpression {
+    contract {
+        callsInPlace(init, InvocationKind.EXACTLY_ONCE)
+    }
+    return FirVariableInConditionalExpressionBuilder().apply(init).build()
+}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirVariableInConditionalExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirVariableInConditionalExpressionImpl.kt
new file mode 100644
index 0000000..61f2cfd
--- /dev/null
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirVariableInConditionalExpressionImpl.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2024 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.
+ */
+
+// This file was generated automatically. See compiler/fir/tree/tree-generator/Readme.md.
+// DO NOT MODIFY IT MANUALLY.
+
+@file:Suppress("DuplicatedCode")
+
+package org.jetbrains.kotlin.fir.expressions.impl
+
+import org.jetbrains.kotlin.KtSourceElement
+import org.jetbrains.kotlin.fir.MutableOrEmptyList
+import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
+import org.jetbrains.kotlin.fir.declarations.FirVariable
+import org.jetbrains.kotlin.fir.expressions.FirAnnotation
+import org.jetbrains.kotlin.fir.expressions.FirVariableInConditionalExpression
+import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
+import org.jetbrains.kotlin.fir.types.ConeKotlinType
+import org.jetbrains.kotlin.fir.visitors.FirTransformer
+import org.jetbrains.kotlin.fir.visitors.FirVisitor
+import org.jetbrains.kotlin.fir.visitors.transformInplace
+
+@OptIn(UnresolvedExpressionTypeAccess::class)
+internal class FirVariableInConditionalExpressionImpl(
+    override val source: KtSourceElement?,
+    @property:UnresolvedExpressionTypeAccess
+    override var coneTypeOrNull: ConeKotlinType?,
+    override var annotations: MutableOrEmptyList<FirAnnotation>,
+    override var declaration: FirVariable,
+) : FirVariableInConditionalExpression() {
+
+    override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
+        annotations.forEach { it.accept(visitor, data) }
+        declaration.accept(visitor, data)
+    }
+
+    override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirVariableInConditionalExpressionImpl {
+        transformAnnotations(transformer, data)
+        transformDeclaration(transformer, data)
+        return this
+    }
+
+    override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirVariableInConditionalExpressionImpl {
+        annotations.transformInplace(transformer, data)
+        return this
+    }
+
+    override fun <D> transformDeclaration(transformer: FirTransformer<D>, data: D): FirVariableInConditionalExpressionImpl {
+        declaration = declaration.transform(transformer, data)
+        return this
+    }
+
+    override fun replaceConeTypeOrNull(newConeTypeOrNull: ConeKotlinType?) {
+        coneTypeOrNull = newConeTypeOrNull
+    }
+
+    override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
+        annotations = newAnnotations.toMutableOrEmpty()
+    }
+}
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt
index a50b656..55e1f3c 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt
@@ -254,6 +254,9 @@
     override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: D): R =
         visitQualifiedAccessExpression(thisReceiverExpression, data)
 
+    override fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression, data: D): R =
+        visitExpression(variableInConditionalExpression, data)
+
     override fun visitTypeProjectionWithVariance(typeProjectionWithVariance: FirTypeProjectionWithVariance, data: D): R =
         visitTypeProjection(typeProjectionWithVariance, data)
 
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt
index b2a96b8..6b1eeb6 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt
@@ -330,6 +330,10 @@
         visitQualifiedAccessExpression(thisReceiverExpression)
     }
 
+    override fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression) {
+        visitExpression(variableInConditionalExpression)
+    }
+
     override fun visitTypeProjectionWithVariance(typeProjectionWithVariance: FirTypeProjectionWithVariance) {
         visitTypeProjection(typeProjectionWithVariance)
     }
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt
index 9d2334c..6a7d8de 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt
@@ -1171,6 +1171,14 @@
         return transformWhenExpression(whenExpression, data)
     }
 
+    open fun transformVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression, data: D): FirStatement {
+        return transformElement(variableInConditionalExpression, data)
+    }
+
+    final override fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression, data: D): FirStatement {
+        return transformVariableInConditionalExpression(variableInConditionalExpression, data)
+    }
+
     open fun transformTypeProjection(typeProjection: FirTypeProjection, data: D): FirTypeProjection {
         return transformElement(typeProjection, data)
     }
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt
index c383b4a..7a9b096 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt
@@ -452,6 +452,9 @@
     open fun visitWhenExpression(whenExpression: FirWhenExpression, data: D): R =
         visitElement(whenExpression, data)
 
+    open fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression, data: D): R =
+        visitElement(variableInConditionalExpression, data)
+
     open fun visitTypeProjection(typeProjection: FirTypeProjection, data: D): R =
         visitElement(typeProjection, data)
 
diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt
index 48defbc..db51044 100644
--- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt
+++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt
@@ -1171,6 +1171,14 @@
         visitElement(whenExpression)
     }
 
+    final override fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression, data: Nothing?) {
+        visitVariableInConditionalExpression(variableInConditionalExpression)
+    }
+
+    open fun visitVariableInConditionalExpression(variableInConditionalExpression: FirVariableInConditionalExpression) {
+        visitElement(variableInConditionalExpression)
+    }
+
     final override fun visitTypeProjection(typeProjection: FirTypeProjection, data: Nothing?) {
         visitTypeProjection(typeProjection)
     }
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt
index 859fa9e..1d6395d 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt
@@ -308,6 +308,9 @@
             additionalImports(stubReferenceType)
         }
 
+        builder(variableInConditionalExpression) {
+        }
+
         builder(resolvedTypeRef) {
             defaultNull("delegatedTypeRef")
             withCopy()
diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
index 996441a..6de1ec2 100644
--- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
+++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTree.kt
@@ -1216,6 +1216,12 @@
         +field("usedAsExpression", boolean)
     }
 
+    val variableInConditionalExpression: Element by element(Expression) {
+        parent(expression)
+
+        +field("declaration", variable, withTransform = true)
+    }
+
     val typeProjection: Element by element(TypeRefElement)
 
     val typeProjectionWithVariance: Element by element(TypeRefElement) {
diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
index 011253c..36c9efc 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java
@@ -59,6 +59,8 @@
     private static final TokenSet L_PAR_L_BRACE_R_PAR_SET = TokenSet.create(LPAR, LBRACE, RPAR);
     private static final TokenSet IN_KEYWORD_SET = TokenSet.create(IN_KEYWORD);
     private static final TokenSet TRY_CATCH_RECOVERY_TOKEN_SET = TokenSet.create(LBRACE, RBRACE, FINALLY_KEYWORD, CATCH_KEYWORD);
+    private static final TokenSet IS_DESTRUCTURING_SET = TokenSet.create(ANDAND, ARROW);
+    private static final TokenSet IS_DESTRUCTURING_SET_RECOVERY = TokenSet.orSet(IS_DESTRUCTURING_SET, PARAMETER_NAME_RECOVERY_SET);
 
     private static ImmutableMap<String, KtToken> tokenSetToMap(TokenSet tokens) {
         ImmutableMap.Builder<String, KtToken> builder = ImmutableMap.builder();
@@ -160,21 +162,21 @@
         PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // annotations
 
             @Override
-            public void parseHigherPrecedence(KotlinExpressionParsing parser) {
+            public void parseHigherPrecedence(KotlinExpressionParsing parser, boolean conditionalContext) {
                 throw new IllegalStateException("Don't call this method");
             }
         },
 
         AS(AS_KEYWORD, AS_SAFE) {
             @Override
-            public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) {
+            public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser, boolean conditionalContext) {
                 parser.myKotlinParsing.parseTypeRefWithoutIntersections();
                 return BINARY_WITH_TYPE;
             }
 
             @Override
-            public void parseHigherPrecedence(KotlinExpressionParsing parser) {
-                parser.parsePrefixExpression();
+            public void parseHigherPrecedence(KotlinExpressionParsing parser, boolean conditionalContext) {
+                parser.parsePrefixExpression(conditionalContext);
             }
         },
 
@@ -185,18 +187,30 @@
         ELVIS(KtTokens.ELVIS),
         IN_OR_IS(IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS) {
             @Override
-            public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) {
-                if (operation == IS_KEYWORD || operation == NOT_IS) {
+            public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser, boolean conditionalContext) {
+                if (operation == IS_KEYWORD && conditionalContext) {
+                    parser.myKotlinParsing.parseTypeRefWithoutIntersections();
+                    if (parser.myKotlinParsing.at(LPAR)) {
+                        parser.myKotlinParsing.parseMultiDeclarationName(IS_DESTRUCTURING_SET, IS_DESTRUCTURING_SET_RECOVERY);
+                    }
+                    return IS_EXPRESSION;
+                } else if (operation == IS_KEYWORD || operation == NOT_IS) {
                     parser.myKotlinParsing.parseTypeRefWithoutIntersections();
                     return IS_EXPRESSION;
                 }
 
-                return super.parseRightHandSide(operation, parser);
+                return super.parseRightHandSide(operation, parser, conditionalContext);
             }
         },
         COMPARISON(LT, GT, LTEQ, GTEQ),
         EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ),
-        CONJUNCTION(ANDAND),
+        CONJUNCTION(ANDAND) {
+            @Override
+            public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser, boolean conditionalContext) {
+                parseHigherPrecedence(parser, conditionalContext); // propagate conditionalContext correctly
+                return BINARY_EXPRESSION;
+            }
+        },
         DISJUNCTION(OROR),
         //        ARROW(KtTokens.ARROW),
         ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
@@ -210,16 +224,16 @@
             }
         }
 
-        private Precedence higher;
+        protected Precedence higher;
         private final TokenSet operations;
 
         Precedence(IElementType... operations) {
             this.operations = TokenSet.create(operations);
         }
 
-        public void parseHigherPrecedence(KotlinExpressionParsing parser) {
+        public void parseHigherPrecedence(KotlinExpressionParsing parser, boolean conditionalContext) {
             assert higher != null;
-            parser.parseBinaryExpression(higher);
+            parser.parseBinaryExpression(higher, conditionalContext);
         }
 
         /**
@@ -228,8 +242,8 @@
          * @param parser the parser object
          * @return node type of the result
          */
-        public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser) {
-            parseHigherPrecedence(parser);
+        public IElementType parseRightHandSide(IElementType operation, KotlinExpressionParsing parser, boolean conditionalContext) {
+            parseHigherPrecedence(parser, false);
             return BINARY_EXPRESSION;
         }
 
@@ -309,12 +323,20 @@
      *   // block is syntactically equivalent to a functionLiteral with no parameters
      *   ;
      */
-    public void parseExpression() {
+    private void parseExpression(boolean conditionalContext) {
         if (!atSet(EXPRESSION_FIRST)) {
             error("Expecting an expression");
             return;
         }
-        parseBinaryExpression(Precedence.ASSIGNMENT);
+        parseBinaryExpression(Precedence.ASSIGNMENT, conditionalContext);
+    }
+
+    public void parseExpression() {
+        parseExpression(false);
+    }
+
+    public void parseConditionalExpression() {
+        parseExpression(true);
     }
 
     /*
@@ -322,17 +344,17 @@
      *
      * see the precedence table
      */
-    private void parseBinaryExpression(Precedence precedence) {
+    private void parseBinaryExpression(Precedence precedence, boolean conditionalContext) {
         PsiBuilder.Marker expression = mark();
 
-        precedence.parseHigherPrecedence(this);
+        precedence.parseHigherPrecedence(this, conditionalContext);
 
         while (!interruptedWithNewLine() && atSet(precedence.getOperations())) {
             IElementType operation = tt();
 
             parseOperationReference();
 
-            IElementType resultType = precedence.parseRightHandSide(operation, this);
+            IElementType resultType = precedence.parseRightHandSide(operation, this, conditionalContext);
             expression.done(resultType);
             expression = expression.precede();
         }
@@ -346,19 +368,19 @@
     private void parseLabeledExpression() {
         PsiBuilder.Marker expression = mark();
         parseLabelDefinition();
-        parsePrefixExpression();
+        parsePrefixExpression(false);
         expression.done(LABELED_EXPRESSION);
     }
 
     /*
      * operation? prefixExpression
      */
-    private void parsePrefixExpression() {
+    public void parsePrefixExpression(boolean conditionalContext) {
         if (at(AT)) {
             if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ false, false)) {
                 PsiBuilder.Marker expression = mark();
                 myKotlinParsing.parseAnnotations(DEFAULT);
-                parsePrefixExpression();
+                parsePrefixExpression(false);
                 expression.done(ANNOTATED_EXPRESSION);
             }
         }
@@ -375,12 +397,12 @@
 
                 myBuilder.restoreJoiningComplexTokensState();
 
-                parsePrefixExpression();
+                parsePrefixExpression(false);
                 expression.done(PREFIX_EXPRESSION);
             }
             else {
                 myBuilder.restoreJoiningComplexTokensState();
-                parsePostfixExpression();
+                parsePostfixExpression(conditionalContext);
             }
         }
     }
@@ -450,10 +472,10 @@
      *   : memberAccessOperation postfixUnaryExpression // TODO: Review
      *   ;
      */
-    private void parsePostfixExpression() {
+    private void parsePostfixExpression(boolean conditionalContext) {
         PsiBuilder.Marker expression = mark();
 
-        boolean firstExpressionParsed = at(COLONCOLON) ? parseDoubleColonSuffix(mark()) : parseAtomicExpression();
+        boolean firstExpressionParsed = at(COLONCOLON) ? parseDoubleColonSuffix(mark()) : parseAtomicExpression(conditionalContext);
 
         while (true) {
             if (interruptedWithNewLine()) {
@@ -473,7 +495,7 @@
                 if (!firstExpressionParsed) {
                     expression.drop();
                     expression = mark();
-                    firstExpressionParsed = parseAtomicExpression();
+                    firstExpressionParsed = parseAtomicExpression(false);
                     continue;
                 }
 
@@ -534,7 +556,7 @@
      */
     private void parseSelectorCallExpression() {
         PsiBuilder.Marker mark = mark();
-        parseAtomicExpression();
+        parseAtomicExpression(false);
         if (!myBuilder.newlineBeforeCurrentToken() && parseCallSuffix()) {
             mark.done(CALL_EXPRESSION);
         }
@@ -632,7 +654,7 @@
      *   : collectionLiteral
      *   ;
      */
-    private boolean parseAtomicExpression() {
+    private boolean parseAtomicExpression(boolean conditionalContext) {
         boolean ok = true;
 
         switch (getTokenId()) {
@@ -718,10 +740,17 @@
             case NULL_KEYWORD_Id:
                 parseOneTokenExpression(NULL);
                 break;
+            case VAL_KEYWORD_Id:
+                if (conditionalContext) {
+                    PsiBuilder.Marker start = mark();
+                    IElementType result = myKotlinParsing.parseProperty(KotlinParsing.DeclarationParsingMode.CONDITIONAL);
+                    start.done(result);
+                    break;
+                }
+                // else, cascade
             case CLASS_KEYWORD_Id:
             case INTERFACE_KEYWORD_Id:
             case FUN_KEYWORD_Id:
-            case VAL_KEYWORD_Id:
             case VAR_KEYWORD_Id:
             case TYPE_ALIAS_KEYWORD_Id:
                 if (!parseLocalDeclaration(/* rollbackIfDefinitelyNotExpression = */ myBuilder.newlineBeforeCurrentToken(), false)) {
@@ -1023,7 +1052,7 @@
                 condition.done(WHEN_CONDITION_EXPRESSION);
                 break;
             default:
-                parseExpression();
+                parseConditionalExpression();
                 condition.done(WHEN_CONDITION_EXPRESSION);
                 break;
         }
diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
index b1e896a..d32b2c9 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinParsing.java
@@ -1437,18 +1437,21 @@
     }
 
     enum DeclarationParsingMode {
-        MEMBER_OR_TOPLEVEL(false, true, true),
-        LOCAL(true, false, false),
-        SCRIPT_TOPLEVEL(true, true, false);
+        MEMBER_OR_TOPLEVEL(false, true, true, false),
+        LOCAL(true, false, false, false),
+        SCRIPT_TOPLEVEL(true, true, false, false),
+        CONDITIONAL(true, false, false, true);
 
         public final boolean destructuringAllowed;
         public final boolean accessorsAllowed;
         public final boolean canBeEnumUsedAsSoftKeyword;
+        public final boolean onlyAtomicExpressions;
 
-        DeclarationParsingMode(boolean destructuringAllowed, boolean accessorsAllowed, boolean canBeEnumUsedAsSoftKeyword) {
+        DeclarationParsingMode(boolean destructuringAllowed, boolean accessorsAllowed, boolean canBeEnumUsedAsSoftKeyword, boolean onlyAtomicExpressions) {
             this.destructuringAllowed = destructuringAllowed;
             this.accessorsAllowed = accessorsAllowed;
             this.canBeEnumUsedAsSoftKeyword = canBeEnumUsedAsSoftKeyword;
+            this.onlyAtomicExpressions = onlyAtomicExpressions;
         }
     }
 
@@ -1507,7 +1510,7 @@
 
         parseTypeConstraintsGuarded(typeParametersDeclared);
 
-        if (!parsePropertyDelegateOrAssignment() && isNameOnTheNextLine && noTypeReference && !receiverTypeDeclared) {
+        if (!parsePropertyDelegateOrAssignment(mode) && isNameOnTheNextLine && noTypeReference && !receiverTypeDeclared) {
             // Do not parse property identifier on the next line if declaration is invalid
             // In most cases this identifier relates to next statement/declaration
             beforeName.rollbackTo();
@@ -1550,14 +1553,18 @@
         return multiDeclaration ? DESTRUCTURING_DECLARATION : PROPERTY;
     }
 
-    private boolean parsePropertyDelegateOrAssignment() {
-        if (at(BY_KEYWORD)) {
+    private boolean parsePropertyDelegateOrAssignment(DeclarationParsingMode mode) {
+        if (at(BY_KEYWORD) && !mode.onlyAtomicExpressions) {
             parsePropertyDelegate();
             return true;
         }
         else if (at(EQ)) {
             advance(); // EQ
-            myExpressionParsing.parseExpression();
+            if (mode.onlyAtomicExpressions) {
+                myExpressionParsing.parsePrefixExpression(false);
+            } else {
+                myExpressionParsing.parseExpression();
+            }
             return true;
         }
 
diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java
index 20a7783..7fb4050 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java
@@ -20,6 +20,7 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.search.LocalSearchScope;
 import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.tree.TokenSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -31,8 +32,7 @@
 import java.util.Collections;
 import java.util.List;
 
-import static org.jetbrains.kotlin.lexer.KtTokens.VAL_KEYWORD;
-import static org.jetbrains.kotlin.lexer.KtTokens.VAR_KEYWORD;
+import static org.jetbrains.kotlin.lexer.KtTokens.*;
 
 @SuppressWarnings("deprecation")
 public class KtDestructuringDeclarationEntry extends KtNamedDeclarationNotStubbed implements KtVariableDeclaration {
@@ -132,7 +132,8 @@
     @NotNull
     private ASTNode getParentNode() {
         ASTNode parent = getNode().getTreeParent();
-        assert parent.getElementType() == KtNodeTypes.DESTRUCTURING_DECLARATION :
+        IElementType parentType = parent.getElementType();
+        assert (parentType == KtNodeTypes.DESTRUCTURING_DECLARATION || parentType == KtNodeTypes.IS_EXPRESSION) :
                 "parent is " + parent.getElementType();
         return parent;
     }
diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtIsExpression.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtIsExpression.java
index 56b5a50..b3d7ab1 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtIsExpression.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtIsExpression.java
@@ -22,6 +22,8 @@
 import org.jetbrains.kotlin.KtNodeTypes;
 import org.jetbrains.kotlin.lexer.KtTokens;
 
+import java.util.List;
+
 public class KtIsExpression extends KtExpressionImpl implements KtOperationExpression {
     public KtIsExpression(@NotNull ASTNode node) {
         super(node);
@@ -52,4 +54,9 @@
         return getOperationReference().getReferencedNameElementType() == KtTokens.NOT_IS;
     }
 
+    @Nullable @IfNotParsed
+    public List<KtDestructuringDeclarationEntry> getDestructuringEntries() {
+        return findChildrenByType(KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY);
+    }
+
 }
diff --git a/compiler/testData/psi/DeclarationsInConditionals.kt b/compiler/testData/psi/DeclarationsInConditionals.kt
new file mode 100644
index 0000000..208d881
--- /dev/null
+++ b/compiler/testData/psi/DeclarationsInConditionals.kt
@@ -0,0 +1,22 @@
+open class Developer
+class Person(val name: String) : Developer()
+class Company(val name: String, val cto: Person) : Developer()
+
+sealed class Download
+data class App(val title: String, val developer: Developer) : Download()
+data class Movie(val title: String, val director: Person) : Download()
+
+fun f(download: Download) = when {
+  download is App
+    && val (title, developer) = download
+    && developer is Person
+    && developer.name == "Alice" -> "$title in Wonderland"
+  else -> "Boo"
+}
+
+fun g(download: Download) = when {
+  download is App (title, developer)
+    && developer is Person
+    && developer.name == "Alice" -> "$title in Wonderland"
+  else -> "Boo"
+}
diff --git a/compiler/testData/psi/DeclarationsInConditionals.txt b/compiler/testData/psi/DeclarationsInConditionals.txt
new file mode 100644
index 0000000..ef0967e
--- /dev/null
+++ b/compiler/testData/psi/DeclarationsInConditionals.txt
@@ -0,0 +1,418 @@
+KtFile: DeclarationsInConditionals.kt
+  PACKAGE_DIRECTIVE
+    <empty list>
+  IMPORT_LIST
+    <empty list>
+  CLASS
+    MODIFIER_LIST
+      PsiElement(open)('open')
+    PsiWhiteSpace(' ')
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('Developer')
+  PsiWhiteSpace('\n')
+  CLASS
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('Person')
+    PRIMARY_CONSTRUCTOR
+      VALUE_PARAMETER_LIST
+        PsiElement(LPAR)('(')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('name')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('String')
+        PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(COLON)(':')
+    PsiWhiteSpace(' ')
+    SUPER_TYPE_LIST
+      SUPER_TYPE_CALL_ENTRY
+        CONSTRUCTOR_CALLEE
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Developer')
+        VALUE_ARGUMENT_LIST
+          PsiElement(LPAR)('(')
+          PsiElement(RPAR)(')')
+  PsiWhiteSpace('\n')
+  CLASS
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('Company')
+    PRIMARY_CONSTRUCTOR
+      VALUE_PARAMETER_LIST
+        PsiElement(LPAR)('(')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('name')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('String')
+        PsiElement(COMMA)(',')
+        PsiWhiteSpace(' ')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('cto')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Person')
+        PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(COLON)(':')
+    PsiWhiteSpace(' ')
+    SUPER_TYPE_LIST
+      SUPER_TYPE_CALL_ENTRY
+        CONSTRUCTOR_CALLEE
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Developer')
+        VALUE_ARGUMENT_LIST
+          PsiElement(LPAR)('(')
+          PsiElement(RPAR)(')')
+  PsiWhiteSpace('\n\n')
+  CLASS
+    MODIFIER_LIST
+      PsiElement(sealed)('sealed')
+    PsiWhiteSpace(' ')
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('Download')
+  PsiWhiteSpace('\n')
+  CLASS
+    MODIFIER_LIST
+      PsiElement(data)('data')
+    PsiWhiteSpace(' ')
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('App')
+    PRIMARY_CONSTRUCTOR
+      VALUE_PARAMETER_LIST
+        PsiElement(LPAR)('(')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('title')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('String')
+        PsiElement(COMMA)(',')
+        PsiWhiteSpace(' ')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('developer')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Developer')
+        PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(COLON)(':')
+    PsiWhiteSpace(' ')
+    SUPER_TYPE_LIST
+      SUPER_TYPE_CALL_ENTRY
+        CONSTRUCTOR_CALLEE
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Download')
+        VALUE_ARGUMENT_LIST
+          PsiElement(LPAR)('(')
+          PsiElement(RPAR)(')')
+  PsiWhiteSpace('\n')
+  CLASS
+    MODIFIER_LIST
+      PsiElement(data)('data')
+    PsiWhiteSpace(' ')
+    PsiElement(class)('class')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('Movie')
+    PRIMARY_CONSTRUCTOR
+      VALUE_PARAMETER_LIST
+        PsiElement(LPAR)('(')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('title')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('String')
+        PsiElement(COMMA)(',')
+        PsiWhiteSpace(' ')
+        VALUE_PARAMETER
+          PsiElement(val)('val')
+          PsiWhiteSpace(' ')
+          PsiElement(IDENTIFIER)('director')
+          PsiElement(COLON)(':')
+          PsiWhiteSpace(' ')
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Person')
+        PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(COLON)(':')
+    PsiWhiteSpace(' ')
+    SUPER_TYPE_LIST
+      SUPER_TYPE_CALL_ENTRY
+        CONSTRUCTOR_CALLEE
+          TYPE_REFERENCE
+            USER_TYPE
+              REFERENCE_EXPRESSION
+                PsiElement(IDENTIFIER)('Download')
+        VALUE_ARGUMENT_LIST
+          PsiElement(LPAR)('(')
+          PsiElement(RPAR)(')')
+  PsiWhiteSpace('\n\n')
+  FUN
+    PsiElement(fun)('fun')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('f')
+    VALUE_PARAMETER_LIST
+      PsiElement(LPAR)('(')
+      VALUE_PARAMETER
+        PsiElement(IDENTIFIER)('download')
+        PsiElement(COLON)(':')
+        PsiWhiteSpace(' ')
+        TYPE_REFERENCE
+          USER_TYPE
+            REFERENCE_EXPRESSION
+              PsiElement(IDENTIFIER)('Download')
+      PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(EQ)('=')
+    PsiWhiteSpace(' ')
+    WHEN
+      PsiElement(when)('when')
+      PsiWhiteSpace(' ')
+      PsiElement(LBRACE)('{')
+      PsiWhiteSpace('\n  ')
+      WHEN_ENTRY
+        WHEN_CONDITION_WITH_EXPRESSION
+          BINARY_EXPRESSION
+            BINARY_EXPRESSION
+              BINARY_EXPRESSION
+                IS_EXPRESSION
+                  REFERENCE_EXPRESSION
+                    PsiElement(IDENTIFIER)('download')
+                  PsiWhiteSpace(' ')
+                  OPERATION_REFERENCE
+                    PsiElement(is)('is')
+                  PsiWhiteSpace(' ')
+                  TYPE_REFERENCE
+                    USER_TYPE
+                      REFERENCE_EXPRESSION
+                        PsiElement(IDENTIFIER)('App')
+                PsiWhiteSpace('\n    ')
+                OPERATION_REFERENCE
+                  PsiElement(ANDAND)('&&')
+                PsiWhiteSpace(' ')
+                DESTRUCTURING_DECLARATION
+                  PsiElement(val)('val')
+                  PsiWhiteSpace(' ')
+                  PsiElement(LPAR)('(')
+                  DESTRUCTURING_DECLARATION_ENTRY
+                    PsiElement(IDENTIFIER)('title')
+                  PsiElement(COMMA)(',')
+                  PsiWhiteSpace(' ')
+                  DESTRUCTURING_DECLARATION_ENTRY
+                    PsiElement(IDENTIFIER)('developer')
+                  PsiElement(RPAR)(')')
+                  PsiWhiteSpace(' ')
+                  PsiElement(EQ)('=')
+                  PsiWhiteSpace(' ')
+                  REFERENCE_EXPRESSION
+                    PsiElement(IDENTIFIER)('download')
+              PsiWhiteSpace('\n    ')
+              OPERATION_REFERENCE
+                PsiElement(ANDAND)('&&')
+              PsiWhiteSpace(' ')
+              IS_EXPRESSION
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('developer')
+                PsiWhiteSpace(' ')
+                OPERATION_REFERENCE
+                  PsiElement(is)('is')
+                PsiWhiteSpace(' ')
+                TYPE_REFERENCE
+                  USER_TYPE
+                    REFERENCE_EXPRESSION
+                      PsiElement(IDENTIFIER)('Person')
+            PsiWhiteSpace('\n    ')
+            OPERATION_REFERENCE
+              PsiElement(ANDAND)('&&')
+            PsiWhiteSpace(' ')
+            BINARY_EXPRESSION
+              DOT_QUALIFIED_EXPRESSION
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('developer')
+                PsiElement(DOT)('.')
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('name')
+              PsiWhiteSpace(' ')
+              OPERATION_REFERENCE
+                PsiElement(EQEQ)('==')
+              PsiWhiteSpace(' ')
+              STRING_TEMPLATE
+                PsiElement(OPEN_QUOTE)('"')
+                LITERAL_STRING_TEMPLATE_ENTRY
+                  PsiElement(REGULAR_STRING_PART)('Alice')
+                PsiElement(CLOSING_QUOTE)('"')
+        PsiWhiteSpace(' ')
+        PsiElement(ARROW)('->')
+        PsiWhiteSpace(' ')
+        STRING_TEMPLATE
+          PsiElement(OPEN_QUOTE)('"')
+          SHORT_STRING_TEMPLATE_ENTRY
+            PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
+            REFERENCE_EXPRESSION
+              PsiElement(IDENTIFIER)('title')
+          LITERAL_STRING_TEMPLATE_ENTRY
+            PsiElement(REGULAR_STRING_PART)(' in Wonderland')
+          PsiElement(CLOSING_QUOTE)('"')
+      PsiWhiteSpace('\n  ')
+      WHEN_ENTRY
+        PsiElement(else)('else')
+        PsiWhiteSpace(' ')
+        PsiElement(ARROW)('->')
+        PsiWhiteSpace(' ')
+        STRING_TEMPLATE
+          PsiElement(OPEN_QUOTE)('"')
+          LITERAL_STRING_TEMPLATE_ENTRY
+            PsiElement(REGULAR_STRING_PART)('Boo')
+          PsiElement(CLOSING_QUOTE)('"')
+      PsiWhiteSpace('\n')
+      PsiElement(RBRACE)('}')
+  PsiWhiteSpace('\n\n')
+  FUN
+    PsiElement(fun)('fun')
+    PsiWhiteSpace(' ')
+    PsiElement(IDENTIFIER)('g')
+    VALUE_PARAMETER_LIST
+      PsiElement(LPAR)('(')
+      VALUE_PARAMETER
+        PsiElement(IDENTIFIER)('download')
+        PsiElement(COLON)(':')
+        PsiWhiteSpace(' ')
+        TYPE_REFERENCE
+          USER_TYPE
+            REFERENCE_EXPRESSION
+              PsiElement(IDENTIFIER)('Download')
+      PsiElement(RPAR)(')')
+    PsiWhiteSpace(' ')
+    PsiElement(EQ)('=')
+    PsiWhiteSpace(' ')
+    WHEN
+      PsiElement(when)('when')
+      PsiWhiteSpace(' ')
+      PsiElement(LBRACE)('{')
+      PsiWhiteSpace('\n  ')
+      WHEN_ENTRY
+        WHEN_CONDITION_WITH_EXPRESSION
+          BINARY_EXPRESSION
+            BINARY_EXPRESSION
+              IS_EXPRESSION
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('download')
+                PsiWhiteSpace(' ')
+                OPERATION_REFERENCE
+                  PsiElement(is)('is')
+                PsiWhiteSpace(' ')
+                TYPE_REFERENCE
+                  USER_TYPE
+                    REFERENCE_EXPRESSION
+                      PsiElement(IDENTIFIER)('App')
+                PsiWhiteSpace(' ')
+                PsiElement(LPAR)('(')
+                DESTRUCTURING_DECLARATION_ENTRY
+                  PsiElement(IDENTIFIER)('title')
+                PsiElement(COMMA)(',')
+                PsiWhiteSpace(' ')
+                DESTRUCTURING_DECLARATION_ENTRY
+                  PsiElement(IDENTIFIER)('developer')
+                PsiElement(RPAR)(')')
+              PsiWhiteSpace('\n    ')
+              OPERATION_REFERENCE
+                PsiElement(ANDAND)('&&')
+              PsiWhiteSpace(' ')
+              IS_EXPRESSION
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('developer')
+                PsiWhiteSpace(' ')
+                OPERATION_REFERENCE
+                  PsiElement(is)('is')
+                PsiWhiteSpace(' ')
+                TYPE_REFERENCE
+                  USER_TYPE
+                    REFERENCE_EXPRESSION
+                      PsiElement(IDENTIFIER)('Person')
+            PsiWhiteSpace('\n    ')
+            OPERATION_REFERENCE
+              PsiElement(ANDAND)('&&')
+            PsiWhiteSpace(' ')
+            BINARY_EXPRESSION
+              DOT_QUALIFIED_EXPRESSION
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('developer')
+                PsiElement(DOT)('.')
+                REFERENCE_EXPRESSION
+                  PsiElement(IDENTIFIER)('name')
+              PsiWhiteSpace(' ')
+              OPERATION_REFERENCE
+                PsiElement(EQEQ)('==')
+              PsiWhiteSpace(' ')
+              STRING_TEMPLATE
+                PsiElement(OPEN_QUOTE)('"')
+                LITERAL_STRING_TEMPLATE_ENTRY
+                  PsiElement(REGULAR_STRING_PART)('Alice')
+                PsiElement(CLOSING_QUOTE)('"')
+        PsiWhiteSpace(' ')
+        PsiElement(ARROW)('->')
+        PsiWhiteSpace(' ')
+        STRING_TEMPLATE
+          PsiElement(OPEN_QUOTE)('"')
+          SHORT_STRING_TEMPLATE_ENTRY
+            PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
+            REFERENCE_EXPRESSION
+              PsiElement(IDENTIFIER)('title')
+          LITERAL_STRING_TEMPLATE_ENTRY
+            PsiElement(REGULAR_STRING_PART)(' in Wonderland')
+          PsiElement(CLOSING_QUOTE)('"')
+      PsiWhiteSpace('\n  ')
+      WHEN_ENTRY
+        PsiElement(else)('else')
+        PsiWhiteSpace(' ')
+        PsiElement(ARROW)('->')
+        PsiWhiteSpace(' ')
+        STRING_TEMPLATE
+          PsiElement(OPEN_QUOTE)('"')
+          LITERAL_STRING_TEMPLATE_ENTRY
+            PsiElement(REGULAR_STRING_PART)('Boo')
+          PsiElement(CLOSING_QUOTE)('"')
+      PsiWhiteSpace('\n')
+      PsiElement(RBRACE)('}')
\ No newline at end of file
diff --git a/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
index 7e6e2ed..75165b1 100644
--- a/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
+++ b/compiler/tests-gen/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java
@@ -151,6 +151,11 @@
       runTest("compiler/testData/psi/ControlStructures.kt");
     }
 
+    @TestMetadata("DeclarationsInConditionals.kt")
+    public void testDeclarationsInConditionals() {
+      runTest("compiler/testData/psi/DeclarationsInConditionals.kt");
+    }
+
     @TestMetadata("DefaultKeyword.kt")
     public void testDefaultKeyword() {
       runTest("compiler/testData/psi/DefaultKeyword.kt");